# Documentación de Dinaup (/docs)
Bienvenido a la documentación de Dinaup. Está organizada en **cinco espacios** según lo que necesites: úsalo, aprende a usarlo, constrúyelo, gestiónalo o mira qué hay de nuevo.
Empezar y todos los módulos: Pymes, TPV, CRM, Proyectos, RRHH, IA, Agendas.
Guías prácticas: puesta en marcha, inventario, TPV, usuarios e integraciones.
Flex (no-code), SDK .NET, integraciones, recursos y guías técnicas.
Alta y planes, suscripción y pagos, usuarios, permisos, legal y partners.
Notas de la versión: qué cambia en cada release del núcleo y del SDK.
# Actividad en tiempo real (/docs/cuenta/actividad-en-tiempo-real)
La aplicación **Live** muestra la actividad de los usuarios en tiempo real. Se abre desde **App > Live** y solo la ve el administrador.
***
## Antes de empezar [#antes-de-empezar]
* Necesitas ser **administrador** de la empresa.
***
## Tiempo real [#tiempo-real]
La pantalla de inicio muestra quién está usando la aplicación ahora mismo.
* **Resumen de actividad**: tres indicadores con los usuarios online, las sesiones activas y las empresas.
* **Buscador**: filtra las sesiones por nombre o email.
* **Sesiones**: la lista de usuarios conectados, agrupada por usuario. Se actualiza sola.
## Componentes [#componentes]
Un análisis del uso de componentes en un rango de fechas que eliges (por defecto, los últimos 30 días).
* **Indicadores**: total de registros, duración total y duración media.
* **Gráficos**: los componentes más usados, los usuarios que más los usan, los componentes más lentos y los que más tiempo acumulan.
## Debug [#debug]
Métricas internas del servidor, solo de lectura y visibles únicamente para el equipo Dinaup. Se actualiza cada pocos segundos e incluye memoria, sesiones activas, datos de build y los paquetes cargados.
# Claves API (/docs/cuenta/claves-api)
Las claves API permiten a aplicaciones externas acceder a los datos de tu empresa en Dinaup de forma programática. Cada clave está vinculada a un usuario y hereda sus permisos.
***
## Cómo funcionan [#cómo-funcionan]
Una clave API es un token que se incluye en las peticiones HTTP a la API de Dinaup:
```
Authorization: Bearer
```
La clave autentica la petición como si fuera el usuario al que pertenece. Esto significa que:
* Solo puede acceder a los datos que ese usuario tiene permiso de ver
* Solo puede escribir en las secciones que ese usuario puede editar
* Las acciones quedan registradas en la auditoría a nombre de ese usuario
***
## Generar una clave API [#generar-una-clave-api]
1. Accede al **Panel de administración** en [dinaup.com](https://dinaup.com)
2. Ve a **Claves API** en el menú lateral
3. Haz clic en **Crear clave API**
4. Selecciona el **usuario** al que se asociará la clave
5. Copia la clave generada y guárdala en un lugar seguro
La clave solo se muestra una vez en el momento de la creación. Si la pierdes, deberás generar una nueva.
***
## Dónde usar las claves API [#dónde-usar-las-claves-api]
| Integración | Uso |
| ----------------------------------------------------------------------- | ----------------------------------------------------- |
| [API REST](/docs/desarrollo/integraciones/webhook/entrantes) | Leer informes, generar documentos, escribir registros |
| [Webhooks entrantes](/docs/desarrollo/integraciones/webhook/entrantes) | Playground de pruebas |
| [SDK .NET](/docs/desarrollo/dotnet/sdk) | Autenticación del cliente SDK |
| [n8n / Make / Zapier](/docs/desarrollo/integraciones/zapier-make-y-n8n) | Configuración de la conexión con Dinaup |
***
## Buenas prácticas de seguridad [#buenas-prácticas-de-seguridad]
| Práctica | Motivo |
| --------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Usa un **usuario específico** para cada integración | Permite revocar acceso individualmente sin afectar a otros |
| **No compartas** claves en código público | Cualquiera con la clave puede acceder a tus datos |
| Usa claves solo en el **backend** | Nunca las incluyas en JavaScript del frontend |
| **Rota las claves** periódicamente | Minimiza el riesgo si una clave se filtra |
| Asigna **permisos mínimos** al usuario de la clave | El usuario de la API solo necesita acceso a las secciones que la integración utiliza |
***
## Revocar una clave [#revocar-una-clave]
Para desactivar una clave API, elimínala desde el panel de Claves API o desactiva al usuario asociado. Las peticiones con esa clave recibirán un error `401 Unauthorized`.
# Configuración de Usuario (/docs/cuenta/configuracion-de-usuario)
La **Configuración de Usuario** guarda tus preferencias personales. Solo te afectan a ti, no al resto de la empresa.
***
## Apariencia [#apariencia]
* **Modo oscuro**: activa o desactiva el tema oscuro de la interfaz.
## Acciones rápidas (FAB) [#acciones-rápidas-fab]
Elige qué accesos aparecen en el botón de acción flotante. Puedes activar:
* Nueva Tarea
* Nuevo Cliente
* Nueva Oportunidad
* Nuevo Evento
* Nueva Venta
* Nuevo Presupuesto
* Nuevo Pedido
Cada cambio se guarda al marcarlo.
# Registrarse en Dinaup (/docs/cuenta/crear-cuenta)
### Accede a la ventana de registro [#accede-a-la-ventana-de-registro]
Visita [dinaup.com](https://dinaup.com) y pulsa en **Iniciar sesión**. En la parte inferior del formulario verás un enlace que dice **“`Darme de alta`”**. Haz clic ahí para comenzar el registro.
### Completa tus datos [#completa-tus-datos]
Introduce tu nombre, correo electrónico y una contraseña segura.\
Cuando termines, pulsa en **“`Crear Cuenta`”**.
### Confirma tu correo [#confirma-tu-correo]
Revisa tu bandeja de entrada. Recibirás un email con el asunto **"Dinaup, activación de cuenta"**. Haz clic en **“`Activar mi cuenta`”** para confirmar tu correo y validar el acceso.
### Inicia sesión [#inicia-sesión]
Vuelve a [dinaup.com](https://dinaup.com), pulsa en **Iniciar sesión** e introduce tu correo y contraseña.
### Solicita unirte a tu empresa [#solicita-unirte-a-tu-empresa]
1. En la pantalla principal verás un campo que dice: **¿Tu empresa ya está en Dinaup?**
2. Busca por nombre, CIF o dominio web (por ejemplo: *miempresa.com*).
3. Cuando la encuentres, haz clic en **“`Solicitar Acceso`”**.
Solo queda esperar a que un administrador apruebe tu solicitud y te asigne permisos.
# Doble factor de autenticación (/docs/cuenta/doble-factor)
El doble factor añade una segunda comprobación al iniciar sesión: además de la contraseña, el usuario confirma su identidad con un código temporal. Si alguien roba la contraseña, sigue sin poder entrar.
## Activarlo por usuario [#activarlo-por-usuario]
Cada usuario tiene la opción **Activar doble factor** en su ficha. Actívala usuario a usuario desde [gestión de usuarios](/docs/cuenta/gestion-de-usuarios).
Los administradores deben llevar el doble factor activado siempre: su cuenta puede tocar datos de toda la empresa. El panel de diagnósticos avisa cuando un administrador no lo tiene activo.
## Política de empresa [#política-de-empresa]
Puedes definir cómo de estricta es la exigencia para el resto del equipo en la configuración de políticas de RRHH: exigirlo, recomendarlo o ignorarlo. Con la política activa, los empleados sin doble factor aparecen como aviso en los diagnósticos.
***
Para el resto de opciones de cada usuario, ver [gestión de usuarios](/docs/cuenta/gestion-de-usuarios).
# Cuenta y facturación (/docs/cuenta)
Aquí gestionas el alta, la suscripción y quién accede a tu empresa en Dinaup. Elige por dónde empezar.
# Perfil de usuario (/docs/cuenta/perfil-de-usuario)
El **perfil de usuario** es tu ficha de trabajador dentro de la aplicación. Reúne tus datos y los accesos a tus gestiones del día a día.
***
## Ficha [#ficha]
En la cabecera aparece tu foto, tu nombre, tu correo, tu departamento y si estás activo. Si es tu perfil, puedes generar un avatar con IA o subir una foto. Con permiso, puedes editar los datos del empleado.
Debajo, un resumen anual muestra tus festivos, tus vacaciones disfrutadas y tus vacaciones aprobadas.
## ¿Qué puedo hacer aquí? [#qué-puedo-hacer-aquí]
Los accesos se agrupan por bloque. Cuáles ves depende de tus permisos.
| Bloque | Accesos |
| ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Fichaje y horarios** | Fichar, ver tu horario actual, ver tus fichajes recientes, ver tus horarios asignados y exportar tus fichajes. |
| **Tiempo libre** | Solicitar vacaciones, ver tu saldo de horas, gestionar tus vacaciones y ver tus ausencias. |
| **Punto de venta** | Ver los almacenes donde puedes vender. |
| **Correspondencias** | Ver tus correspondencias y enviar una nueva. |
| **Documentos** | Ver tus contratos. |
## Notificaciones y calendario [#notificaciones-y-calendario]
Bajo los accesos se cargan tus notificaciones y, con permiso, tu calendario laboral.
# Permisos y Roles (/docs/cuenta/permisos-y-roles)
Los *roles de usuario* determinan los permisos y accesos de cada usuario dentro de Dinaup. Con ellos controlas qué acciones puede realizar cada miembro del equipo. Cada uno accede solo a la información y funciones que necesita para su trabajo.
Los informes y documentos dinámicos no se configuran mediante roles. Para dar acceso a un usuario, añádelo a un dashboard: verá todos los informes de sus dashboards sin configurar permisos uno a uno.
## Casos de uso [#casos-de-uso]
### Diseños de sección personalizados [#diseños-de-sección-personalizados]
Personaliza la vista de cada usuario según su rol. Así muestras solo los campos y apartados que necesita en su trabajo diario.
En este ejemplo:
* El **Comercial** accede a un diseño simplificado, con solo los campos imprescindibles para su día a día: nombre, imagen y descripción del producto.
* El **Administrador** utiliza un diseño completo con todos los apartados habilitados: stock, compras, ventas, opciones avanzadas y más.
### Menús adaptados por rol [#menús-adaptados-por-rol]
Los menús también se adaptan al rol de cada usuario para que cada uno vea solo lo que necesita.
En este ejemplo:
* El **Comercial** accede a un menú reducido, centrado en su operativa diaria: productos, documentación y ayuda.
* El **Administrador** dispone de un menú completo con acceso a todas las áreas del sistema: presupuestos, ventas, compras, gastos, nóminas, etc.
## Crear o editar un rol [#crear-o-editar-un-rol-]
1. Desde Dinaup Desktop navega hacia `Configuración`\

2. Haz clic en `Roles` \

3. Desde ahí puedes **Agregar** o **Editar** los roles existentes\

## Configuración de una sección [#configuración-de-una-sección]
Para dar acceso a una sección dentro de un rol, sigue estos pasos:
* Abre la configuración del rol desde **Configuración > Roles**.
* En el panel izquierdo, verás el listado de secciones activas. Si está vacío, no hay ninguna aún.
* Haz clic en el botón **Opciones...** (abajo a la izquierda).
* Selecciona **Administrar Secciones** en el menú emergente.
* Se abrirá la ventana de secciones (como la que ves en la imagen).
* Activa o desactiva el acceso a cada sección. Verás el estado actualizado como:
* 🔒 **Accesible** → el usuario podrá entrar a la sección.
* 🚫 **Sin acceso** → la sección estará oculta para ese rol.
### Configurar permisos de una sección [#configurar-permisos-de-una-sección]
Una vez hayas activado una sección en el panel izquierdo, toca definir qué puede hacer el rol dentro de esa sección.
* Haz clic en la sección (por ejemplo, **Empleados**).
* En la parte central verás todos los permisos disponibles (Agregar, Eliminar, Ver eliminados, Ver histórico)
* Haz clic en cada permiso para activarlo (✔) o desactivarlo (🚫).
* Usa los botones **Solo lectura** o **Todo** si quieres aplicar un conjunto de permisos de forma rápida.
### Diseños de las secciones [#diseños-de-las-secciones-]
El diseño de una `Sección` determina la distribución de los campos, así como los campos bloqueados, los campos obligatorios, etc.
Siempre que puedas, usa el diseño por defecto (**Sistema**). Si Dinaup lanza una actualización que cambia la distribución de pestañas y campos, un diseño personalizado no la incorpora. Usar **Sistema** reduce el mantenimiento.
#### Modificar un diseño [#modificar-un-diseño-]
Una vez creado el diseño, puedes modificarlo así.
1. Haz clic sobre el siguiente icono.
2. En la ventana que se abre, pulsa Configurar.
3. Continúa a partir del paso 5 de [Crear un diseño personalizado](/docs/cuenta/permisos-y-roles#crear-un-dise-o-personalizado)
### Asignar roles a un empleado [#asignar-roles-a-un-empleado-]
Asigna los roles desde la web, en el apartado Secure Link.
# Preguntas frecuentes (/docs/cuenta/preguntas-frecuentes)
Dudas frecuentes sobre cuenta y usuarios. Si no encuentras la respuesta, escribe a `soporte@dinaup.com` o abre el chat de ayuda en [play.dinaup.com](https://play.dinaup.com).
***
## Primeros pasos y cuenta [#primeros-pasos-y-cuenta]
* Accede a [dinaup.com](https://dinaup.com)
* Haz clic en "Registrarse" o "Crear cuenta"
* Completa el formulario con tus datos personales
* Verifica tu correo electrónico haciendo clic en el enlace que recibirás
* Una vez verificado, podrás acceder al panel de control
* Al iniciar sesión por primera vez podrás "solicitar unirte a una empresa ya existente" o "dar de alta una empresa nueva"
→ [Crear cuenta](/docs/cuenta/crear-cuenta)
Dinaup es una aplicación web que funciona en cualquier navegador moderno:
* **Navegadores recomendados**: Chrome, Firefox, Edge, Safari (versiones actualizadas)
* **Conexión a internet** estable
No necesitas instalar nada. Funciona en ordenador, tablet y móvil de forma responsive; algunas funciones como el TPV o los fichajes se manejan incluso mejor desde móvil o tablet.
Si conoces tu contraseña actual y solo quieres cambiarla:
* Inicia sesión en [dinaup.com](https://dinaup.com)
* Abre tu perfil desde el icono de la esquina superior derecha
* Entra en la sección de seguridad y elige cambiar contraseña
* Introduce la contraseña actual y la nueva, y guarda
Si no recuerdas tu contraseña actual, usa la opción "Olvidé mi contraseña" de la pantalla de inicio de sesión.
* Ve a la pantalla de inicio de sesión en [dinaup.com](https://dinaup.com)
* Haz clic en "Olvidé mi contraseña"
* Introduce tu correo electrónico registrado
* Recibirás un enlace para restablecer tu contraseña
* Sigue las instrucciones del correo para crear una nueva contraseña
Haz clic en el nombre de la empresa en la barra superior y selecciona otra. El cambio es inmediato, sin reiniciar, y Dinaup recuerda en cuál estabas la próxima vez que entres.
***
## Usuarios y permisos [#usuarios-y-permisos]
* El usuario debe registrarse en [dinaup.com](https://dinaup.com)
* Cuando valide su cuenta, debe solicitar unirse a la organización
* Un usuario administrador debe aceptar la solicitud
Da a cada persona el **mínimo acceso** que necesite y súbele permisos si hace falta. Invitar a todos como administrador "por si acaso" es el error más habitual.
Desde [dinaup.com](https://dinaup.com), un administrador puede acceder a **Usuarios** y:
* Activar y desactivar accesos a las diferentes soluciones Ready To Go
* Activar y desactivar opciones de desarrollo
* Cambiar el rol
* Cambiar el tipo de usuario: Administrador, Estándar, Básico, Solo lectura
* Bloquear al usuario
El rol se crea en **Dinaup Desktop** (la aplicación de escritorio para Windows) con un usuario administrador, desde **Configuración → Roles**. Después lo asignas al usuario desde el panel web de [dinaup.com](https://dinaup.com).
→ [Cómo crear y asignar roles de usuario](/docs/cuenta/permisos-y-roles/como-crear-y-asignar-roles-de-usuario-en-dinaup)
Cada usuario tiene la opción **Activar doble factor** en su ficha, dentro de la gestión de usuarios. Además de la contraseña, el usuario confirma su identidad con un código temporal al iniciar sesión.
Los administradores deben llevarlo siempre activado: su cuenta puede tocar datos de toda la empresa. También puedes definir una política de empresa que lo exija o lo recomiende al resto del equipo.
→ [Doble factor de autenticación](/docs/cuenta/doble-factor)
El número de usuarios no está limitado. Cada usuario adicional tiene un pequeño coste, salvo los usuarios bloqueados, que no cuentan.
→ [Cuenta y facturación](/docs/cuenta/cuenta-y-facturacion)
* Inicia sesión con un usuario administrador en [dinaup.com](https://dinaup.com)
* Navega al apartado de **Usuarios**
* Busca el usuario que quieras bloquear y pulsa "Editar"
* En tipo de usuario, selecciona "Bloqueado" y guarda
Los usuarios bloqueados no tienen coste y conservan su historial. Es la forma recomendada de dar de baja a alguien sin perder su rastro de actividad.
***
## Soluciones y licencia [#soluciones-y-licencia]
Se complementan y el acceso se activa por empleado:
* **Ready to Go TPV**: punto de venta para mostrador, barra, caja o call center. Si solo necesitas vender y cumplir con Verifactu, sin compras ni contabilidad.
* **Ready to Go Pymes**: añade compras, inventario multi-almacén, contabilidad y tesorería.
→ [Diferencias Solución Pymes y TPV](/docs/cuenta/precios/diferencias-solucion-pymes-y-tpv)
***
## Seguridad y datos [#seguridad-y-datos]
Sí. Dinaup cifra la información, realiza copias de seguridad diarias y cumple con el RGPD. Para el detalle legal, consulta [dinaup.com/legal](https://dinaup.com/legal).
Sí, la interfaz es responsive y funciona en móvil y tablet. Algunas funciones, como el TPV y los fichajes, se manejan incluso mejor desde estos dispositivos.
***
# Registro de Licencia (/docs/cuenta/registrar-empresa)
Para dar de alta una licencia en Dinaup necesitas disponer de un email válido y registrarte como empresa desde el portal oficial.
### Requisitos previos [#requisitos-previos]
* Correo electrónico válido
* Datos de tu empresa (Razón social, NIF/CIF, teléfono, dirección completa)
### Proceso de registro [#proceso-de-registro]
### Acceder al formulario de registro [#acceder-al-formulario-de-registro]
Accede a la página de registro en [https://dinaup.com/Register](https://dinaup.com/Register)
### Completar los datos de registro [#completar-los-datos-de-registro]
Rellena los datos solicitados en el formulario inicial y confirma el registro.
### Verificar el correo electrónico [#verificar-el-correo-electrónico]
Una vez completado el formulario, aparecerá el siguiente mensaje:
> Se ha enviado un email a la dirección indicada, por favor, sigue las instrucciones para activar tu cuenta.
### Activar la cuenta [#activar-la-cuenta]
Recibirás un correo electrónico de confirmación. Haz clic en el enlace de validación incluido en el email.
Tras hacer clic, verás el mensaje:
> La cuenta se ha activado correctamente, ya puedes iniciar sesión.
### Iniciar sesión [#iniciar-sesión]
Accede con tus credenciales recién creadas.
### **Registrar mi empresa** [#registrar-mi-empresa]
Si vas a crear el perfil de la empresa por primera vez, completa el formulario **"Registrar mi empresa"** con los siguientes datos:\\
**Datos de Empresa**
| Campo | Descripción |
| ---------------- | --------------------------------------------- |
| **Razón social** | Nombre legal de tu empresa |
| **NIF/CIF** | Número de identificación fiscal de la empresa |
| **Teléfono** | Teléfono de contacto de la empresa |
**Dirección**
| Campo | Descripción |
| ----------------- | ------------------------------------------------------- |
| **Dirección** | Dirección fiscal principal de la empresa |
| **Dirección 2** | Información adicional de dirección (piso, puerta, etc.) |
| **Municipio** | Ciudad o localidad |
| **Provincia** | Provincia o región |
| **Código Postal** | Código postal de la dirección |
| **País** | Selecciona tu país en el desplegable |
#### Finalizar el registro [#finalizar-el-registro]
Una vez completados todos los campos, pulsa el botón **"Crear perfil de empresa"** para finalizar el registro y activar tu licencia.
### Termina la configuración [#termina-la-configuración]
### Espera [#espera]
# Automatizaciones del servidor (/docs/desarrollo/automatizaciones-del-servidor)
Dinaup no solo responde cuando tú haces algo: su servidor ejecuta trabajo por su cuenta, de forma continua y sin que tengas que lanzarlo. Parte de ese trabajo lo configuras tú; otra parte es mantenimiento que ocurre solo. Esta página resume qué corre en segundo plano y qué controlas.
Si una tarea falla, no arrastra a las demás: se reintenta por su cuenta.
## Lo que tú configuras [#lo-que-tú-configuras]
### Peticiones HTTP programadas [#peticiones-http-programadas]
Configuras peticiones HTTP recurrentes desde una sección del sistema. Defines la URL, el método (GET, POST o PUT), una autenticación Bearer opcional, cada cuánto se dispara, en qué horario y qué días.
El servidor las lanza solo según tu programación. Guarda el resultado de cada ejecución (estado, duración y cuándo fue la última) para que puedas revisarlo.
Puedes fijar un ritmo dentro del horario laboral y otro fuera de él. Por ejemplo, más a menudo durante el día.
Usos típicos:
| Para qué | Ejemplo |
| ------------------------------ | ----------------------------------------- |
| Disparar flujos externos | Lanzar un escenario en n8n, Make o Zapier |
| Sincronizar con otros sistemas | Avisar a una API tuya de que revise datos |
| Comprobaciones periódicas | Verificar un estado cada pocos minutos |
Hay un intervalo mínimo por seguridad. Si programas por debajo de él, la petición no se acelera: se respeta ese mínimo.
### Webhooks salientes [#webhooks-salientes]
Cuando un registro cumple los criterios que definiste, Dinaup avisa solo a la URL que configuraste. No tienes que consultar nada: el aviso sale en cuanto ocurre.
Puedes desactivar todos los webhooks salientes de golpe desde la configuración.
→ [Webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes)
### Sincronización Verifactu con la AEAT [#sincronización-verifactu-con-la-aeat]
Si activas Verifactu y pones tu clave, el servidor sincroniza solo las facturas con la AEAT. Crea los registros de alta de las ventas nuevas, reintenta los que fallan y actualiza su estado (aceptado, rechazado y demás).
Tú solo configuras la clave. El resto va solo.
Sin una clave válida, Verifactu no sincroniza. Es lo primero que revisar si no ves movimiento.
→ [Guía de Verifactu](/docs/guias/verifactu)
### Control horario y fichajes [#control-horario-y-fichajes]
Con los horarios configurados por empleado, el servidor genera los turnos del día y actualiza su estado según avanza la jornada: programado, en curso o ausencia si no se fichó.
También cierra solo los fichajes que quedaron abiertos demasiadas horas. Es una protección ante olvidos.
→ [Guía de fichaje](/docs/guias/fichaje)
### Reserva de recursos [#reserva-de-recursos]
Cuando ligas líneas de pedido a un recurso o recambio, el servidor gestiona la reserva por su cuenta:
| Cuándo | Qué hace el servidor |
| ----------------- | -------------------- |
| Llega el momento | Activa la reserva |
| Vence el plazo | Libera el recurso |
| Cancelas la línea | Limpia la asociación |
## Lo que ocurre solo [#lo-que-ocurre-solo]
Este trabajo no lo configuras: es mantenimiento que Dinaup hace por su cuenta para que todo cuadre y vaya rápido.
**Propagación de datos relacionados.** Cuando cambias un dato maestro (por ejemplo, la marca en una ficha), Dinaup actualiza solo todos los registros que dependían de él. Configuras la relación una vez y el sistema mantiene todo en sincronía. No tienes que ir registro por registro corrigiendo a mano.
| Tarea | Efecto |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| Consistencia de estados | Repara estados de ventas y compras para que nada quede a medias |
| Recálculo contable | Ajusta nombres de cuenta, cuadres y márgenes para que los informes cuadren |
| Archivado del histórico | De madrugada mueve el histórico antiguo a un almacén aparte; las consultas recientes van rápidas |
En el archivado no se pierde nada: solo se reorganiza para que lo que consultas a diario responda antes.
### Campos auto-calculados [#campos-auto-calculados]
Cuando defines un campo como calculado en Flex, el servidor ejecuta su algoritmo solo al guardar. No tienes que recalcular nada tú.
→ [Algoritmos en Flex](/docs/desarrollo/flex/algoritmos)
## Una sola vez, aunque tengas varios servidores [#una-sola-vez-aunque-tengas-varios-servidores]
Las automatizaciones que salen "hacia fuera" (peticiones HTTP programadas, webhooks y sincronización con la AEAT) se ejecutan una sola vez aunque tengas varios servidores. No se duplican.
## Relacionado [#relacionado]
* → [Webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes)
* → [Webhooks entrantes](/docs/desarrollo/integraciones/webhook/entrantes)
* → [Algoritmos en Flex](/docs/desarrollo/flex/algoritmos)
* → [Verifactu](/docs/guias/verifactu)
* → [Fichaje](/docs/guias/fichaje)
# Dinaup & .NET (/docs/desarrollo/dinaup-and-.net)
Desarrolla sobre Dinaup desde .NET con los paquetes NuGet oficiales.
Paquetes NuGet oficiales: cliente API, logging, validaciones y acceso a base de datos.
# Ecosistema de desarrollo (/docs/desarrollo/ecosistema-desarrollo)
Desarrollar dentro de Dinaup es construir sobre cimientos que ya existen: secretos, archivos, base de datos, API y herramientas compartidas. Construir por tu cuenta significa montar y mantener todo eso desde cero. Estos son los cinco pilares que ya tienes resueltos.
***
### Gestión de secretos [#gestión-de-secretos]
Una app necesita contraseñas y claves para conectarse a la base de datos, enviar emails o cobrar pagos. Son los *secretos*. El error común es meterlos en archivos que acaban subidos a GitHub, donde quedan públicos sin que nadie se dé cuenta. Cualquiera podría acceder a tu información o destruir tus datos.
[**Dinaup Vault**](/docs/desarrollo/dotnet/sdk) obliga a guardar esas claves fuera del código y encriptadas:
* Si cambia una contraseña, no hay que actualizarla servidor por servidor.
* Varias aplicaciones comparten el mismo secreto sin copiarlo en cada una.
* Se automatiza lo que suele fallar por error humano.
***
### Gestión de archivos [#gestión-de-archivos]
Al principio basta con guardar los archivos en un servidor. Con el tiempo el volumen crece, cambian los equipos y aparecen los problemas. Un servidor propio rara vez está preparado para compartir, versionar o proteger esos datos. Por ejemplo, las imágenes públicas acaban junto a documentación confidencial, y no puedes exponerlas en un Marketplace ni dar acceso a una integradora.
En Dinaup los archivos se guardan en varias ubicaciones, protegidos frente a fallos de proveedor, borrados accidentales y desastres:
* Se conserva cada versión: si algo se sobrescribe, se puede recuperar.
* Los archivos no desaparecen si un servidor se cae o si alguien borra el FTP.
* Se comparten con URLs firmadas temporales (útiles para mostrar imágenes en una web).
**Caso real:** una empresa guardaba sus archivos en su propio servidor. Al querer integrarlos en una tienda online, el servidor no permitía generar enlaces temporales y tuvieron que migrar todo de urgencia.
***
### Base de datos [#base-de-datos]
Fuera de Dinaup tienes que crear la base de datos desde cero: configurarla, protegerla, hacer copias de seguridad y vincularla con otros sistemas. Cada informe o estadística lo construyes tú o lo pagas aparte.
Dentro de Dinaup no necesitas una base de datos adicional. Los datos están conectados, seguros y disponibles desde el panel de control (Play Dinaup):
* Usas informes, gráficas y plantillas sin crear nada nuevo.
* No pagas servidores extra de infraestructura.
* Un equipo de desarrollo nuevo entiende rápido cómo funciona todo, porque sigue estándares comunes.
**Ejemplo:** una empresa de golf desarrolló su app por fuera. Funcionaba, pero no podía cruzar datos con sus clientes, hacer informes ni generar plantillas de impresión. La rehicieron sobre nuestra API y, además de resolverlo, redujeron el coste a una décima parte.
***
### API [#api]
A medida que una empresa crece, crece su catálogo de aplicaciones: una para facturar, otra para fichar, otra para tareas, el correo, Excel… Cada una habla su propio idioma, y conectarlas entre sí se complica.
La API de Dinaup actúa como intérprete universal: cada nueva app solo necesita hablar con Dinaup, no aprender todos los idiomas.
* Reduce el coste de desarrollo.
* Permite cambiar de proveedor sin perder el conocimiento técnico.
* Evita datos duplicados y errores de sincronización.
***
### Independencia del equipo de desarrollo [#independencia-del-equipo-de-desarrollo]
Con un equipo externo, al principio todo va bien. Con el tiempo el programador se va, cambias de proveedor o el proyecto crece. Y descubres que nadie más entiende cómo está montado: sin documentación, todo a medida, semanas o meses para que alguien nuevo se ponga al día. Tu negocio queda atrapado en una caja negra.
En programación a esto se le llama proyecto legacy.
Sobre Dinaup el sistema está estandarizado:
* Cualquier otro equipo, certificado o nuevo, continúa el trabajo sin partir de cero.
* Hay documentación y buenas prácticas comunes.
* Usas herramientas compartidas como **Play Dinaup**, **Dinaup Vault**, **Dinaup Logs**, **Ready To Blazor**, **GitHub** y **ReadyToAutomate**.
* Los datos y la configuración están en tu cuenta. No dependes de quién hizo el desarrollo.
# Desarrollo (/docs/desarrollo)
Recursos para construir sobre Dinaup: personalizar sin código, conectar tu propio frontend o sistema externo, y consultar la referencia técnica.
# Preguntas frecuentes (/docs/desarrollo/preguntas-frecuentes)
Dudas frecuentes sobre desarrollo. Si no encuentras la respuesta, escribe a `soporte@dinaup.com` o abre el chat de ayuda en [play.dinaup.com](https://play.dinaup.com).
***
## Integraciones y API [#integraciones-y-api]
* Ve a **Administrador → Claves API** en [dinaup.com](https://dinaup.com)
* Haz clic en "+ Nueva Clave"
* Indica un nombre descriptivo para la clave
* Selecciona los permisos necesarios
* Guarda y copia la clave
La clave se muestra una sola vez. Cópiala y guárdala en un lugar seguro en el momento de crearla.
Dinaup se integra con múltiples plataformas:
* **Automatización**: Zapier, Make (Integromat), n8n
* **Análisis**: Power BI
* **Pagos**: Stripe
* **Sincronización**: PostgreSQL Sync
* **Desarrollo**: webhooks, API REST, SDK .NET, Cloudflare Workers
→ [Integraciones](/docs/desarrollo/integraciones)
Los webhooks conectan Dinaup con tus sistemas mediante notificaciones HTTP automáticas:
* **Salientes** (Dinaup → tu sistema): ve a **Desarrollo → Webhooks → Salientes**, crea un webhook, indica la URL de destino y selecciona los eventos que lo dispararán
* **Entrantes** (tu sistema → Dinaup): ve a **Desarrollo → Webhooks → Entrantes**, crea un endpoint y usa la URL generada para enviar datos a Dinaup
* Obtén tu clave API desde **Administrador → Claves API**
* En Make o Zapier, busca la app de Dinaup o usa el módulo HTTP
* Configura la autenticación con tu clave API
* Crea los flujos de automatización que necesites
→ [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n)
Sí. Conecta Power BI a tus datos mediante la sincronización con PostgreSQL o la API REST, y construye los paneles e informes que necesites sobre la información de Dinaup.
Los del usuario al que pertenece: el token hereda sus permisos y solo accede a lo que ese usuario puede ver y escribir. Si el usuario no puede escribir en una sección, la operación se rechaza con un error.
Usa la clave solo en tu **backend**. Nunca la incrustes en código público ni en el frontend de una web.
→ [Referencia de la API REST](/docs/desarrollo/integraciones/api-rest-referencia)
Dos topes protegen el servicio:
* **Paginación**: los informes devuelven resultados paginados; pide las páginas que necesites con `page` y `resultsPerPage`.
* **Límite de tasa por endpoint**: si lo superas, recibes `429 Too Many Requests` con la cabecera `Retry-After` indicando cuándo reintentar.
Las cifras exactas están en la [referencia de endpoints](/docs/desarrollo/integraciones/webhook/entrantes#límites-de-tasa).
Configura un [informe de Flex](/docs/desarrollo/flex/informes) con las columnas y filtros que quieras y ejecútalo por API: recibes sus filas en JSON, paginadas. La API dispara lo que tú ya dejaste preparado en Flex.
***
## Personalización sin código (Flex) [#personalización-sin-código-flex]
Sí, con **Dinaup Flex**: creas secciones de datos (tablas), defines sus campos con validaciones y autorrellenado, montas informes sin SQL y automatizas procesos. Requiere el permiso **Dinaup Flex**, pensado para personal técnico cualificado.
→ [Dinaup Flex](/docs/desarrollo/flex)
Sí, con los **documentos dinámicos** de Flex: defines la plantilla (por ejemplo, la impresión de facturas) y Dinaup la genera con tus datos. También puedes renderizarlas por API.
→ [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos) · [Plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas)
Sí. Si tu aplicación es .NET, el [SDK oficial](/docs/desarrollo/dotnet/sdk) te da tipado fuerte y nombres de campo legibles. Para cualquier otro lenguaje, la API REST es la vía universal.
***
# Análisis y resultado (/docs/guias/analisis)
Análisis calcula, para el periodo que elijas, cuánto entra, cuánto sale, qué te queda y cuánto le toca a Hacienda. Refleja lo que ya está registrado: si una cifra te chirría, suele faltar algo por emitir, importar o conciliar.
## Antes de empezar [#antes-de-empezar]
* Estás en el módulo de **Pymes** con facturas, gastos y cobros ya registrados.
* Para que aparezca el impuesto sobre el beneficio (IS/IRPF), el **ejercicio contable** del periodo necesita una tabla de tipos asignada.
## Elige el periodo [#elige-el-periodo]
Todo lo que ves en Análisis está acotado a un **rango de fechas**. El selector está arriba a la derecha, en la tarjeta *Pulso del negocio*, y arranca en los **últimos 30 días**.
Abre **Pymes → Más → Análisis**. La pantalla se titula **Pulso del negocio**.
Pulsa el selector de fechas de la cabecera y elige el periodo (un mes, un trimestre, el año…).
KPIs, resultado y gráficas se recalculan para ese rango.
## Los cuatro indicadores de cabecera [#los-cuatro-indicadores-de-cabecera]
La cabecera da cuatro indicadores del periodo:
| Indicador | Qué te dice |
| ---------------------- | ------------------------------------------ |
| **Ticket Medio** | El importe medio de tus facturas emitidas. |
| **Facturas Emitidas** | Cuántas ventas registraste en el rango. |
| **Facturas Recibidas** | Cuántas compras y gastos entraron. |
| **Clientes** | El total de clientes dados de alta. |
## El resultado del periodo [#el-resultado-del-periodo]
El bloque **Análisis Financiero → Detalle del periodo** organiza el resultado en tres columnas, de izquierda a derecha: lo que entra, lo que sale y lo que queda.
**Ingresos**
del periodo y el
**IVA cobrado**
(repercutido) a tus clientes.
**Gastos**
del periodo y el
**IVA pagado**
(soportado) a tus proveedores.
**Resultado bruto**
,
**liquidación de IVA**
,
**liquidación del impuesto**
y
**beneficio neto**
.
Cómo se encadenan los números del balance:
* **Resultado bruto** = Ingresos − Gastos. Lo que gana el negocio antes de impuestos.
* **Liquidación de IVA** = IVA repercutido − IVA soportado. Bajo el bloque aparece como *"Repercutido − Soportado"*, con la etiqueta **(a ingresar)** si sale positivo o **(a compensar)** si sale negativo.
* **Liquidación IS / IRPF** = el impuesto sobre el beneficio según el ejercicio (más abajo, por qué a veces pone IS y a veces IRPF).
* **Beneficio neto** = Ingresos − Gastos − liquidación de IVA − impuesto sobre el beneficio. Lo que queda después de pasar por Hacienda.
Bajo el resultado pueden aparecer dos bloques que solo se muestran cuando hay algo que enseñar: **Suplidos** (importes que adelantas por cuenta de un cliente o proveedor y no forman parte de tu margen) y **Devoluciones pendientes**. Si no tienes ninguno, no salen.
## Lo que está pendiente de cobrar y pagar [#lo-que-está-pendiente-de-cobrar-y-pagar]
Junto al resultado, el bloque **Pendientes** resume el dinero comprometido fuera de tu cuenta:
* **Pendiente de Cobro**: lo que te deben tus clientes de las ventas del periodo.
* **Pendiente de Pago**: lo que debes a tus proveedores.
## La liquidación de IVA [#la-liquidación-de-iva]
La cifra de **Liquidación IVA** del bloque Balance es la diferencia entre el IVA que cobras en tus ventas y el que pagas en tus compras:
* **IVA cobrado (repercutido)**: sale de tus facturas emitidas.
* **IVA pagado (soportado)**: sale de tus facturas recibidas.
Si el repercutido supera al soportado, sale **a ingresar** (toca pagar a Hacienda). Si pagaste más IVA del que cobraste, sale **a compensar**.
Análisis calcula la liquidación sobre las facturas del rango que elijas, para que sepas por dónde vas. No sustituye al modelo oficial que presentas a Hacienda: para eso tienes los **Documentos Oficiales** del módulo de Pymes.
## El impuesto sobre el beneficio [#el-impuesto-sobre-el-beneficio]
La última pieza del balance grava lo que ganas. La etiqueta cambia sola según la **tabla de tipos** asociada al ejercicio del periodo:
* **IS**: Impuesto de Sociedades, si tributas como sociedad.
* **IRPF**: si el ejercicio está configurado con una tabla de IRPF (típico del autónomo).
El cálculo se hace **por tramos**: a cada parte del beneficio se le aplica el tipo que le corresponde en esa tabla. Si cambias de ejercicio o ajustas su tabla, el cálculo se actualiza con ella.
### Ver el desglose por tramos [#ver-el-desglose-por-tramos]
La cifra de **Liquidación IS** (o IRPF) es un botón:
En el bloque **Balance**, haz clic sobre la cifra de **Liquidación IS** / **Liquidación IRPF**.
Se abre el diálogo **Cálculo del IRPF** con un **Resumen**: la **base imponible** (tu beneficio) y el **total impuesto a pagar**.
Debajo, el **Desglose por tramos**: para cada tramo, su rango (desde / hasta), el **tipo (%)** aplicado, la **base** que cae en ese tramo y la **cuota** resultante.
## Las gráficas: ingresos, gastos y tesorería [#las-gráficas-ingresos-gastos-y-tesorería]
Bajo el resultado, la tarjeta **Ingresos, Gastos y Tesorería** organiza el detalle en pestañas:
Evolución mensual de
**ingresos vs gastos**
, el
**beneficio mes a mes**
y el
**IVA repercutido vs soportado**
.
Top 10 clientes, ingresos por categoría, por tipo de factura y facturas por estado.
Top 10 proveedores, gastos por categoría, por tipo de operación y facturas por estado.
Cobros y pagos del periodo, con su desglose por
**método de pago**
.
Top categorías y productos
**vendidos**
y
**comprados**
.
Nóminas emitidas y reparto por empleado (si tienes el módulo).
La pestaña **Nóminas** solo aparece si tu cuenta gestiona nóminas. Casi todas las gráficas permiten **cambiar entre vista de gráfico y de tabla**.
*Ingresos por categoría* y *Gastos por categoría* solo valen si cada factura lleva su categoría correcta. Asígnalas al facturar: cómo, en la [referencia de Facturación](/docs/rtg/pymes/facturacion).
## Cuándo mirar Análisis [#cuándo-mirar-análisis]
* **Cada mañana**, para ver si vas por encima o por debajo de lo previsto.
* **Antes de cada liquidación**, para saber por dónde anda el IVA y el impuesto sobre el beneficio.
* **Al cerrar el mes**, para confirmar que el resultado cuadra.
* **Cuando una cifra te chirríe**: suele faltar algo por registrar o conciliar. Empieza por [Ponerse al día](/docs/rtg/pymes/ponerse-al-dia).
Si quieres un informe propio (con tus filtros, agrupaciones y columnas calculadas) lo montas con [Informes con Flex](/docs/desarrollo/flex/informes).
Para la referencia completa del módulo, ver [Análisis (referencia)](/docs/rtg/pymes/analisis) y [Ponerse al día](/docs/rtg/pymes/ponerse-al-dia).
# Cómo funciona el stock (/docs/guias/como-funciona-el-stock)
Una venta no descuenta stock por sí misma. Pasa por la [política de tu empresa](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos), que decide si nace un movimiento y con qué efecto. Ese efecto es lo único que mueve las dos cuentas del inventario.
¿Buscas solo lo justo para empezar? → [Stock: lo esencial](/docs/guias/stock-lo-esencial).
***
## El recorrido completo [#el-recorrido-completo]
**Por eso las correcciones se hacen con devoluciones, no editando:** anular una venta no toca el stock por arte de magia, y editar una venta no recalcula existencias. Cada movimiento se rige por su propio estado.
***
## Venta ≠ Movimiento [#venta--movimiento]
Son dos mundos separados a propósito.
| La venta 🧾 | El movimiento de stock 📦 |
| ----------------------------------------------------------------------- | --------------------------------------------- |
| Documento comercial, con su propio ciclo (pendiente, cobrada, anulada). | Salida o entrada de inventario. |
| No mueve el inventario por sí misma. | Lo genera el sistema automáticamente. |
| No se edita: un error se corrige con una devolución. | Su estado decide cuánto baja y de qué cuenta. |
| Es inmutable una vez hecha. | Se reparte por lotes y ubicaciones. |
***
## Dos cuentas: disponible vs físico [#dos-cuentas-disponible-vs-físico]
El stock no es un número, son **dos**. Casi todo el modelo se entiende mirando cuál de las dos toca cada operación.
* **Disponible**: lo que aún puedes vender. Baja en cuanto reservas o entregas.
* **Físico**: lo que hay de verdad en la estantería. Solo baja cuando el producto sale (entrega).
La relación entre ambas es una resta:
```
disponible = físico real
− reservado (ventas pendientes de entregar)
− en revisión (stock en cuarentena)
```
Si disponible y físico difieren, casi siempre hay algo reservado o algo en revisión. No es un error: son dos cuentas con propósitos distintos.
***
## Los estados de una salida [#los-estados-de-una-salida]
Una salida nace en un estado, y ese estado determina su efecto sobre las dos cuentas.
| Estado | Disponible | Físico | Significado |
| -------------- | ---------- | -------- | ---------------------------------------- |
| **Pendiente** | baja | intacto | Reservado: vendido, aún no entregado. |
| **Completada** | baja | baja | Entregado: sale de verdad y asigna lote. |
| **Anulada** | revierte | revierte | Cancelado: el cálculo se deshace. |
En el TPV lo normal es la **entrega directa**: la salida nace completada, baja las dos cuentas y asigna el lote en el acto. La **reserva** (pendiente) es para "se vende hoy, sale más tarde".
***
## Lotes: FIFO vs FEFO [#lotes-fifo-vs-fefo]
Cuando un producto va por **lotes**, la salida no elige a mano de qué lote sale: una **estrategia por producto** ordena los lotes y el sistema consume en ese orden, usando varios si hace falta.
* **FIFO**: *first in, first out*, sale primero lo que entró antes.
* **FEFO**: *first expired, first out*, sale primero lo que antes caduca.
Eliges la estrategia en la ficha del producto. FEFO es la opción natural para productos con caducidad.
***
## Sobreventa: la regla la pones tú [#sobreventa-la-regla-la-pones-tú]
¿Qué pasa si se intenta vender más de lo que hay? Lo decides por producto:
| Regla | Qué hace |
| ------------ | --------------------------------------------------------- |
| **Permitir** | Vende igual. Lo que falta sale sin lote asignado. |
| **Avisar** | Vende y deja constancia para que lo revises después. |
| **Bloquear** | Recorta a lo disponible. Nunca deja el stock en negativo. |
***
## Devoluciones y cuarentena [#devoluciones-y-cuarentena]
Una devolución no vuelve directa a la venta: crea una **entrada** hacia un hueco de **devoluciones** del almacén, que está **en revisión**. Lo devuelto suma al **físico** (está en tu almacén) pero queda fuera del **disponible** hasta que lo compruebas, para que no revendas por error algo sin revisar.
Es la misma mecánica de los dos números: la cuarentena es físico que todavía no es disponible.
***
## Vender en una unidad, controlar en otra [#vender-en-una-unidad-controlar-en-otra]
El control interno es siempre en la unidad base (por ejemplo, gramos), pero vendes y ves la unidad cómoda. El sistema convierte y formatea.
***
## Multi-almacén [#multi-almacén]
Cada venta indica **de qué almacén** sale, y cada almacén puede marcarse como servible o de uso solo interno. El stock baja del almacén correcto, sin mezclar cuentas.
No hay rutas automáticas de un almacén a otro. Para mover stock entre ubicaciones usas un [traspaso](/docs/rtg/pymes/inventario-y-precios/movimientos-de-inventario): una salida en el origen y una entrada en el destino.
***
## Por qué cuadra siempre [#por-qué-cuadra-siempre]
El stock no depende de que todo ocurra en el instante exacto de la venta. El sistema combina dos caminos hacia el mismo resultado y nunca duplica un movimiento:
Si se corta la luz o la conexión a media venta, el repaso de seguridad recupera lo que quedó a medias al volver; y si algo se procesa dos veces, no se descuenta dos veces.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Porque vender y mover inventario son dos cosas distintas. La venta es el documento comercial; el movimiento de stock lo decide la política de tu empresa. Separarlos es lo que permite reservar, anular o corregir sin que las cuentas se descuadren.
El disponible es lo que puedes vender ahora mismo; el físico es lo que hay realmente en la estantería. Coinciden casi siempre, y se separan cuando hay stock reservado (vendido pero no entregado) o en revisión (devoluciones por comprobar).
Por la estrategia que marques en el producto: FIFO (sale antes lo que entró antes) o FEFO (sale antes lo que antes caduca). Si una venta no cabe en un solo lote, el sistema reparte entre varios en ese orden.
Depende de la regla de sobreventa que fijes por producto: permitir (vende igual), avisar (vende y te avisa) o bloquear (recorta a lo disponible y nunca deja el stock en negativo).
Porque entra en cuarentena: suma al stock físico pero queda fuera del disponible hasta que lo revisas. Así no revendes algo sin comprobar su estado.
No se pierde nada y no se descuenta dos veces. Un repaso periódico de seguridad recupera las ventas que quedaron sin movimiento, y cada movimiento es único: reprocesarlo no lo duplica.
***
## Sigue explorando [#sigue-explorando]
* [Stock: lo esencial](/docs/guias/stock-lo-esencial). La versión rápida para empezar.
* [Montar tu inventario](/docs/guias/montar-tu-inventario): el recorrido de puesta en marcha.
* [Stock por almacén](/docs/rtg/pymes/inventario-y-precios/stock-por-almacen): la matriz de existencias y las cifras de cabecera.
* [Movimientos de inventario](/docs/rtg/pymes/inventario-y-precios/movimientos-de-inventario): entradas, salidas, ajustes y traspasos.
* [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos): trazabilidad, caducidad y estado.
* [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes): ubicaciones y quién ve qué.
# Conciliación bancaria con IA (/docs/guias/conciliacion-ia)
Conciliar es cuadrar lo que dice el banco con lo que dicen tus facturas. En Dinaup es una pantalla con un recorrido fijo: el sistema clasifica y empareja lo que puede, te enseña qué hizo, y tú decides el resto.
## Antes de empezar [#antes-de-empezar]
La conciliación trabaja sobre los **movimientos** de una cuenta bancaria, así que necesitas haber **importado el extracto** de esa cuenta. Si aún no lo has hecho, mira [Cómo importar extractos](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios).
## Abre el conciliador de una cuenta [#abre-el-conciliador-de-una-cuenta]
Ve a **Pymes → Cuentas bancarias** y abre la cuenta que quieras cuadrar.
En la barra de la cuenta tienes los botones de trabajo: **Importar extracto**, **Clasificar**, **Conciliar**, **Analizar con Yudo** y **Ver extracto**.
Pulsa **Conciliar**. Se abre la pantalla **Conciliación bancaria**, que junta clasificar (decir de quién y de qué tipo es cada movimiento) y conciliar (enlazarlo con su factura, cobro o pago) en un mismo recorrido.
## El recorrido: cuatro etapas, en orden [#el-recorrido-cuatro-etapas-en-orden]
La cabecera de la pantalla **es la navegación**. Cada etapa es un paso, y la pantalla arranca sola en el primer paso que tenga trabajo pendiente:
Movimientos de los que aún no sabemos quién es ni qué tipo son.
Ya tienen entidad, pero falta la factura, cobro o pago que los justifica.
Parejas movimiento ↔ operación ya encontradas, listas para revisar.
Diferencias pequeñas: comisiones, redondeos, cambio de divisa.
Arriba a la derecha verás dos cifras que son tu marcador: **Sin conciliar** (la suma neta de todo lo pendiente; el objetivo es verla bajar) y **confirmados** (lo que ya has cuadrado en esta sesión).
## Lo que el sistema hace solo (y cómo deshacerlo) [#lo-que-el-sistema-hace-solo-y-cómo-deshacerlo]
Al abrir la pantalla, Dinaup empareja lo evidente sin preguntarte: movimientos cuyo **nº de factura aparece en el concepto del banco y el importe coincide**. Si lo hace, te avisa.
Todo lo automático aparece en el panel **«Qué hizo el sistema automáticamente»**, que se despliega solo cuando ha escrito algo. Ahí ves, decisión a decisión, qué movimiento tocó, qué tipo o entidad le puso y por qué motivo, separando lo que vino de **reglas** de lo que vino de **factura exacta**.
Cada decisión automática lleva su botón. Y arriba del panel tienes **Deshacer N**: revierte de golpe toda la tanda (reglas, autoclasificación e IA) y los movimientos vuelven a su estado anterior. Te pide confirmación antes, porque toca varios registros a la vez.
## Etapa 1 · Clasificar lo que no tiene dueño [#etapa-1--clasificar-lo-que-no-tiene-dueño]
Un movimiento "sin clasificar" es uno del que no sabes ni el **tipo** (nómina, comisión, IVA, transferencia interna…) ni la **entidad** (qué cliente o proveedor es). Tienes cuatro formas de resolverlo, de la más automática a la más manual:
| Herramienta | Qué hace |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Agrupar con IA** | La IA junta los movimientos en grupos con sentido (p. ej. "Suministros", "Comisiones") y propone tipo y entidad para cada uno. Aplicas un grupo entero o todo de golpe. |
| **Aplicar reglas (N)** | Pasa tus reglas de clasificación por los movimientos sin clasificar y guarda lo que coincida. |
| **Clasificador completo** | Abre el clasificador por meses, con selección múltiple y asignación en lote. |
| **A mano** | En cada fila eliges **Tipo** y **Entidad** y confirmas. |
El **clic derecho** sobre una fila abre acciones rápidas: **puntear**, **crear regla con IA**, **crear gasto** o **ingreso**, y asignar tipos habituales (comisión bancaria, transferencia interna, nómina, IVA, Seg. Social…).
Impuestos, Seguridad Social o comisiones llegan al banco sin una factura detrás. Si su [tipo de movimiento](/docs/rtg/pymes/tesoreria/tipos-de-movimiento) tiene puesto el tipo y la categoría de gasto, lo creas como gasto desde el propio apunte (y entra en tu informe de ingresos y gastos) sin ir a registrarlo aparte.
En cualquier fila, el botón de **regla** crea una regla de clasificación tomando el concepto del movimiento. Y si **seleccionas con el ratón** un trozo del concepto (por ejemplo solo el nombre del proveedor), te ofrece crear la regla con ese texto exacto. La siguiente vez que llegue ese concepto, se clasifica solo.
## Etapa 2 · Asociar movimiento con su operación [#etapa-2--asociar-movimiento-con-su-operación]
Aquí el movimiento ya tiene entidad, pero le falta la factura. Los movimientos se agrupan **por entidad**, con los más antiguos arriba (la deuda vieja es la urgente). Para cada uno:
Pulsa **Asociar con IA** (de toda la etapa o por grupo) para que proponga qué operación corresponde a cada movimiento, o **selecciona la operación** a mano del desplegable de esa entidad.
Si no aparece, **busca** en otra sección (Ventas, Compras, Cobros, Pagos, Movimientos) con el botón de búsqueda, o **crea el gasto/ingreso** que falta directamente desde ahí.
Comprueba la barra de **importe**: te dice cuánto cubren las operaciones elegidas y si el importe es exacto o queda diferencia. Puedes asociar **varias operaciones** a un mismo movimiento. Es el caso de las liquidaciones de pasarelas y marketplaces (Stripe, Amazon), donde un solo ingreso del banco salda muchas ventas. Para que esos ingresos lleguen marcados como liquidación, configura su [tipo de movimiento y una regla](/docs/guias/configurar-conciliacion-bancaria).
Pulsa **Conciliar**. Eso enlaza el movimiento con esas operaciones.
Si una entidad no cuadra y no sabes por qué, el botón **Investigar** abre una vista que cruza sus movimientos de banco con sus ventas y compras, para entender dónde está el desajuste.
**Puntear** marca un movimiento como conciliado *sin* vincularlo a ninguna factura. Es útil para ajustes o cuando ya cuadraste por otro lado, pero la factura que le correspondía seguirá apareciendo como pendiente y podría emparejarse por error con un movimiento futuro. Por eso te pide confirmación.
## Etapa 3 · Revisar y confirmar las parejas [#etapa-3--revisar-y-confirmar-las-parejas]
Las parejas que Dinaup encuentra cruzando **entidad, importe y fecha** llegan aquí para tu visto bueno. Cada pareja muestra sus motivos (**€ exacto**, **nº factura** en el concepto, **fecha** cercana) y los días de diferencia entre movimiento y operación.
* Una pareja con el icono de **verificado** es de **alta confianza**.
* Una marcada **"revisar"** es de confianza media: míralo antes de confirmar.
Puedes confirmar **una a una**, **por entidad** o pulsar **Confirmar todos**, que confirma de golpe solo las de alta confianza y deja las dudosas para que las repases tú.
Confirmar una pareja vincula los dos registros (movimiento y operación) de forma permanente. Por eso las de confianza media no entran en "Confirmar todos": esas se confirman a mano, una a una.
## Residuos: las diferencias pequeñas [#residuos-las-diferencias-pequeñas]
Tras conciliar a veces sobra un resto mínimo: una comisión, un redondeo, una diferencia de cambio. Eso va a **Residuos**, y no urge. Por cada uno puedes:
* **Crear gasto / ingreso**: genera la operación que justifica la diferencia (p. ej. la comisión bancaria), con la fecha del movimiento.
* **Resuelto**: lo das por cuadrado, puntea el movimiento y asume la diferencia.
## Enseña a la IA para corregir menos [#enseña-a-la-ia-para-corregir-menos]
En el botón de **conocimiento** (el cerebro, arriba a la derecha) refuerzas el aprendizaje con tu histórico y escribes **indicaciones** en lenguaje normal (por ejemplo, *"los pagos de Stripe son comisiones"*) que la IA aplica en cada análisis. Cuanto mejor el contexto, menos corriges a mano.
Esta guía es el recorrido de trabajo. Para la referencia completa tienes [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria), [Conciliación avanzada](/docs/rtg/pymes/tesoreria/conciliacion-avanzada), [Reglas de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios) y [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias).
# Conectar tu primera integración (/docs/guias/conectar-una-integracion)
Esta guía te lleva de cero a un flujo funcionando: una clave API acotada, el método que te conviene y una automatización en marcha (por ejemplo, nueva venta en Dinaup → aviso a Make). Los pasos básicos no requieren programar.
## Antes de empezar [#antes-de-empezar]
* Una **cuenta de administrador** en [dinaup.com](https://dinaup.com) para crear claves API.
* Decidido **qué quieres conectar** (tu tienda, un CRM, una hoja de cálculo, Slack…).
***
## Las tres formas de conectar [#las-tres-formas-de-conectar]
No son excluyentes; muchas integraciones combinan dos.
| Quieres... | Usa | Dirección |
| ----------------------------------------------------------------- | ------------------ | ----------- |
| **Leer** informes o **escribir** registros desde tu propio código | API REST | Tú → Dinaup |
| **Enterarte** en el momento de que algo cambia en Dinaup | Webhooks salientes | Dinaup → Tú |
| Conectar Dinaup con otras apps **sin programar** | Zapier, Make o n8n | Las dos |
Si dudas, empieza por la opción sin código (Zapier / Make / n8n): monta el flujo completo sin escribir una línea y pasas a la API REST cuando necesites más control.
→ Visión completa de canales disponibles: [Integraciones](/docs/desarrollo/integraciones)
***
## El recorrido [#el-recorrido]
### Crea una clave API con permisos acotados [#crea-una-clave-api-con-permisos-acotados]
Toda integración se autentica con una **clave API**. La clave va vinculada a un usuario y **hereda sus permisos**: solo accede a lo que ese usuario puede ver y escribir.
La decisión que más importa para tu seguridad: **crea un usuario específico para la integración** y dale acceso únicamente a las secciones que el flujo necesita. Si la clave se filtra, el daño está acotado y puedes revocarla sin tocar a nadie más.
1. Entra al **Panel de administración** en [dinaup.com](https://dinaup.com).
2. Ve a **Claves API** y pulsa **Crear clave API**.
3. Asóciala al **usuario** de la integración (con permisos mínimos).
4. **Copia la clave y guárdala** en un gestor de secretos o en la configuración de tu servidor.
La clave **solo se muestra una vez**. Si la pierdes, genera otra. Y úsala siempre en el **backend**, nunca en el JavaScript de una web.
👉 [Ver artículo: Claves API](/docs/cuenta/claves-api)
### Elige tu método [#elige-tu-método]
Con la clave en la mano, decide por dónde tiras según lo que quieras lograr:
* **API REST**: tu sistema le pregunta a Dinaup. Lee informes, genera documentos o escribe registros desde cualquier lenguaje. Base: `https://webhook.dinaup.com`.
* **Webhooks salientes**: Dinaup avisa a tu sistema. Configuras una sección y una URL, y recibes un aviso en cuanto algo cambia. Cero *polling*.
* **Zapier / Make / n8n**: sin código. Conectas Dinaup con miles de apps mediante webhooks, arrastrando bloques.
👉 [Ver: referencia de la API REST](/docs/desarrollo/integraciones/api-rest-referencia) · [Webhooks](/docs/desarrollo/integraciones/webhook) · [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n)
### Prueba la conexión (ping y whoami) [#prueba-la-conexión-ping-y-whoami]
Antes de montar nada, comprueba que la autenticación funciona con dos llamadas:
* **Ping**: confirma que el servidor responde. No necesita clave.
* **Whoami**: confirma que **tu clave es válida** y te dice con qué usuario operas.
```bash
# 1. El servidor está vivo (sin autenticación)
curl -X GET "https://webhook.dinaup.com"
# 2. Mi clave funciona y opero como el usuario correcto
curl -X GET "https://webhook.dinaup.com/api/whoami" \
-H "Authorization: Bearer "
```
Si `whoami` te devuelve los datos del usuario que esperabas, vas bien. Si recibes un `401`, la clave es inválida o no la estás enviando en la cabecera.
¿Prefieres no usar la terminal? Tienes un **Playground** dentro de Dinaup para lanzar estas llamadas desde el navegador: [Abrir Playground](https://play.dinaup.com/App/Dev/IncomingWebhooks).
👉 [Ver: referencia completa de endpoints](/docs/desarrollo/integraciones/webhook/entrantes)
### Lee o escribe tus datos [#lee-o-escribe-tus-datos]
Ya conectado, haz tu primera operación real con la API REST:
* **Leer**: configura un [informe en Flex](/docs/desarrollo/integraciones/api-rest-referencia) con las columnas y filtros que quieras y ejecútalo por API. Te devuelve las filas en JSON, paginadas.
* **Escribir**: usa **WriteOperations**. La misma llamada sirve para crear y para editar un registro; el borrado es lógico.
```bash
# Ejecutar un informe ya configurado en Flex
curl -X POST "https://webhook.dinaup.com/api/reports?id=&page=1&resultsPerPage=100" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{}'
```
La API **dispara lo que ya dejaste preparado** en Dinaup. Primero configuras el informe o el documento (columnas, filtros, plantilla) y luego lo ejecutas por API. Activa `safeColumnsName=true` para que los nombres de columna no cambien si renombras un campo.
👉 [Ver: referencia de la API REST](/docs/desarrollo/integraciones/api-rest-referencia)
### Monta tu primer flujo automático [#monta-tu-primer-flujo-automático]
Que Dinaup **reaccione solo** ante un evento. El caso típico (**nueva venta → aviso a una herramienta externa**) se monta con un **webhook saliente**.
1. En **Dinaup Flex** (o el módulo **Desarrollo**), crea un webhook saliente.
2. Elige la **sección** a vigilar (ej. Ventas/Ingresos) y marca **Disparar en nuevos**.
3. Pega la **URL de destino**: por ejemplo, la que te da un escenario de **Make** o **n8n**.
4. Añade un **Bearer Token** para que tu receptor verifique que el aviso viene de Dinaup.
5. Crea una venta de prueba en Dinaup y confirma que tu escenario la recibe.
A partir de ahí, el escenario de Make/n8n hace lo que quieras con el dato: mandarlo a Slack, a una hoja de cálculo, a tu CRM...
👉 [Ver: configurar webhooks salientes](/docs/desarrollo/integraciones/webhook) · [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n)
***
## Un ejemplo de punta a punta [#un-ejemplo-de-punta-a-punta]
Avisar a tu equipo cada vez que entra una venta. Así encajan las piezas:
| Paso | Qué haces | Dónde |
| ---- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| 1 | Creas una clave API con un usuario de permisos mínimos | [Claves API](/docs/cuenta/claves-api) |
| 2 | Eliges **webhook saliente** (quieres enterarte de un cambio) | [Webhooks](/docs/desarrollo/integraciones/webhook) |
| 3 | Verificas la conexión con `whoami` | [Endpoints](/docs/desarrollo/integraciones/webhook/entrantes) |
| 4 | Creas un escenario en **Make** que recibe el webhook y publica en Slack | [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n) |
| 5 | Configuras el webhook saliente en la sección Ventas con la URL de Make | [Webhooks salientes](/docs/desarrollo/integraciones/webhook) |
Resultado: una venta nueva en Dinaup dispara un POST a Make, que lo reenvía a Slack. Sin *polling*, sin código en tu servidor.
***
## Buenas prácticas desde el primer día [#buenas-prácticas-desde-el-primer-día]
| Práctica | Por qué |
| -------------------------------------------- | ---------------------------------------------------- |
| Un **usuario distinto por integración** | Revocas o limitas cada una sin afectar al resto |
| **Permisos mínimos** en ese usuario | La clave solo alcanza las secciones que el flujo usa |
| Clave **solo en el backend** | Nunca en el frontend ni en repositorios públicos |
| **Verifica el Bearer Token** en tus webhooks | Confirmas que el aviso viene de Dinaup |
| Responde `2xx` **en menos de 10 segundos** | Dinaup espera confirmación; si tardas, reintenta |
| **Rota** las claves cada cierto tiempo | Minimiza el riesgo si alguna se filtra |
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Con Zapier, Make o n8n montas el flujo completo arrastrando bloques. La API REST y el SDK son para cuando quieres control total desde tu propio código.
La API REST es la dirección tú → Dinaup: tú preguntas y Dinaup responde. El webhook saliente es Dinaup → tú: Dinaup te avisa cuando algo cambia, sin que tengas que preguntar. Muchas integraciones usan las dos.
Porque la clave hereda los permisos de su usuario. Con un usuario dedicado y acotado, la integración solo toca lo que necesita, y puedes revocarla sin afectar a nadie más.
Las capacidades de integración forman parte de Dinaup. Para los detalles de tu plan, consulta la página de Precios en dinaup.com.
***
→ [Claves API](/docs/cuenta/claves-api)
→ [Referencia de la API REST](/docs/desarrollo/integraciones/api-rest-referencia)
→ [API y Webhooks](/docs/desarrollo/integraciones/webhook)
→ [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n)
→ [Todas las integraciones](/docs/desarrollo/integraciones)
# Configura la conciliación bancaria (/docs/guias/configurar-conciliacion-bancaria)
Esta preparación se hace una vez por empresa. Das de alta tus cuentas, traes el primer extracto, repasas los tipos de movimiento y dejas unas reglas que clasifiquen solas. Con la base montada, el día a día es entrar y confirmar.
## Antes de empezar [#antes-de-empezar]
Necesitas acceso a **Pymes → Tesorería**. Si no ves las cuentas bancarias, pídele al administrador que active el módulo.
## El recorrido [#el-recorrido]
### Da de alta tus cuentas bancarias [#da-de-alta-tus-cuentas-bancarias]
Crea una cuenta por cada IBAN con el que operas y asóciala a su banco. Ese vínculo es lo que después identifica las comisiones y los movimientos de cada entidad.
→ [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias) · [Bancos](/docs/rtg/pymes/tesoreria/bancos)
### Importa tu primer extracto [#importa-tu-primer-extracto]
Desde la ficha de la cuenta, pulsa **Importar** y sube el archivo que descargas de tu banca electrónica (CSV o Excel). Dinaup lee la fecha, el importe y el concepto de cada línea.
→ [Importar extractos bancarios](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios)
### Repasa los tipos de movimiento [#repasa-los-tipos-de-movimiento]
El **tipo de movimiento** es la etiqueta que dice de qué es cada apunte: una venta, una compra, una comisión, una nómina, un impuesto… Es lo que decide **contra qué se puede conciliar** ese movimiento.
Mira los que vienen de serie y crea los que le falten a tu negocio. Si rellenas su **tipo y categoría de gasto** (o de ingreso), das de alta los apuntes sin factura (impuestos, Seguridad Social, comisiones) desde el propio movimiento.
Y si cobras a través de una pasarela o un marketplace (Stripe, Amazon…) que te ingresa en bloque varias ventas, marca en su tipo la casilla **Liquidación de varias operaciones** para señalar que ese apunte se cuadra contra [varias operaciones](/docs/rtg/pymes/tesoreria/tipos-de-movimiento).
### Crea tus primeras reglas [#crea-tus-primeras-reglas]
En la ventana de **clasificación**, crea reglas para los conceptos que se repiten cada mes (tu proveedor de luz, las comisiones del banco, las cuotas…). A partir de ahí, esos movimientos se clasifican solos en cuanto importas el extracto.
→ [Reglas de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios)
## Contra qué se puede conciliar [#contra-qué-se-puede-conciliar]
Un movimiento del banco se cuadra con tus **ventas, ingresos, compras, gastos**, con sus **cobros y pagos**, o con **otra cuenta** (las transferencias internas).
Puedes activar que la conciliación **busque por pedido o por presupuesto**. No cuadra el pedido ni el presupuesto en sí: los usa para llegar a **la venta que salió de ellos**. Si ese pedido o presupuesto todavía no tiene venta, no se podrá conciliar.
## Qué consigues al conciliar [#qué-consigues-al-conciliar]
Cuando la pantalla te dice *"este movimiento es de esta venta"* y pulsas **Conciliar**, Dinaup registra por ti el **cobro** de esa venta. La marca como **cobrada**, con la **fecha real** del apunte del banco. Lo mismo con las compras y sus pagos. Por eso cuadrar el banco mantiene a la vez al día el estado de tus facturas.
## Ya puedes conciliar [#ya-puedes-conciliar]
Con la base montada, el día a día es revisar las sugerencias y confirmar.
→ [Conciliación bancaria con IA](/docs/guias/conciliacion-ia)
# Configurar el TPV desde cero (/docs/guias/configurar-el-tpv)
## Antes de empezar [#antes-de-empezar]
* Una **licencia activa** con el módulo de **TPV** disponible en tu cuenta.
* Acceso de **administrador** a [play.dinaup.com](https://play.dinaup.com) para crear tipos de venta, cajas y cuentas bancarias.
* Si vas a cobrar con tarjeta, el **datáfono** (integrado o manual) a mano.
Esta guía te lleva desde los ajustes iniciales hasta tu primer cierre de caja, en el orden en que conviene hacerlos. Cada paso enlaza a su página de referencia para el detalle.
Sigue los pasos en orden. La venta y el cierre solo funcionan una vez montada la base: tipo de venta, cuenta bancaria y caja.
***
## El recorrido completo [#el-recorrido-completo]
### Configura el TPV [#configura-el-tpv]
Entra en la **App de TPV** desde [play.dinaup.com](https://play.dinaup.com) y prepara la base del punto de venta:
* Crea un **tipo de venta** propio para el TPV (con su numeración para ventas ordinarias y otra para rectificativas), así separas las ventas de caja del resto.
* Si vas a usar pantalla táctil, activa **TPV Modo Táctil** en ese tipo de venta.
* Marca ese tipo como **predeterminado** para que el botón de iniciar venta arranque solo con él.
* Da de alta tus **productos**, sus **precios** y las **categorías de venta** con imagen (clave en modo táctil).
* Oculta del TPV lo que el equipo de mostrador no necesita (impuestos, retenciones y tipos de venta avanzados) para una interfaz limpia.
Tienes el proceso completo, incluido el bloqueo de precios y descuentos, en [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv).
### Asocia la cuenta bancaria para el cobro con tarjeta [#asocia-la-cuenta-bancaria-para-el-cobro-con-tarjeta]
Si vas a cobrar con datáfono, da de alta la **cuenta bancaria** a la que entra ese dinero en `Apps` > `Pymes` > `Cuentas Bancarias`. La necesitas en el paso siguiente para vincularla a la caja.
El detalle, junto con el resto de la configuración, está en [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv).
### Crea y vincula una caja al dispositivo [#crea-y-vincula-una-caja-al-dispositivo]
La caja es el cajón de efectivo del puesto. Para cobrar desde este navegador tienes que crearla y vincularla:
* Da de alta la **caja** en la app de TPV.
* En su ficha, asígnale la **cuenta bancaria** del paso anterior en el campo de pago con tarjeta. Así, lo que cobres con datáfono aterriza en el sitio correcto.
* Pulsa **Vincular caja** para asociarla a este navegador. Dinaup la detecta sola la próxima vez que entres desde este equipo.
Cómo hacerlo, en [Configurar y vincular una caja](/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja).
La vinculación es **por navegador**. Si vas a cobrar desde varios equipos o tablets, repite la vinculación en cada uno.
### Haz tu primera venta [#haz-tu-primera-venta]
Con la base lista, monta un ticket de prueba para comprobar que todo funciona:
* Pulsa **Nueva venta**.
* Elige el **cliente**: genérico para un ticket anónimo, o registrado para traer sus datos fiscales y descuentos.
* Añade **productos** con el buscador, la búsqueda avanzada o el lector de código de barras.
* Ajusta **cantidades y descuentos** y revisa el total.
El recorrido completo, con los métodos de búsqueda y los niveles de descuento, está en [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida).
### Cóbrala (efectivo, tarjeta o mixto) [#cóbrala-efectivo-tarjeta-o-mixto]
Con la venta montada, pasa al cobro y elige cómo paga el cliente:
* **Efectivo**: teclea el importe recibido y Dinaup calcula el cambio. Ese dinero suma a la caja.
* **Tarjeta**: cobra con el datáfono (integrado o manual). El importe va a la cuenta bancaria.
* **Pago mixto**: reparte el total entre efectivo y tarjeta; cada parte aterriza en su depósito.
Después decides qué entregas: un **ticket** o, si el cliente lo pide, una **factura simplificada**.
Todas las formas de pago, incluido el link de pago y el cobro parcial, en [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro).
El efectivo entra en la **caja** y la tarjeta va a la **cuenta bancaria**. Tenerlo claro ahora es lo que hace que el cierre te cuadre al final del turno.
### Cierra la caja al final del turno [#cierra-la-caja-al-final-del-turno]
Cuando termines la jornada, haz el cierre para cuadrar el dinero:
* Crea un nuevo cierre, elige el **depósito** (la caja o la cuenta), el **rango de fechas** y el **responsable**.
* Pulsa **Recalcular** para que Dinaup sume entradas, salidas, cobros y pagos del periodo.
* Introduce el **importe contado** físicamente (o el saldo del banco) y revisa la **diferencia** que calcula el sistema.
* Guarda para confirmar el cierre.
El detalle, en [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja).
Si cobras en efectivo **y** con tarjeta en el mismo punto, haz **dos cierres separados**: uno por la caja (el efectivo, que cuadras contando el dinero) y otro por la cuenta bancaria (la tarjeta y los links de pago).
***
## Hostelería: modo táctil y kiosko [#hostelería-modo-táctil-y-kiosko]
Para una barra, un restaurante o cualquier mostrador con tablet, dos ajustes cambian la operativa diaria.
| Ajuste | Qué te da | Dónde |
| --------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **Modo táctil** | Botones grandes y catálogo por categorías con imagen, para vender a golpe de dedo sin teclear. | Se activa en el tipo de venta del TPV. Ver [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv). |
| **Modo kiosko** | El equipo arranca directo en Dinaup a pantalla completa, sin escritorio ni distracciones, e imprime los tickets solo. | Acceso directo del navegador. Ver [Modo kiosko](/docs/rtg/tpv/modo-kiosko). |
El modo kiosko es para un ordenador **dedicado** en exclusiva al punto de venta. No lo configures en un equipo que también uses para correo, pedidos o contabilidad.
Para llevar comandas, preparar pedidos en cocina o repartir a domicilio, completa la configuración con [Pedidos y delivery](/docs/rtg/tpv/procesos/pedidos-y-delivery).
***
## Comprueba que todo encaja [#comprueba-que-todo-encaja]
Antes de dar el TPV por listo para producción, repasa que cada pieza está en su sitio:
* [ ] El **tipo de venta** del TPV existe, está marcado como predeterminado y (si aplica) con modo táctil activo.
* [ ] Tienes **productos con precio** y, en táctil, **categorías con imagen**.
* [ ] La **caja** está dada de alta y **vinculada** a este navegador.
* [ ] La **cuenta bancaria** está asociada a la caja para el cobro con tarjeta.
* [ ] Has hecho una **venta de prueba** y la has cobrado en efectivo y en tarjeta.
* [ ] El **cierre** recalcula y cuadra (recuerda los dos cierres si usas caja y banco).
El efectivo que cuadras en el cierre se vuelca a tu [caja de tesorería](/docs/rtg/pymes/tesoreria/cajas), así que no lo registras dos veces.
***
→ [Introducción al TPV](/docs/rtg/tpv)
→ [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv)
→ [Configurar y vincular una caja](/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja)
→ [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida)
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
→ [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
→ [Modo kiosko](/docs/rtg/tpv/modo-kiosko)
# Configurar correctamente las licencias (/docs/guias/configurar-licencias)
Tu licencia de Dinaup define tres cosas: **qué módulos** tiene tu empresa, **cuántos usuarios** entran y **qué puede hacer cada uno**. Aquí los configuras en orden, desde activar un módulo hasta repartir permisos.
## Antes de empezar [#antes-de-empezar]
* Una cuenta de Dinaup con el permiso **Gestionar Suscripción Dinaup**. Sin él no entras a Cuenta y facturación.
* Acceso al panel de administración en [dinaup.com](https://dinaup.com).
***
## Tipos de licencia [#tipos-de-licencia]
Combinas **módulos Ready To Go** (soluciones listas para usar) con extras como usuarios adicionales, claves API o desarrollo a medida con Flex.
| Tipo | Qué es | Para quién |
| ----------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| **Ready To Go Pymes** | Facturación, contabilidad, tesorería e inventario. Incluye **TPV** sin coste adicional. | La mayoría de empresas que facturan y gestionan stock. |
| **Ready To Go CRM** | Gestión comercial, oportunidades y seguimiento de clientes. | Equipos de ventas. |
| **Ready To Go RRHH** | Control horario, fichajes y vacaciones. | Gestión de personal. |
| **Ready To Go Proyectos** | Gestión de tareas y proyectos. | Equipos que organizan trabajo por proyectos. |
| **Dinaup Flex** | Licencia base para diseñar tu propio sistema a medida (secciones, informes, documentos, scripts). | Procesos únicos que los módulos estándar no cubren. |
| **Licencia de desarrollador** | Habilita las herramientas de desarrollo y personalización avanzada sobre Flex. | Personal técnico cualificado. |
| **Usuarios adicionales** | Amplía el número de personas que pueden entrar más allá de los incluidos en tu licencia. | Cuando tu equipo crece. |
| **Claves API** | Tokens para que sistemas externos accedan a tus datos vía API REST. | Integraciones y automatizaciones. |
Cada módulo Ready To Go incluye un número de usuarios acumulables. Los precios, los usuarios incluidos y los costes de cada extra los tienes en **[Precios](/docs/cuenta/precios)**.
***
## Configura tu licencia en seis pasos [#configura-tu-licencia-en-seis-pasos]
Sigue los pasos en orden: primero activas lo que la empresa puede usar, luego das de alta a las personas, y por último decides qué ve cada una. Cada paso enlaza a su página para que profundices donde lo necesites.
### Entra al panel de administración [#entra-al-panel-de-administración]
Accede al panel de administración en [dinaup.com](https://dinaup.com) y ve a **Cuenta y facturación**. Desde ahí gestionas tu plan, los módulos activos y los métodos de pago.
👉 [Ver: Cuenta y facturación](/docs/cuenta/cuenta-y-facturacion)
### Activa los módulos que necesites [#activa-los-módulos-que-necesites]
En la sección de suscripción, activa o desactiva los módulos Ready To Go (Pymes, CRM, RRHH, Proyectos). **TPV viene incluido con Pymes**.
El cambio se refleja **al instante** en Play Dinaup para todos los usuarios de tu empresa. Aún no verán el módulo hasta que tengan el permiso, que configuras en el paso 4.
👉 [Ver: Módulos activos](/docs/cuenta/cuenta-y-facturacion)
### Da de alta a tus usuarios [#da-de-alta-a-tus-usuarios]
Crea las cuentas de tu equipo y asígnales el **tipo de usuario** según el nivel de acceso que necesitan: Administrador, Estándar, Básico o Lectura.
Cada usuario activo cuenta para la facturación. Si superas los incluidos en tu licencia, se añaden como usuarios adicionales.
👉 [Ver: Gestión de usuarios](/docs/cuenta/gestion-de-usuarios)
### Asigna permisos por módulo [#asigna-permisos-por-módulo]
Aquí decides **qué ve cada persona**. Para que un usuario entre a un módulo, dale el permiso correspondiente (RTG Pymes, RTG CRM, RTG RRHH, etc.). Sin el permiso, el módulo no le aparece aunque esté activo en la empresa.
Para afinar más (qué secciones ve y qué puede hacer dentro de cada una) configúralo con roles.
Si a alguien "no le aparece" un módulo que debería ver, casi siempre falta el permiso de este paso, no la licencia. Empieza por aquí.
👉 [Ver: Gestión de usuarios](/docs/cuenta/gestion-de-usuarios) · [Permisos y roles](/docs/cuenta/permisos-y-roles)
### Crea claves API si tienes integraciones [#crea-claves-api-si-tienes-integraciones]
¿Conectas Dinaup con otra herramienta (n8n, Make, Zapier, tu propio backend)? Genera una clave API. Cada clave se asocia a un usuario y **hereda sus permisos**, así que crea un usuario específico para la integración con los permisos mínimos.
👉 [Ver: Claves API](/docs/cuenta/claves-api)
### (Avanzado) Flex y canal del Terminal [#avanzado-flex-y-canal-del-terminal]
Si tu proceso es único y los módulos estándar no llegan, activa **Dinaup Flex** para diseñar tu propio sistema. Para usar las herramientas de desarrollo, necesitas además la **licencia de desarrollador** y el permiso correspondiente.
A nivel técnico, la funcionalidad de tu licencia llega empaquetada en módulos que avanzan por canales (desarrollo, beta, producción) gestionados desde el Terminal.
👉 [Ver: Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal) · [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales)
***
## Preguntas frecuentes [#preguntas-frecuentes]
Sí. Flex es una licencia base independiente: puedes diseñar tu sistema a medida sin partir de Pymes, CRM, RRHH ni Proyectos. También puedes combinar Flex con un módulo Ready To Go si quieres aprovechar lo estándar y personalizar el resto. Consulta las tarifas en [Precios](/docs/cuenta/precios).
Cada módulo Ready To Go incluye un número de usuarios acumulables. Cuando superas ese número, los nuevos se añaden como **usuarios adicionales** y se reflejan en la facturación. Das de alta a la persona desde [Gestión de usuarios](/docs/cuenta/gestion-de-usuarios) y el cómputo se actualiza solo.
No. Desactivar un módulo **deja de mostrarlo** a los usuarios y deja de facturarlo, pero tus datos siguen guardados. Si vuelves a activarlo más adelante, los recuperas tal y como estaban.
Solo los usuarios con el permiso **Gestionar Suscripción Dinaup**. Ese permiso da acceso a [Cuenta y facturación](/docs/cuenta/cuenta-y-facturacion): ver costes, cambiar el plan, gestionar métodos de pago y dar de alta o baja módulos y usuarios. Asígnalo solo a quien deba administrar la cuenta.
***
→ [Cuenta y facturación](/docs/cuenta/cuenta-y-facturacion) · [Gestión de usuarios](/docs/cuenta/gestion-de-usuarios) · [Permisos y roles](/docs/cuenta/permisos-y-roles) · [Claves API](/docs/cuenta/claves-api) · [Precios](/docs/cuenta/precios)
# Contabilidad (/docs/guias/contabilidad)
La contabilidad de Dinaup trabaja sobre tus facturas, cobros, pagos y nóminas: montas el **cuadro de cuentas** una vez y la **contabilidad automática** convierte esas operaciones en asientos. Lo que no encaje, lo registras a mano en un editor que te avisa si el asiento descuadra.
Todo vive en **Pymes → Contabilidad**, con cuatro entradas: **Asientos**, **Cuentas**, **Inmovilizados** y **Contabilidad Automática**.
## Antes de empezar [#antes-de-empezar]
* El menú **Contabilidad** solo aparece si tu licencia incluye la app de **Pymes** y tu usuario tiene permiso sobre los asientos contables.
* La primera vez que entras en **Asientos**, Dinaup te pide configurar la estructura de cuentas antes de dejarte registrar nada.
### Configura los dígitos de cuenta [#configura-los-dígitos-de-cuenta]
En el aviso **Se requiere configurar la contabilidad**, rellena **Máx. dígitos cuentas oficiales** (cuántas cifras tiene la cuenta del plan general, normalmente 3) y **Dígitos cuentas auxiliares** (la longitud total de tus subcuentas, por ejemplo 8).
Los dígitos de cuentas oficiales deben ser **menores** que los de las subcuentas: las oficiales son el grupo común (`430`) y las auxiliares la subcuenta concreta del cliente (`43000001`).
Guarda. A partir de ahí ya puedes crear cuentas y asientos.
## Monta el cuadro de cuentas [#monta-el-cuadro-de-cuentas]
En **Pymes → Contabilidad → Cuentas** tienes tu cuadro completo, con un contador por grupo (Clientes 43x, Proveedores 400, Acreedores 410, Bancos 57x, Gastos 6xx, Ingresos 7xx) y filtros rápidos por grupo del 1 al 7. Buscas por código o por título, y el listado se pagina.
Tienes tres caminos para llenarlo, según prefieras partir de cero, de un plan oficial o de un Excel que ya tengas:
Crea una cuenta a mano: le pones código y título.
Trae cuentas del plan general contable (PGC) marcándolas de un árbol.
Sube un Excel con tus cuentas y las da de alta en bloque.
### Importar el plan general (cuentas oficiales) [#importar-el-plan-general-cuentas-oficiales]
Pulsa **Importar oficiales**. Se abre **Cuentas Oficiales** con el plan agrupado por grupo (1 a 7) y un buscador arriba.
Marca las cuentas que quieras. Las que ya existen aparecen marcadas y bloqueadas, y al elegir una subcuenta se seleccionan solas sus cuentas padre para no dejar huecos en el árbol. El botón **Todo** selecciona o limpia de golpe.
Pulsa **Aceptar**. Dinaup da de alta solo las cuentas nuevas que has marcado.
Desde **Vista report** abres el cuadro de cuentas como informe estándar de Dinaup, para filtrar, ordenar y exportar la lista con las herramientas de cualquier listado.
## Registra un asiento a mano [#registra-un-asiento-a-mano]
En **Pymes → Contabilidad → Asientos** tienes dos pestañas: **Asientos** (la lista de todo lo registrado, con buscador y filtros) y **Libro Diario** (el diario del ejercicio, que necesita un ejercicio contable activo para mostrarse).
Para crear uno nuevo, pulsa **Nuevo** y trabaja sobre el editor de asiento:
En **Datos del asiento** pon la **Fecha**, elige el **Ejercicio** y, si quieres, un **Concepto**. El **Nº de asiento** se genera al guardar.
En **Apuntes**, añade líneas con **Agregar** (o la tecla **F2**). En cada línea eliges la **cuenta**, un concepto y el importe en **Debe** o en **Haber**: al rellenar uno, el otro se bloquea para esa línea.
Mira el pie: **Total Debe**, **Total Haber** y **Descuadre**. Mientras no coincidan, el asiento sale marcado como **Descuadrado**; cuando cuadran, pasa a **Cuadrado**.
Pulsa **Aceptar** para guardarlo. Con **Ver ficha** abres el registro completo del asiento si necesitas todos sus campos.
El botón **Pegar lote** pega varias líneas desde texto con el formato `código debe haber concepto` (separadas por tabulador o espacios; el concepto es opcional). Antes de añadirlas, Dinaup muestra una previsualización con cuántas líneas están listas, cuáles tienen error y si el conjunto cuadra.
El editor de asiento lleva **Yudo** embebido: pídele en lenguaje natural que añada apuntes, ajuste un importe o cuadre el asiento, y lo hace sobre la misma pantalla. Más sobre el asistente en [Yudo](/docs/guias/yudo).
## Deja que Dinaup contabilice solo [#deja-que-dinaup-contabilice-solo]
**Pymes → Contabilidad → Contabilidad Automática** convierte tus operaciones del día a día en cuentas y asientos sin teclearlos. Va en dos pasos.
### Paso 1: crear las cuentas que faltan [#paso-1-crear-las-cuentas-que-faltan]
El primer paso revisa tus datos y detecta lo que aún no tiene cuenta contable asignada, agrupado por área:
| Área | Qué crea | Grupo |
| -------- | ------------------------------------------------------------------------ | --------------------- |
| Venta | Clientes, categorías de venta, IVA repercutido, retenciones practicadas | 430 / 700 / 477 / 475 |
| Compra | Proveedores, categorías de compra, IVA soportado, retenciones soportadas | 400 / 600 / 472 / 475 |
| Finanzas | Cuentas bancarias y cajas | 572 / 570 |
| RRHH | Sueldos y salarios, adelantos y pagos pendientes de nómina | 640 / 460 / 465 |
Cada fila te dice cuántos elementos están sin cuenta. Pulsas sobre una con datos pendientes y Dinaup genera las subcuentas que faltan.
### Paso 2: generar los asientos [#paso-2-generar-los-asientos]
Elige el **periodo** que quieras contabilizar con el selector de arriba.
Recorre las pestañas **Ventas**, **Compras**, **Cobros**, **Pagos** y **Nóminas**. Cada una lista solo las operaciones de ese periodo que **aún no tienen asiento**.
Marca las casillas de las operaciones que quieras contabilizar. El botón **Procesar** lleva un contador con cuántas tienes seleccionadas.
Pulsa **Procesar** y Dinaup crea los asientos en bloque, dejando cada operación enlazada a su asiento.
Los asientos automáticos guardan la referencia a la venta, compra, cobro, pago o nómina de la que nacieron. Por eso una operación ya contabilizada deja de aparecer como pendiente: no se duplica.
Si arrancas con operaciones atrasadas, el asistente de [Ponerse al día](/docs/rtg/pymes/ponerse-al-dia) detecta cuántas ventas, compras, cobros, pagos y nóminas te quedan **sin asiento** y te lleva directo a contabilizarlas.
## Inmovilizados [#inmovilizados]
En **Pymes → Contabilidad → Inmovilizados** llevas los bienes de la empresa (maquinaria, vehículos, equipos informáticos…) con su coste, vida útil y amortización. Al registrar la amortización, Dinaup genera el asiento contra las cuentas de dotación y amortización acumulada que hayas configurado en el tipo de inmovilizado.
El alta, la clasificación por tipos y estados, el cálculo de la amortización y la baja, en [Inmovilizados](/docs/rtg/pymes/contabilidad/inmovilizados).
## Exporta los libros para tu asesoría [#exporta-los-libros-para-tu-asesoría]
Para enviar la contabilidad fuera, ve a **Pymes → Más → Exportación**. Desde ahí descargas en Excel:
El libro de un tipo de factura de venta, con sus totales.
El libro de un tipo de factura de compra.
El movimiento de una cuenta bancaria.
Elige en el desplegable el **tipo de factura** (o la **cuenta bancaria**) que quieres exportar.
Indica el **año** y el **periodo**: anual, por trimestre (T1 a T4) o por mes concreto.
Pulsa **Descargar**. Se genera el Excel y se muestra en pantalla; en los libros de facturas verás además los totales de Base Imponible, IVA, RE, Retenciones y Total.
Con **Enviar por email** mandas ese mismo archivo adjunto sin salir de Dinaup.
Para el detalle campo a campo del módulo (incluidos los atajos para crear subcuentas y las tres vistas del asiento) tienes la referencia en [Contabilidad](/docs/rtg/pymes/contabilidad), y la organización del año fiscal en [Ejercicios](/docs/rtg/pymes/ejercicios).
# Control de gastos y compras (/docs/guias/control-gastos)
No tecleas facturas: las sueltas. Subes un PDF o reenvías el email del proveedor, la IA lee el documento, agrupa todo por proveedor y deja una cola lista para revisar y contabilizar en lote.
Dinaup separa dos cosas dentro de **Compras & Gastos**, en el menú lateral de **Pymes**:
Las facturas de tus proveedores con su IVA, retenciones y libros de registro. Es la entrada fiscal "completa".
Gastos sin factura formal (tickets, pequeños desembolsos) que también quieres registrar y categorizar.
Ambas pantallas funcionan igual; cambia solo el rigor fiscal que esperan.
## Antes de empezar [#antes-de-empezar]
* Cuenta con acceso a **Pymes** y al grupo **Compras & Gastos**.
* Las pestañas **Pagos** y **Archivos** no aparecen en el plan Lite. Si no las ves, es por tu plan.
## Las dos pantallas y sus pestañas [#las-dos-pantallas-y-sus-pestañas]
Tanto **Facturas Recibidas** como **Otros Gastos** se organizan en pestañas:
| Pestaña | Para qué |
| ------------------------------- | -------------------------------------------------------------------------- |
| **Facturas Recibidas / Gastos** | El listado de lo ya contabilizado, con su buscador y filtros. |
| **Conceptos** | El desglose línea a línea de lo comprado (qué conceptos, no qué facturas). |
| **Pagos** | Los pagos asociados a esas compras. |
| **Archivos** | La cola de digitalización: aquí subes los PDF y la IA los procesa. |
| **Notas** | Apuntes del equipo sobre esta sección. |
## Del PDF a contabilizado [#del-pdf-a-contabilizado]
Todo el flujo vive en la pestaña **Archivos**.
### Sube las facturas [#sube-las-facturas]
En la pestaña **Archivos**, pulsa el botón verde **+** y suelta tus archivos. Acepta **PDF, PNG, JPG y JPEG**, hasta **20 MB** por archivo. Puedes subir muchos de golpe (la cola admite cientos).
### Analiza con IA [#analiza-con-ia]
Cuando hay facturas sin leer, aparece el botón **Analizar N**. Al pulsarlo eliges el nivel de IA y arranca el análisis: una barra de progreso te va diciendo *X de Y*. La IA extrae proveedor, importes, impuestos y conceptos de cada documento.
### Revisa los grupos por proveedor [#revisa-los-grupos-por-proveedor]
La cola se reordena sola **agrupada por proveedor**. Cada grupo se marca según su estado: proveedor listo, proveedor con datos fiscales incompletos, o proveedor nuevo que aún no existe en tu base.
### Contabiliza en lote [#contabiliza-en-lote]
Cuando hay facturas listas, pulsa **Revisar en lote (N)**. Se abre el asistente que te pasa los documentos **uno a uno** para confirmar y guardar.
## Recibir facturas por email [#recibir-facturas-por-email]
Cada empresa tiene una **dirección de email propia** para facturas. Reenvías ahí los correos de tus proveedores (o configuras un reenvío automático desde tu buzón de facturación) y Dinaup mete los adjuntos en la cola.
En la pestaña **Archivos**, copia la dirección de email que aparece en el banner (botón de copiar al lado).
Configura en tu correo un **reenvío** de las facturas hacia esa dirección, o reenvía los correos a mano.
Cuando haya correos esperando, el banner muestra **N en buzón**. Pulsa **importar** y los adjuntos entran en la cola, listos para analizar.
La dirección de email no es la misma en las dos pantallas: cada una recibe en su propio buzón. Usa la que toque según dónde quieras que aterricen esas facturas.
## El asistente de revisión en lote [#el-asistente-de-revisión-en-lote]
Abre las facturas listas una tras otra; en cada una confirmas los datos y avanzas. Arriba ves el contador (*3 / 50*) y el progreso: procesadas, saltadas, rechazadas y pendientes.
En cada documento puedes:
* **Guardar y siguiente**: contabiliza la factura y salta a la próxima.
* **Saltar**: la dejas pendiente y pasas a la siguiente sin guardar.
* **Rechazar**: marcas el documento como descartado y avanzas.
Con el teclado vas más rápido:
| Atajo | Acción |
| ---------------- | ------------------- |
| **Ctrl + Enter** | Guardar y siguiente |
| **Alt + →** | Saltar / siguiente |
| **Alt + ←** | Anterior |
Desde la cabecera de cada grupo de proveedor puedes lanzar la revisión en lote **solo de ese proveedor**, sin revisar todo de golpe.
## Proveedores: crear, asignar y completar [#proveedores-crear-asignar-y-completar]
La IA reconoce al proveedor por su NIF y nombre, pero a veces ese proveedor todavía no existe en tu base o le faltan datos fiscales. Lo resuelves desde la **cabecera del grupo**, sin salir de la cola:
| Acción | Qué hace |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **Crear** | Da de alta el proveedor nuevo con los datos que la IA ya leyó de la factura (NIF, dirección, etc.). No reescribes nada. |
| **Existente** | Si el proveedor ya está pero la IA no lo enlazó, lo buscas y lo asignas a todo el grupo. |
| **Completar / Configurar** | Abre la ficha del proveedor para rellenar los datos fiscales que falten cuando el grupo aparece como incompleto. |
Un proveedor marcado como **incompleto** no tiene datos fiscales asignados. Complétalo antes de contabilizar para que el IVA, las retenciones y el libro de registro salgan correctos.
Los proveedores también viven en su propia pantalla: menú **Pymes → Entidades → Proveedores**.
## Dar de alta una compra a mano [#dar-de-alta-una-compra-a-mano]
No todo entra por PDF. Para registrar una compra directamente, usa los botones **+** de la barra superior del listado: hay **uno por cada tipo de compra** que tengas configurado (nacional, intracomunitaria, importación…). Pulsas el del tipo que corresponde y se abre la ventana de la factura para rellenarla.
El tipo de compra define cómo se trata fiscalmente (impuestos, libro de registro, inversión del sujeto pasivo…). Si te faltan tipos, los configuras en la sección de configuración fiscal. Tienes el detalle en [Categorías de compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra).
## Que la IA ponga a punto tu configuración [#que-la-ia-ponga-a-punto-tu-configuración]
Cuando empiezas, es normal que falten impuestos, retenciones, libros o categorías para clasificar bien lo que compras. Dinaup trae varios asistentes de IA que **proponen** lo que falta:
Desde la pestaña Archivos, la IA revisa tus facturas pendientes y detecta huecos en tu configuración fiscal (impuestos, retenciones, libros, categorías), ordenados por prioridad.
Propone un juego de categorías de gasto a partir de lo que de verdad compras.
Propone reglas para clasificar automáticamente movimientos y conceptos.
Repasa los proveedores y avisa de los que tienen datos fiscales con errores.
Todas estas pantallas marcan sus propuestas como **"Revisar antes de aplicar"**. Nada se crea hasta que lo apruebas: léelo y quédate solo con lo que tenga sentido para tu negocio.
## Re-analizar cuando algo no cuadró [#re-analizar-cuando-algo-no-cuadró]
Si la IA leyó mal una factura o cambiaste la configuración del proveedor después, no hace falta borrar nada:
* **Re-analizar** un grupo concreto desde su cabecera, para volver a leer solo esas facturas.
* **Re-analizar todo** desde la barra de estadísticas, para repasar la cola entera.
En ambos casos se vuelve a pasar la IA con la configuración actual, así que las correcciones que hayas hecho se reflejan.
Para la referencia completa (categorías, tipos de compra, libros de registro, impuestos) tienes [Compras](/docs/rtg/pymes/facturacion/compras) y, para el conjunto de la app, [Pymes](/docs/rtg/pymes).
# Cuenta y facturación (/docs/guias/cuenta-facturacion)
Tu cuenta tiene una zona privada con menú propio: Mi perfil, Mi empresa, Usuarios, Suscripción y Facturas. Desde ahí controlas el acceso, el plan y la facturación.
## Antes de empezar [#antes-de-empezar]
La administración (usuarios, suscripción, facturas) la maneja el administrador. Un empleado normal solo ve y edita su propio perfil.
## Usuarios y permisos [#usuarios-y-permisos]
Decides qué ve y qué puede tocar cada persona:
* **Nivel de acceso:** Bloqueado, Lectura, Básico, Estándar o Administrador.
* **App por app:** a qué programas entra cada uno (TPV, Pymes, RRHH, CRM, To-Do…).
* **Seguridad:** cambiar la contraseña y activar el doble factor (un código extra al entrar).
Para perfiles concretos: Servicios de IA (usar Yudo), Desarrollador, Soporte y Live (pruebas).
## Altas y bajas [#altas-y-bajas]
| Acción | Cómo |
| -------------------------- | -------------------------------------------------------------------------------- |
| Dar de alta | Pulsa «Invitar por email». La persona se registra, pide unirse y tú lo apruebas. |
| Aceptar solicitudes | Quien pide entrar aparece en una lista para aceptar o rechazar. |
| Dar de baja a una persona | La bloqueas o la quitas cuando quieras. |
| Darte de baja de la cuenta | Cancelas la suscripción tú mismo, sin llamar a nadie. |
## Suscripción y facturación [#suscripción-y-facturación]
Ves tu plan y lo gestionas tú:
* Prueba gratis de 14 días; cambias de plan o arrancas la suscripción cuando quieras.
* Resumen de consumo: usuarios de pago, espacio, archivos, APIs y almacenes.
* Pagos por Stripe (la pasarela de pago): un botón te lleva a su portal para tarjetas y recibos.
* En **Facturas** tienes tus facturas, recibos y métodos de pago.
En «Mi empresa» van los datos fiscales, el representante legal y la facturación. Si falta algo, Dinaup te avisa.
Si un partner factura por ti, verás una versión sin los botones de pago: de eso se encarga él. Tu cuenta sigue siendo tuya (ver [Partners](/docs/cuenta/partners)).
# DinaZen (/docs/guias/dinazen)
Coges piezas de DinaZen y las encajas en tu pantalla. Hay unas **80 piezas** (tarjetas, gráficos, desplegables, diálogos, ventanas…) en una docena de familias, construidas sobre la librería Radzen y pensadas para las apps de Dinaup.
El componente es tonto, los datos mandan: le pasas un dato (o el id de algo que ya existe en Dinaup) y la pieza decide cómo pintarse. A esas las llamamos **componentes dinámicos**.
## Componentes dinámicos: una línea, la cosa entera [#componentes-dinámicos-una-línea-la-cosa-entera]
Con una sola línea aparece un informe, un formulario o una estadística, generados a partir de los datos. Tres ejemplos en marcha.
### 1 · Informe `DnzReportView` [#1--informe-dnzreportview]
Le das la conexión y el **id del informe** y pinta la tabla completa: columnas, buscador, filtros y páginas, leídos de la definición del informe. Cambias el id y sale otro informe distinto.
### 2 · Formulario `DnzFormView` [#2--formulario-dnzformview]
Le das la conexión y la **sección** y monta el formulario entero (cada campo con su tipo y su validación, y el botón de guardar). Con `DatoId=""` crea uno nuevo; con un id, edita esa ficha.
### 3 · Estadística `DnzDynamicStat` [#3--estadística-dnzdynamicstat]
Le das un dato y **él elige cómo mostrarlo**: un número suelto → tarjeta KPI; varios → fila de mini-KPIs; una lista → gráfico. No decides el formato, lo decide la forma de los datos.
Cualquiera de los tres puede salir flotando en una ventana de escritorio (arrastrable, minimizable) con una línea: `DnzReportView.OpenAsWindow(WindowManager, client, reportId)`. Las crea y coloca el `DnzWindowManager`.
## Selectores: la regla de oro [#selectores-la-regla-de-oro]
Los desplegables son donde más gente mete la pata. Cinco parecen el mismo, pero la diferencia que importa no es cómo se ven: es **de dónde salen los datos**. Antes de teclear, una pregunta: **¿este conjunto cabe siempre en memoria y no crece sin tope?**
Estados, monedas, almacenes, tipos propios, un enum. Son
**decenas**
y no se disparan con los años. Lo cargas entero en
`Data`
y filtras en memoria:
`RadzenDropDown`
,
`DnzEnumDropDown`
,
`DnzDropDown`
o
`DnzDataGridDropDown`
según cómo necesites
*verlo*
.
Clientes, proveedores, productos, lotes, empleados. Hoy son 200; dentro de tres años, 8.000.
**No tienen techo real.**
Usa
`DnzRowSelector`
: consulta al servidor paginado, nunca cargas la lista entera. Es el único que deja
**seleccionar cualquier registro**
.
Tratar datos que **crecen sin tope** (clientes + proveedores) como si fueran acotados: cargarlos con un `Limit 3000` "por si acaso" en un `RadzenDropDown`. Resultado: el cliente número 3.001 **no aparece y no se puede seleccionar**, sin ningún aviso. Parece que funciona, hasta que a alguien le falta una ficha.
## Árbol de decisión [#árbol-de-decisión]
Tres preguntas y aciertas siempre. Empieza arriba:
## Los cinco selectores comparados [#los-cinco-selectores-comparados]
| Componente | Datos | Búsqueda | Bindeas… | Pinta | Cuándo |
| --------------------- | -------- | ----------------------- | ------------------------ | ------------------------ | ----------------------------------------- |
| `RadzenDropDown` | memoria | cliente | un valor (Guid) | 1 texto | lista corta y estable, solo texto |
| `DnzEnumDropDown` | enum | cliente | un enum | 1 texto | cualquier `enum` (con DisplayName) |
| `DnzDropDown` | memoria | cliente | la fila (objeto) | 1 texto + acciones | lista en memoria con +crear / abrir ficha |
| `DnzDataGridDropDown` | memoria | cliente | la fila (objeto) | N columnas, color, icono | lista en memoria que hay que *ver* rica |
| `DnzRowSelector` | servidor | **servidor** (debounce) | la fila o un `DefaultID` | resultado del informe | **dataset ilimitado**: cualquier registro |
"Cliente" = filtra en el navegador sobre lo que ya cargaste (instantáneo, pero solo encuentra lo cargado). "Servidor" = cada búsqueda viaja a la API (encuentra TODO, cuesta un viaje de red).
## Selectores uno a uno: pros, contras y código [#selectores-uno-a-uno-pros-contras-y-código]
### 1 · RadzenDropDown [#1--radzendropdown]
*memoria · base Radzen*
El de toda la vida. Le das una lista en `Data`, eliges qué propiedad es el texto y cuál el valor, y devuelve el valor (normalmente un `Guid`). Filtrado en cliente, opción de virtualizar el render.
| A favor | En contra |
| ------------------------------------------------------------ | -------------------------------------------------------------------- |
| El más simple y ligero; cero ceremonia. | Carga **toda** la `Data` en la RAM del circuito. |
| Bindea directo a un `Guid` / valor. | Si truncas la carga, lo truncado es **inseleccionable** y sin aviso. |
| `AllowVirtualization` aguanta miles de filas sin lag de DOM. | Una sola "columna": solo texto plano. |
```csharp
```
### 2 · DnzEnumDropDown\ [#2--dnzenumdropdowntenum]
*enum*
Un envoltorio sobre RadzenDropDown que se rellena solo a partir de `Enum.GetValues`. Respeta el `[Display(Name="…")]` de cada miembro, así que sale el texto bonito en vez del nombre técnico.
| A favor | En contra |
| ------------------------------------------------------------- | ------------------------------------------------------------ |
| Cero boilerplate para un enum: no construyes la lista a mano. | Solo sirve para enums. |
| Usa el `DisplayName` automáticamente. | Recalcula los items en cada render (irrelevante: son pocos). |
```csharp
```
### 3 · DnzDropDown\ [#3--dnzdropdownt]
*memoria · IDinaupRow*
Como el Radzen pero "Dinaup-aware": trabaja con filas `IDinaupRow`, muestra el `Label` y trae de serie los botones de **crear** (+), **quitar** (✕) y **abrir ficha** (↗). Bindea al objeto entero (`Selected`), no a un Guid.
| A favor | En contra |
| ----------------------------------------------------- | --------------------------------------------------- |
| Acciones integradas: crear al vuelo y abrir la ficha. | Sigue siendo en memoria: mismo techo que el Radzen. |
| Formato Dinaup sin configurar (usa `Label`). | Una columna; bindea a objeto (no Guid). |
```csharp
```
### 4 · DnzDataGridDropDown\ [#4--dnzdatagriddropdownt]
*memoria · rico*
El hermano vistoso. Misma fuente en memoria, pero el desplegable es una mini-tabla: **varias columnas**, badges de **color** (`ColorProperty` → `DnzBadgetAutoColor`) e **iconos** por fila. Para cuando el texto solo no basta para distinguir las opciones.
| A favor | En contra |
| --------------------------------------------------------------------- | ------------------------------------ |
| Lo más legible en memoria: columnas, color y estado en la misma fila. | En memoria igual que los anteriores. |
| Plantillas propias (`Columns`, `ValueTemplate`, `IconTemplate`). | Más markup; bindea a objeto. |
```csharp
```
### 5 · DnzRowSelector [#5--dnzrowselector]
*servidor · ilimitado*
El distinto de la familia. **No le pasas `Data`**: le pasas un `ReportId` y el `Client` de sesión. Abre un popup perezoso y consulta al servidor paginado (20 por tanda) con búsqueda *debounced*. Da igual que haya 50 o 5 millones de registros: encuentra cualquiera y no llena la RAM.
| A favor | En contra |
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **Sin techo**: selecciona cualquier registro de la sección. | Cada instancia pesa más en el DOM (form-field + popup). |
| No carga nada en memoria hasta que abres y buscas. | Con `DefaultID` hace 1 consulta por instancia para resolver el nombre (ver gotcha). |
| Filtros avanzados (`AdvancedFilter`), +crear, abrir ficha, requerido. | Cada búsqueda es un viaje de red (con debounce, pero lo es). |
```csharp
```
## Los detalles finos que cuestan caro [#los-detalles-finos-que-cuestan-caro]
### El gotcha del nombre que ahorra la query [#el-gotcha-del-nombre-que-ahorra-la-query]
En `DnzRowSelector` hay dos formas de decirle "ya hay algo seleccionado", y eligen entre **una consulta o ninguna**:
| Con `DefaultID` (un Guid) | Con `SelectedRow` precargado |
| ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| El componente solo tiene el ID, así que para pintar el nombre **llama al servidor** (`SelectByIdAsync → Report_GetAsync`) al inicializarse. | Si **ya tienes el nombre** a mano (p. ej. el movimiento bancario trae `mov.Entidad`), construyes la fila con Id + Label y se la pasas hecha. |
| **1 query por instancia.** En una lista de 50 filas = **50 viajes** al servidor solo para pintar lo que ya estaba asignado. | **0 queries** al pintar. El servidor solo se toca cuando el usuario *abre* el buscador de una fila concreta. |
Si el dato que vas a mostrar **ya viaja contigo en memoria**, nunca uses `DefaultID` en una lista: pásale el `SelectedRow` ya resuelto y te ahorras una consulta por fila. `DefaultID` solo cuando lo único que tienes es el ID suelto.
### Otros tres que muerden [#otros-tres-que-muerden]
`AllowVirtualization=true` en RadzenDropDown solo evita pintar 5.000 nodos en el DOM. Los 5.000 **objetos siguen en RAM** y el cap de carga sigue ahí. Arregla el lag visual, no el problema de memoria ni el de cobertura.
En Blazor Server, ese `Data` grande vive en el circuito de **cada** usuario conectado. 6.000 entidades × N sesiones = RAM que se multiplica. RowSelector no carga nada hasta que se busca.
Radzen/Enum bindean a un **valor** (`Guid`/enum vía `ValueProperty`). DnzDropDown / DataGridDropDown / RowSelector bindean al **objeto** (`T`/`IDinaupRow`). Migrar de uno a otro cambia el tipo del binding: el `Change=v => SetX(id, v)` pasa a `SelectedRowChanged`. No es solo cambiar la etiqueta.
## Checklist de selectores [#checklist-de-selectores]
1. **¿Es un enum?** → `DnzEnumDropDown`. Fin.
2. **¿El dato crece sin tope** (clientes, productos, lotes, empleados…)? → `DnzRowSelector`. Es el único que los abarca todos.
3. **¿Acotado y estable?** Entonces según cómo lo veas:
* solo texto → `RadzenDropDown`
* texto + crear / abrir ficha → `DnzDropDown`
* columnas / color / icono → `DnzDataGridDropDown`
4. Si usas RowSelector en una **lista** y ya tienes el nombre → `SelectedRow` precargado, nunca `DefaultID`.
## El resto del catálogo [#el-resto-del-catálogo]
Las familias que cubren el 90 % de una pantalla. Todas con la misma cara y comportamiento, los estilos vienen resueltos de serie:
Números, dinero, fechas, bytes o minutos con formato correcto: la familia
`DnzSpan*`
(DnzSpanMoney, DnzSpanDate…).
DnzCardTitle, DnzKpiCard, DnzKpiRow, DnzStatsDisplay y el dinámico DnzDynamicStat.
Etiquetas de estado con color automático, deltas (↑↓), países y avatares por iniciales.
Búsqueda, desplegables, subida de archivos, editor HTML, pasos (stepper) y el DnzFormView atado a tus datos.
Confirmar, elegir de una lista, histórico de cambios, recuperar contraseña… con el mismo layout siempre.
Los conectados a tus datos: DnzReportView, DnzRowSelector, DnzDynamicDocumentView y el gestor de ventanas.
Diagramas de Gantt y piezas de recursos humanos (cuadrantes, intervalos, líneas de tiempo).
Cargadores, skeletons de carga, resaltado de código, visor de documentos de Office y más.
Cada componente tiene su demo y su código en el catálogo de DinaZen. Para conectar tu propia app, mira la guía del [SDK .NET y API](/docs/guias/sdk-api).
# Modelar tu negocio con Flex (/docs/guias/excel)
Con **Dinaup Flex** modelas las tablas propias de tu sector sobre la base que ya traen las soluciones Ready To Go. Defines secciones, campos y relaciones, y el panel de gestión genera los formularios, listados y permisos solo.
## Antes de empezar [#antes-de-empezar]
* Una cuenta de Dinaup con **Flex** disponible en tu plan.
* Permisos de **administrador** para crear secciones y campos.
* Las soluciones **Ready To Go** que vayas a usar de base ya activas (facturación, contabilidad, tesorería, inventario).
Flex se construye encima de Ready To Go: no empiezas en blanco. Lo común de toda empresa ya está resuelto; tú añades lo específico de tu sector.
## Modelar una sección [#modelar-una-sección]
Una sección es una "tabla" de tu negocio: vehículos, fincas, expedientes, lo que necesites.
### Crea la sección [#crea-la-sección]
Desde el panel de gestión, añade una sección nueva y dale nombre.
### Añade los campos [#añade-los-campos]
Define las columnas: texto, número, fecha, relación con otra sección. Puedes poner **fórmulas automáticas**, **validaciones** y **KPIs calculados**.
### Relaciónala con otras secciones [#relaciónala-con-otras-secciones]
Enlaza una sección con otra para que un registro apunte a otro (por ejemplo, un expediente a su cliente).
Cada cambio de estructura aparece **solo** en el panel: formularios, listados y permisos, sin que nadie los programe.
## Qué tienes por debajo [#qué-tienes-por-debajo]
A diferencia de una hoja de cálculo, lo que modelas vive sobre una base de datos real:
| Lo que ganas | Qué significa |
| ------------------------- | ---------------------------------------------------------------- |
| Histórico y auditoría | Cada cambio queda registrado: quién, cuándo y qué modificó. |
| Control de usuarios | Permisos por sección y por rol: cada uno ve y toca solo lo suyo. |
| Base de datos real | PostgreSQL: integridad, rendimiento y millones de registros. |
| Backups e infraestructura | Copias replicadas en la nube. No mantienes servidores. |
## Conectarlo con el exterior [#conectarlo-con-el-exterior]
Lo que modelas no se queda aislado. Sin escribir código:
| Opción | Para qué |
| ---------------------- | ------------------------------------------------------------------ |
| **Webhooks** | Avisar a otra app en tiempo real cada vez que cambie un dato. |
| **n8n, Make o Zapier** | Enlazar Dinaup con miles de servicios. |
| **API REST** | Exponer cualquier informe o dato para leer y escribir desde fuera. |
Con perfil técnico puedes construir tu aplicación sobre Dinaup con el [SDK .NET y la API](/docs/guias/sdk-api) y el espacio de [Desarrollo](/docs/desarrollo).
## Si todavía no necesitas Flex [#si-todavía-no-necesitas-flex]
Si aún no necesitas modelar nada propio, empieza por los módulos estándar de [Ready to Go](/docs/rtg) y añade Flex el día que toque, sin migrar nada.
# Fichaje y control horario (/docs/guias/fichaje)
Dinaup separa tres capas que la mayoría de programas mezclan:
Lo que el empleado
*debería*
trabajar según su horario.
Lo que se le imputa como trabajado (lo que va a nómina).
El registro físico de entrada y salida.
**Inmutable**
: nunca se edita.
Si hay un error, corriges el **Realizado** (el turno reconocido), no el fichaje. El fichaje original queda intacto como prueba, y eso es lo que aguanta una inspección.
## Antes de empezar [#antes-de-empezar]
* Cuenta de **administrador** con acceso a Recursos Humanos.
* El empleado, dado de alta en **Recursos Humanos → Personas → Empleados**.
* Un **horario** y un **calendario de festivos** creados (los asignas en los pasos siguientes).
## Activa el control horario de un empleado [#activa-el-control-horario-de-un-empleado]
No hay un interruptor "activar fichaje": el control se enciende cuando el empleado tiene un **horario asignado**.
Marca al empleado como **Activo** en su ficha (**Recursos Humanos → Personas → Empleados**).
Asígnale un **horario** desde su perfil, con el botón **Cambiar horario**.
Comprueba que tiene un **calendario de festivos** asignado.
A partir de ahí, Dinaup genera cada noche los **turnos** del día para ese empleado a partir de su horario. No tienes que crearlos a mano.
## Cómo ficha tu equipo [#cómo-ficha-tu-equipo]
El empleado ficha desde donde le venga bien, sin instalar nada:
* **Web**: desde cualquier navegador.
* **App móvil** de Dinaup.
* **Tótem en recepción** (modo kiosko).
Y registra cuatro acciones a lo largo de la jornada:
| Acción | Para qué |
| --------------- | -------------------------------------- |
| **Entrada** | Empieza la jornada o el turno. |
| **Pausa** | Detiene el cómputo (descanso, comida). |
| **Reanudación** | Vuelve a contar tras la pausa. |
| **Salida** | Cierra la jornada o el turno. |
Fecha y hora exactas, dirección IP, navegador y dispositivo, y (si lo activas) geolocalización (desactivable por RGPD). Cada fichaje lleva una huella única y es inmutable: si algo está mal, ajustas el **Realizado** del día, nunca el fichaje.
## La Línea de Tiempo [#la-línea-de-tiempo]
En **Recursos Humanos → Línea de Tiempo** ves, día a día, la jornada de cada empleado con las capas superpuestas:
* 🔵 **Programado**: lo que tocaba trabajar.
* 🟢 **Realizado**: lo que se imputa como trabajado (lo rayado es trabajo fuera de lo planificado).
* 🟠 **Fichaje**: las entradas y salidas reales.
* ⚫ **Ausencia**: no asistencia, justificada o no.
Filtras por lo que te interese: ausencias (justificadas o sin justificar), fichado sin horario, tiempo extra, tiempo menor o **sin fichar salida**.
## Horarios y turnos [#horarios-y-turnos]
**Un horario** es la plantilla de la jornada; **un turno** es la instancia de un día concreto, que Dinaup crea solo.
| Acción | Dónde | Detalle |
| -------------------------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **Crear un horario** | Configuración → Horarios → Horarios | Defines sus tramos (hora de inicio, de fin, tipo). |
| **Asignarlo** | Perfil del empleado → Cambiar horario | Guarda **fechas de vigencia**: cambias el horario de alguien a mitad de su vida laboral sin perder el histórico. |
| **Ver los turnos del día** | Día a día → Turnos (Hoy / Ayer / Todos) | Estados *Programada*, *Presente*, *Ausencia* o *Cancelada*. |
| **Planificar** | Día a día → Planificador | Vista Gantt o Calendario. |
## Corregir un día [#corregir-un-día]
Cuando el Realizado no cuadra con la realidad (alguien olvidó fichar la salida, hizo horas fuera de turno…), lo arreglas sin tocar el fichaje:
Desde la **Línea de Tiempo**, haz clic en el día del empleado. Se abre **Edición de fichaje**.
Verás el **horario esperado** y el **horario realizado**. Ajusta el *Realizado* (puedes copiarlo del esperado o vaciarlo) y, si procede, añade una **ausencia**.
**Acepta**. El cambio queda registrado.
Cada corrección se anota en el **Log legal**: quién la hizo, cuándo y qué cambió (antes y después). El fichaje original sigue ahí como prueba forense.
En la edición del día puedes pedirle el cambio a **Yudo** en lenguaje natural ("registra una ausencia justificada el martes", "ajusta la salida a las 18:00") y lo aplica por ti.
## Vacaciones y ausencias [#vacaciones-y-ausencias]
Se gestionan por dos vías:
* **El empleado las pide** desde su app (**Solicitud de vacaciones**), con fechas y comentario; tú las **apruebas o rechazas**.
* **Tú las registras** desde **Edición de fichaje → Agregar ausencia**, eligiendo el motivo (vacaciones, baja, permiso…) y el rango de fechas.
Las ausencias aparecen en gris en la Línea de Tiempo, separando las justificadas de las que no.
## Exporta las horas [#exporta-las-horas]
En **Recursos Humanos → Rendimiento → Exportar** eliges un **rango de fechas** y descargas un **Excel** con las horas por empleado, desglosadas por tipo (ordinarias, extras, descansos) y con la comparativa programado vs. realizado.
Para el resto de Recursos Humanos (empleados, documentos, organización) tienes la referencia completa en [Recursos Humanos](/docs/rtg/recursos-humanos).
# Guía de inicio rápido (/docs/guias/guia-de-inicio-rapido)
Vas a entrar por primera vez, reconocer el escritorio, dejar tu perfil listo, montar la empresa con el asistente de arranque y abrir la puerta a tu equipo.
## Antes de empezar [#antes-de-empezar]
Necesitas dos cosas hechas antes del primer paso:
* **Una cuenta.** Si no la tienes, créala en → [Crear cuenta y unirte a tu empresa](/docs/cuenta/crear-cuenta).
* **Una empresa registrada.** Si vas a dar de alta una empresa nueva, registra primero la licencia en → [Registrar tu empresa](/docs/cuenta/registrar-empresa).
Si tienes una **invitación** de tu empresa, usa el enlace del email en vez de crear cuenta. Entras directo en la empresa existente con los permisos que te haya asignado el administrador.
Dinaup tiene **dos portales**. En [dinaup.com](https://dinaup.com) gestionas la cuenta (usuarios, suscripción, claves API). En [play.dinaup.com](https://play.dinaup.com) trabajas cada día. Esta guía vive sobre todo en Play.
***
## 1. Entrar por primera vez [#1-entrar-por-primera-vez]
### Accede a Play Dinaup [#accede-a-play-dinaup]
Abre [play.dinaup.com](https://play.dinaup.com) en tu navegador (Chrome, Edge o Firefox). No hay nada que instalar: Dinaup funciona desde el navegador, también en tablet y móvil.
### Inicia sesión [#inicia-sesión]
Introduce tu **email y contraseña**, o entra con tu cuenta de **Google** si registraste así tu acceso.
### Configura el doble factor (si te lo pide) [#configura-el-doble-factor-si-te-lo-pide]
Si tu empresa exige verificación en dos pasos, Dinaup te guía para activarla. Recibes el código por **SMS** o lo generas con una **app autenticadora**. Desde ahí, cada inicio de sesión pide ese segundo código además de la contraseña. Luego lo gestionas desde tu perfil.
### Elige tu empresa [#elige-tu-empresa]
Si perteneces a **varias empresas**, Dinaup te muestra un selector para elegir con cuál trabajar. Con una sola, este paso se salta y entras directo al escritorio.
Con **varias empresas**, cambias de una a otra en caliente desde la barra superior, sin volver a iniciar sesión. Dinaup recuerda en cuál estabas la próxima vez que entres.
***
## 2. Reconoce el escritorio [#2-reconoce-el-escritorio]
Al entrar llegas al **escritorio**: tu punto de partida cada día. Tiene cuatro zonas.
| Zona | Para qué sirve |
| -------------------- | ------------------------------------------------------------------------------------------------- |
| **Barra superior** | Buscador global, notificaciones, tu perfil, ayuda y cambio de empresa. Siempre visible. |
| **Lanzador de apps** | El acceso a cada módulo contratado: Pymes, CRM, TPV, RRHH, Proyectos, IA y más. |
| **Dashboard** | La zona central, con resúmenes e indicadores que cada app aporta. Tu foto del estado del negocio. |
| **Menú lateral** | Dentro de una app, lista las secciones de esa app. Cambia según dónde estés. |
### La barra superior [#la-barra-superior]
Tu centro de control, no desaparece estés donde estés:
* **Buscador global**: escribe lo que buscas (un cliente, una factura, una sección) y Dinaup te lleva directo. La forma más rápida de moverse.
* **Notificaciones**: avisos de lo que pasa en tu empresa.
* **Perfil**: tu foto y el acceso a tus preferencias y al cierre de sesión.
* **Ayuda**: abre el canal de soporte cuando te atascas.
* **Empresa activa**: si tienes varias, desde aquí cambias entre ellas.
### El lanzador de apps [#el-lanzador-de-apps]
Desde el lanzador abres cada módulo de tu suscripción. Cada app tiene su icono y su propio menú lateral una vez dentro.
| App | Para qué sirve |
| ------------- | --------------------------------------------------------- |
| **Pymes** | Facturación, contabilidad, tesorería e inventario. |
| **CRM** | Gestión comercial: oportunidades, seguimientos, clientes. |
| **TPV** | Punto de venta táctil para cobros rápidos. |
| **RRHH** | Fichajes, horarios, vacaciones y nóminas. |
| **Proyectos** | Tareas, tableros Kanban y seguimiento del trabajo. |
Solo verás las apps de los módulos que tu empresa tenga contratados y a los que tu usuario tenga acceso. → [Ready To Go](/docs/rtg/que-es-dinaup)
***
## 3. Mi perfil [#3-mi-perfil]
Antes de trabajar, deja tu perfil listo. Lo abres desde tu **foto en la barra superior**. Desde ahí ajustas:
* **Foto y nombre visible**: cómo te ven tus compañeros.
* **Idioma**: cambia sin reiniciar nada.
* **Preferencias de notificación**: qué avisos quieres recibir y por dónde.
* **Doble factor de autenticación**: actívalo o gestiónalo para proteger tu acceso.
**Pon tu foto.** Aparece en comentarios, menciones y en la planificación del equipo, así que tus compañeros te identifican sin leer el nombre.
***
## 4. Configurar tu empresa con el asistente [#4-configurar-tu-empresa-con-el-asistente]
La primera vez que entras en **Pymes**, Dinaup abre un **asistente de arranque** que deja tu empresa lista para facturar. Te pide los datos esenciales y prepara la base contable por ti. La IA sugiere categorías y reglas según la actividad que elijas.
### Datos fiscales [#datos-fiscales]
Introduce el **NIF/CIF**, la **razón social** y la **dirección fiscal**. Dinaup **valida el NIF/CIF contra la AEAT**. Estos datos salen en todas tus facturas.
### Forma jurídica y actividad [#forma-jurídica-y-actividad]
Indica tu **forma jurídica** (autónomo, sociedad limitada, etc.) y tu **actividad principal**. Con esto Dinaup adapta las sugerencias del resto del asistente a tu tipo de negocio.
### Cuentas bancarias [#cuentas-bancarias]
Añade tus **cuentas bancarias** principales. Las usarás después para registrar cobros y pagos y para la conciliación.
→ [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias)
### Categorías de gasto [#categorías-de-gasto]
Dinaup te **propone categorías de gasto** según tu sector. Acéptalas tal cual o ajústalas. Determinan cómo se contabilizan tus compras.
### Plan contable [#plan-contable]
El asistente prepara el **plan contable base** sobre el que se apoya toda la contabilidad. Queda listo para empezar y podrás afinarlo más adelante.
El asistente se ejecuta la primera vez, pero puedes **volver a abrirlo** cuando quieras desde la configuración de Pymes.
Esta información tiene carácter orientativo. Consulta con tu asesor fiscal antes de aplicarla a tu caso concreto.
***
## 5. Ajustes fiscales para facturar [#5-ajustes-fiscales-para-facturar]
El asistente deja la base montada. Si vas a emitir facturas, revisa además estos tres puntos.
### Impuestos [#impuestos]
Dinaup preconfigura el **IVA 21 % del régimen general**. Si operas con otros regímenes (VIES intracomunitario, exportación, OSS, REBU), configúralos antes de facturar.
→ [Configuración de Impuestos](/docs/rtg/pymes/configuracion/impuestos)
### Tipos de venta [#tipos-de-venta]
Cada **tipo de venta** define el régimen fiscal, el libro registro y la serie de numeración. Dinaup incluye los más comunes ya configurados.
→ [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
### Categorías de compra [#categorías-de-compra]
Determinan cómo se contabilizan tus gastos. Revísalas o complétalas antes de registrar tu primera compra.
→ [Categorías de Compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra)
***
## 6. Emitir tu primera factura [#6-emitir-tu-primera-factura]
Con la empresa configurada, ya puedes facturar.
### Abre Ventas [#abre-ventas]
En **Pymes**, ve a **Ventas** en el menú lateral y haz clic en **Nueva Venta**.
### Elige tipo de venta y cliente [#elige-tipo-de-venta-y-cliente]
Selecciona el **tipo de venta** (por ejemplo, Nacional) y añade el **cliente**. Si aún no existe, lo creas sobre la marcha.
### Añade conceptos y guarda [#añade-conceptos-y-guarda]
Añade los **productos o conceptos** con sus cantidades y precios, revisa totales, impuestos y retenciones, y haz clic en **Guardar**.
La factura queda registrada en su libro y, si tienes la contabilización automática activada, la contabilidad se genera sola.
→ [Guía: Emitir Factura Nacional](/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-nacional)
***
## 7. Invitar a tu equipo [#7-invitar-a-tu-equipo]
Los usuarios se gestionan desde el **Panel de administración** en [dinaup.com](https://dinaup.com).
### Ve a Usuarios [#ve-a-usuarios]
En el panel de [dinaup.com](https://dinaup.com), abre **Usuarios** y haz clic en **Invitar usuario**.
### Indica email y tipo de usuario [#indica-email-y-tipo-de-usuario]
Introduce el **email** del compañero y elige su **tipo de usuario**: Administrador, Estándar, Básico o Lectura. El tipo define qué puede hacer dentro de Dinaup.
### Activa sus módulos [#activa-sus-módulos]
Marca los **módulos** a los que tendrá acceso (Pymes, CRM, RRHH, etc.). El invitado solo verá lo que le habilites.
### Espera a que active su cuenta [#espera-a-que-active-su-cuenta]
El compañero recibe un **email de invitación** para unirse. Cuando entre, podrás afinar sus permisos.
**Da el mínimo, no el máximo.** Asigna el tipo de usuario más bajo que le permita trabajar y sube permisos solo si hacen falta. Evita invitar a todo el mundo como Administrador "por si acaso".
→ [Gestión de Usuarios](/docs/cuenta/gestion-de-usuarios)
***
## 8. Dónde pedir ayuda [#8-dónde-pedir-ayuda]
* **Icono de ayuda** en la barra superior: abre el canal de **soporte** para escribir tu duda.
* **Buscador global** (arriba): escribe lo que buscas y Dinaup te lleva directo a la sección o al registro.
* **Email de soporte**: [soporte@dinaup.com](mailto:soporte@dinaup.com).
***
## 9. Siguientes pasos [#9-siguientes-pasos]
Según lo que necesites, estos son los caminos recomendados.
### Si necesitas facturar [#si-necesitas-facturar]
* [ ] Configura tus [impuestos](/docs/rtg/pymes/configuracion/impuestos) y [retenciones](/docs/rtg/pymes/configuracion/retenciones)
* [ ] Crea tus primeros [clientes](/docs/rtg/pymes/facturacion/ventas)
* [ ] Registra tu primera [factura de venta](/docs/rtg/pymes/procesos/emision-de-facturas)
* [ ] Activa [Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu) si aplica
### Si necesitas controlar el inventario [#si-necesitas-controlar-el-inventario]
* [ ] Da de alta tus [productos](/docs/rtg/pymes/inventario-y-precios/productos)
* [ ] Configura [almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes) si tienes varias ubicaciones
* [ ] Crea [catálogos de venta](/docs/rtg/pymes/inventario-y-precios) con tarifas por segmento
### Si necesitas gestionar recursos humanos [#si-necesitas-gestionar-recursos-humanos]
* [ ] Da de alta a tus [empleados](/docs/rtg/recursos-humanos/procesos/alta-de-empleado)
* [ ] Configura los [horarios](/docs/rtg/recursos-humanos/procesos/alta-de-horarios) y [festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos)
* [ ] Los empleados ya pueden [fichar](/docs/rtg/recursos-humanos/fichaje) desde su dispositivo
### Si necesitas integrar con otros sistemas [#si-necesitas-integrar-con-otros-sistemas]
* [ ] Genera una [Clave API](/docs/cuenta/claves-api)
* [ ] Consulta los [endpoints disponibles](/docs/desarrollo/integraciones/webhook/entrantes)
* [ ] Configura [webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes) para recibir eventos en tiempo real
* [ ] Explora la integración con [n8n, Make o Zapier](/docs/desarrollo/integraciones/zapier-make-y-n8n)
***
## Preguntas frecuentes [#preguntas-frecuentes]
Sí, desde tu perfil. El cambio es inmediato y no necesitas reiniciar nada.
No hace falta empezar de cero: reabres el asistente de arranque desde la configuración de Pymes y completas lo que falte cuando quieras.
Puedes revocar el acceso o eliminar la invitación desde el Panel de administración, en la sección de Usuarios.
Sí, Dinaup es responsive. Algunas funciones, como el TPV o los fichajes, funcionan especialmente bien en móvil o tablet.
***
→ [¿Qué es Dinaup?](/docs/rtg/que-es-dinaup)
→ [Crear cuenta](/docs/cuenta/crear-cuenta)
→ [Ready To Go](/docs/rtg/que-es-dinaup)
→ [Gestión de Usuarios](/docs/cuenta/gestion-de-usuarios)
# La IA de Dinaup y Yudo (/docs/guias/ia)
La IA de Dinaup te propone, redacta, lee documentos y rellena formularios, pero el botón final lo pulsas tú. Vive en dos sitios:
Un sitio aparte (
**Apps → IA**
) para chatear, crear asistentes y usar herramientas sueltas.
El copiloto que aparece
*dentro*
de la ventana en la que ya estás trabajando, y opera sobre lo que tienes delante.
Ninguna IA de Dinaup cierra una factura, envía un email ni graba un dato por su cuenta. Cuando algo va a cambiar, te abre el formulario relleno y firmas tú. Y hereda **tus** permisos: lo que tú no ves, la IA tampoco.
## Antes de empezar [#antes-de-empezar]
La IA es una capa **opcional**. Si tu empresa la tiene apagada, no aparece; si la ves disponible, está activa para ti. Cuando no puedas usarla (desactivada en la empresa o agotada tu cuota de la semana) el botón de Yudo aparece como **"Yudo no disponible"**. El motivo sale al pasar el ratón.
## Chatear con un agente [#chatear-con-un-agente]
Un **agente** es un asistente con el que conversas en lenguaje natural y que conoce tu negocio (dentro de tus permisos). Los chats se abren en una **ventana flotante**, así que sigues viendo la pantalla de detrás mientras hablas.
Entra en **Apps → IA → Explorador**. Verás los agentes disponibles y las plantillas listas para usar.
Abre uno. Si no sabes por dónde arrancar, pulsa uno de los **prompts sugeridos** que aparecen como botones y empiezas sin escribir nada.
Pregunta lo que necesites. Puedes **adjuntar archivos** (PDF, imágenes, hojas de cálculo, documentos) para que el agente responda sobre su contenido.
### Elegir cómo de listo lo quieres [#elegir-cómo-de-listo-lo-quieres]
En la cabecera del chat eliges el **nivel** con el que piensa el agente. Es el equilibrio entre rapidez y profundidad, y cambia lo que consume:
| Nivel | Cuándo usarlo |
| --------------- | ---------------------------------------------------------------------------------- |
| **Rápido** | Preguntas simples, clasificar, resumir algo corto. El más ágil y barato. |
| **Equilibrado** | El día a día. El punto de partida para casi todo. |
| **Razonador** | Decisiones complejas, análisis a fondo, textos delicados. Más lento, el más capaz. |
Empieza por **Equilibrado**. Si se queda corto, sube a **Razonador**; si repites lo mismo muchas veces, baja a **Rápido** y ahorras. Puedes cambiar de nivel a mitad de conversación sin perder el hilo.
Todo lo que hablas se **guarda solo** y es buscable por palabra clave en **IA → Historial**, así que recuperas lo que ya preguntaste sin repetirlo.
→ [Chat y agentes en detalle](/docs/rtg/ia/chat-y-agentes)
## Yudo: el copiloto dentro de la ventana [#yudo-el-copiloto-dentro-de-la-ventana]
**Yudo no es un sitio al que vas; es un panel que aparece donde ya estás.** En muchas ventanas de Dinaup (un asiento contable, la ficha de un cliente, los datos fiscales, la edición de un día de fichaje, una cuenta bancaria…) lo tienes a un clic, y opera sobre **lo que tienes delante en ese momento**.
Abre una de esas ventanas. Arriba a la derecha verás un chip **"Activar Yudo"**.
Púlsalo. La ventana se parte en dos: tu formulario a la izquierda, el chat de Yudo a la derecha (con su icono, su título y la etiqueta **IA**). Arrastra la división para darle más o menos sitio.
Pídele el cambio en lenguaje natural. Yudo **edita el formulario por ti** (añade líneas, rellena campos, ajusta valores) y tú lo ves pasar en directo.
Revisa lo que ha dejado y **guarda tú**, con el botón normal de la ventana.
Antes de borrar líneas o vaciar un campo, Yudo te lo pregunta, y nada queda registrado hasta que pulsas guardar. Para acciones delicadas, repasa el resultado antes de aceptar.
Si trabajas con Yudo abierto, se queda abierto en **todas** las ventanas que lo lleven; si lo prefieres cerrado, igual. Y dentro de una misma ventana puedes cerrar y reabrir el panel sin perder la conversación.
Algunos sitios donde Yudo ya echa una mano:
| Ventana | Para qué te sirve Yudo |
| -------------------------------- | -------------------------------------------------------------------------------------------------------- |
| **Asiento contable** | Montar el asiento dictándolo: busca la cuenta, añade los apuntes y cuadra debe y haber. |
| **Ficha de cliente / proveedor** | Completar o corregir datos de la entidad sin saltar de campo en campo. |
| **Datos fiscales** | Pedir una revisión de los datos antes de guardar. |
| **Edición de un día de fichaje** | "Registra una ausencia justificada el martes", "ajusta la salida a las 18:00", y lo aplica sobre el día. |
| **Cuenta bancaria** | Analizar y clasificar movimientos sin escribir reglas a mano. |
La lista crece con cada actualización: **si ves a Yudo en una ventana, puede operar sobre ella.** Si no lo ves, esa ventana todavía no lo lleva.
## De la factura al dato: digitalización [#de-la-factura-al-dato-digitalización]
En lugar de teclear una factura de proveedor, la subes y la IA **lee el PDF y te extrae los datos** (proveedor, importes, fechas) para que tú solo confirmes.
En **IA → Análisis Facturas** tienes el historial de todo lo digitalizado: qué se procesó, cuándo, y cuánto tiempo te ha ahorrado frente a meterlo a mano. El dato extraído te llega como **propuesta**: lo revisas antes de que entre en tu contabilidad.
→ [Digitalización con OCR](/docs/rtg/ia/digitalizacion-ocr)
## Herramientas sueltas (sin agente) [#herramientas-sueltas-sin-agente]
En **IA → Herramientas** tienes utilidades de un solo uso, cada una en su tarjeta. Pulsas una, rellenas y tienes el resultado:
Crea una imagen a partir de una descripción de texto.
Quita el fondo de una imagen.
Sube la calidad y la nitidez de una foto.
Corrige, resume, expande o reformula un texto.
Genera un email profesional a partir de cuatro puntos clave.
Repasa ortografía y gramática.
Pasa un texto a otro idioma.
Crea un código QR desde un texto o una URL.
Genera contraseñas seguras a tu medida.
→ [Herramientas de IA](/docs/rtg/ia/herramientas)
## Crea tu propio agente [#crea-tu-propio-agente]
Cuando un agente predefinido no encaja con tu negocio, te montas el tuyo en el **Builder** (**IA → Builder**). Le das un rol, le subes documentos que debe conocer y eliges con qué modelo piensa.
En **IA → Builder**, crea un agente nuevo y ponle **nombre** y una **descripción** clara (ayuda a tu equipo a saber cuándo usarlo).
Escribe el **system prompt**: quién es, cómo habla y qué reglas sigue. Es lo que más diferencia a un buen agente de uno mediocre.
Opcional: súbele **archivos de conocimiento** (manuales, catálogos, normativa interna) para que responda sobre tu información.
**Pruébalo** desde el propio Builder, ajusta lo que falle y, cuando esté listo, decide quién puede usarlo: solo tú o todo el equipo.
Un agente compartido respeta los permisos de cada persona: si alguien no puede ver cierta información en Dinaup, el agente tampoco se la enseña.
→ [Crear un agente](/docs/rtg/ia/crear-agente)
## Controla lo que gastas [#controla-lo-que-gastas]
La IA se paga **por uso real**: cada operación tiene un precio, no hay cuotas fijas ni mínimos. Para que nadie se dispare, cada usuario tiene un **tope de gasto semanal** que define el administrador.
En **IA → Inicio** ves tu panel de uso:
* **Tu consumo de la semana** y cuánto te queda hasta el tope, con una barra que avisa en ámbar y en rojo según te acercas.
* El **histórico** por periodo, desglosado entre chat y herramientas, con tokens y coste.
* Si eres administrador, además el reparto por **persona del equipo**.
Cuando agotas tu cuota semanal, las acciones de IA se pausan hasta el siguiente periodo (o hasta que el administrador amplíe tu límite). El resto de Dinaup sigue funcionando con normalidad: solo se pausa la IA.
→ [Cuotas y permisos](/docs/rtg/ia/cuotas-y-permisos) · [Panel de uso](/docs/rtg/ia/panel-de-uso)
***
Para el detalle de cada zona (explorador, builder, clasificadores, casos por módulo, cuotas) tienes la [referencia de IA](/docs/rtg/ia).
# Guías (/docs/guias)
# Instalar Dinaup Terminal y publicar tu primer módulo (/docs/guias/instalar-terminal-y-publicar-modulo)
Vas a instalar [Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal), conectarte a un tenant, crear una sección con un par de campos, darle comportamiento con un algoritmo y un informe, y publicarlo como módulo. Cada paso enlaza al detalle por si quieres profundizar.
**Contenido técnico para partners e integradores** que construyen sobre Dinaup. El usuario final que factura o vende trabaja desde la aplicación web; aquí moldeas el sistema por debajo con [Flex](/docs/desarrollo/flex).
***
## Antes de empezar [#antes-de-empezar]
| Requisito | Por qué |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Equipo con Windows** | Terminal es una aplicación de escritorio para Windows. Se instala en tu perfil de usuario, sin permisos de administrador. |
| **Acceso a un tenant** | El servidor de tu organización, una **licencia** y un **usuario** con su contraseña. Si no los tienes, pídelos a quien administre Dinaup. |
| **Licencia Flex activa** | Sin ella abres Terminal pero **no editas la estructura** del tenant. Es lo que habilita crear secciones, campos, algoritmos y módulos. |
Si al entrar no puedes editar secciones ni campos, revisa que el tenant tenga **Flex activo** y que tu usuario no sea de solo lectura. Planes en [Precios](/docs/cuenta/precios); concepto en [¿Qué es Dinaup?](/docs/rtg/que-es-dinaup).
***
## Construir el módulo [#construir-el-módulo]
Seis fases: instalas y conectas, modelas los datos, les das comportamiento y publicas. Cada capa se apoya en la anterior, así que vas de abajo arriba: primero los datos, luego los cálculos, por último cómo se explotan.
### Instala Terminal y conéctate al tenant [#instala-terminal-y-conéctate-al-tenant]
Instala Dinaup Terminal con `winget install Dinaup.CLI` (o descarga el ejecutable oficial), ábrelo y acepta la licencia. En la pantalla de acceso introduce los tres datos que identifican tu entorno:
* **Servidor**: la instancia de Dinaup de tu organización.
* **Licencia**: tu empresa dentro de ese servidor; determina los datos a los que entras.
* **Usuario**: tu cuenta personal; determina qué puedes ver y hacer.
Conéctate al tenant que vas a personalizar con un usuario que pueda **editar la estructura** (no de solo lectura).
Lo que editas con Flex afecta a **todos los usuarios de ese tenant**. Para cambios delicados, usa un entorno de pruebas, no el tenant de producción de un cliente.
👉 [Ver detalle: Instalación y conexión](/docs/desarrollo/recursos/dinaup-terminal/instalacion-y-conexion)
### Entiende los canales antes de tocar nada [#entiende-los-canales-antes-de-tocar-nada]
Tu trabajo viaja por **canales de madurez**. Saber en cuál estás te evita sorpresas al publicar.
| Canal | Para qué es |
| ------------------------ | ----------------------------------------------------------------------------------- |
| **Desarrollo** | Versión en construcción, sujeta a cambios. Donde creas y pruebas mientras trabajas. |
| **Beta** | Versión candidata, estable pero en validación, para probar en condiciones reales. |
| **Producción** (release) | Versión estable que reciben los clientes finales en su día a día. |
Una versión nace en **desarrollo**, madura hacia **beta** y se publica en **producción**. La licencia fija el canal: una de producción no instala versiones a medio hacer. Por eso conviene **construir contra un tenant de desarrollo o beta**.
👉 [Ver detalle: Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales)
### Crea una sección con un par de campos [#crea-una-sección-con-un-par-de-campos]
Una **sección** es una tabla de datos (clientes, equipos, incidencias… lo que tu solución necesite). Es el cimiento, así que empiezas por aquí.
1. Crea la sección y dale un **nombre** claro.
2. Si va a compartir estructura con otras, apóyala en una **sección base** para no repetir campos.
3. Añade un par de **campos** para arrancar. Para cada uno eliges:
* un **tipo base** (texto, número decimal, fecha, sí/no, relación…),
* un **rol** opcional que lo afina (un Texto con rol Email valida el formato),
* sus **atributos**: obligatorio, bloqueado, valor por defecto.
Modela los campos pensando en cómo se rellenan y consultan después. Un buen diseño aquí te ahorra correcciones más tarde.
👉 [Ver detalle: Secciones](/docs/desarrollo/flex/secciones) · [Campos](/docs/desarrollo/flex/campos)
### Añade un algoritmo simple [#añade-un-algoritmo-simple]
Cuando un valor **se calcula** en vez de teclearse (un total, un acumulado, un dato traído de otra sección), lo resuelves con un **algoritmo**.
Define uno y conéctalo a un campo **auto-calculado**: ese campo deja de escribirse a mano y se rellena solo a partir del cálculo. Los algoritmos son el motor de Flex: los defines una vez y los reutilizas en campos, informes y documentos.
👉 [Ver detalle: Algoritmos](/docs/desarrollo/flex/algoritmos)
### Construye un informe para explotar los datos [#construye-un-informe-para-explotar-los-datos]
Un **informe** convierte tu sección en un listado útil: eliges columnas, aplicas filtros y orden, agrupas y añades columnas calculadas con el algoritmo del paso anterior.
Así el usuario "ve" y "filtra" lo que guardas sin escribir consultas a mano. Con esto tu solución ya **guarda, calcula y muestra**: un ciclo completo de datos.
👉 [Ver detalle: Informes](/docs/desarrollo/flex/informes)
### Publica todo como módulo [#publica-todo-como-módulo]
Cuando el conjunto funciona, **empaquetas** la sección, sus campos, el algoritmo y el informe en un **módulo** reutilizable. Es lo que convierte una personalización suelta en algo distribuible y repetible. La publicación tiene su propio recorrido, justo debajo.
👉 [Ver detalle: Flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo)
***
## Publicar el módulo [#publicar-el-módulo]
Terminal te guía por una serie de comprobaciones para que el módulo llegue completo y a quien debe.
### Prepara el módulo [#prepara-el-módulo]
Reúne en el módulo todas las piezas que construiste: la sección, sus campos, el algoritmo y el informe. Revisa que no falte nada y que el conjunto tenga sentido como una **unidad coherente**.
### Valida las dependencias [#valida-las-dependencias]
Un módulo suele apoyarse en otras piezas (otras secciones, otros módulos). Terminal **comprueba esas dependencias** antes de dejarte publicar, para que no instales un módulo que "casi" funciona porque le falta algo de su origen.
### Asigna versión y canal [#asigna-versión-y-canal]
Cada publicación lleva una **versión** (para saber qué cambió respecto a la anterior) y se envía por un **canal** (que determina quién la recibe y cuándo).
Para un primer módulo, publica en **desarrollo**: lo pruebas a fondo y, cuando esté sólido, lo promocionas a **beta** y luego a **producción**. Tratar versión y canal como parte de la publicación es lo que te deja distribuir cambios de forma ordenada y volver atrás si hace falta.
Una vez publicado, cualquier licencia compatible instala el módulo desde la galería compartida y obtiene el mismo comportamiento. El núcleo se actualiza solo a la versión vigente del canal de cada licencia.
***
## Cómo encaja con el resto [#cómo-encaja-con-el-resto]
* El **qué** (el modelo de secciones, campos, algoritmos, informes y documentos) vive en [Flex](/docs/desarrollo/flex). Esta guía es el **orden** en que lo aplicas desde Terminal.
* La **instalación y conexión** al tenant tiene su página propia: [Instalación y conexión](/docs/desarrollo/recursos/dinaup-terminal/instalacion-y-conexion).
* La mecánica de **empaquetar y distribuir** se desarrolla en [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales) y [Flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo).
***
## Preguntas frecuentes [#preguntas-frecuentes]
Buena parte del trabajo (secciones, campos, informes) se configura sin escribir código. Para lógica avanzada existen los algoritmos y DinaScript. En cualquier caso es un recorrido técnico, pensado para partners e integradores, no para el usuario final.
Conviene no hacerlo. Publica primero en desarrollo, pruébalo, pásalo a beta para validar en condiciones reales y solo entonces a producción. Cada canal es un peldaño más fiable que el anterior. Lo tienes en Módulos y canales.
Casi siempre es por falta de licencia Flex activa, o porque tu usuario tiene rol de solo lectura. Sin Flex puedes abrir Terminal pero no crear secciones ni campos. Revísalo con quien administre el tenant.
No. El recorrido completo importa la primera vez y antes de cada publicación. En el día a día entras directo a lo que toque: ajustar un campo, retocar un informe o sacar una nueva versión del módulo.
***
→ [Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal)
→ [Instalación y conexión](/docs/desarrollo/recursos/dinaup-terminal/instalacion-y-conexion)
→ [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales)
→ [Flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo)
→ [Documentación de Flex](/docs/desarrollo/flex)
# Cómo gestiona Dinaup el inventario (/docs/guias/inventario)
Todo cuelga del menú lateral, dentro del grupo **Inventario**:
El catálogo: qué vendes, cómo controlas su stock, sus lotes y movimientos.
El stock por ubicación, los movimientos manuales y el picking de salidas pendientes.
Qué productos están por debajo de su mínimo y cuántas unidades pedir.
## Antes de empezar [#antes-de-empezar]
Crea al menos un almacén en **Configuración → Almacenes**: es donde se guarda el stock, así que sin almacén no hay inventario.
Para entender *por qué* una venta no descuenta el stock al instante (los tres estados, los lotes FIFO/FEFO, la cuarentena) mira [Cómo funciona el stock](/docs/guias/como-funciona-el-stock). Aquí trabajas con las pantallas.
## Da de alta un producto [#da-de-alta-un-producto]
Los productos están en **Inventario → Productos**. La pestaña **Productos** lista el catálogo; al lado tienes **Entradas**, **Salidas** y **Lotes de productos** para mirar el histórico en crudo.
Pulsa **Nuevo** (arriba a la derecha). Se abre un asistente que decide la pieza más importante: **cómo se controla el stock**.
Elige **Producto** (un bien tangible) o **Servicio** (una actividad, que no cuenta inventario).
Si es producto, elige el **modo de stock**:
* **Unidades**: cuenta las unidades disponibles. Lo habitual.
* **Lotes**: controla lotes, caducidades y trazabilidad (FIFO/FEFO).
* **Sin stock**: no cuenta inventario (servicios o lo que no controlas).
Confirma la **unidad de medida** y, si las tienes definidas, una **categoría de venta** y una de **compra** por defecto. Puedes omitir las categorías.
Al terminar se abre la ficha del producto para rellenar el resto (nombre, precio…). Guarda.
El modo que eliges aquí decide cómo se comporta todo lo demás. Un producto **por cantidad** no usa lotes: cuando registres un movimiento, el campo de lote aparece bloqueado con el aviso *"Este producto se gestiona por cantidad"*. Un producto **por lotes** sí pide lote en cada entrada y salida.
## Dale existencias a un producto [#dale-existencias-a-un-producto]
Crear el producto **no** le da stock: nace en cero. Las existencias entran con un **movimiento de inventario**. El camino depende del modo de stock del producto.
### Por unidades [#por-unidades]
Abre **Inventario → Almacenes** y pulsa el botón **Inventario** (arriba). Se abre el diálogo de movimiento:
Deja el conmutador en **Entrada** y elige el **tipo de movimiento** (motivo): inventario inicial, ajuste de conteo, producción interna… Si tu cuenta lo tiene sembrado, viene preseleccionado *Ajuste*.
Selecciona el **producto** y el **almacén**. El **hueco** es opcional.
Pon las **unidades a añadir** y pulsa **Registrar movimiento**.
Para retirar stock (merma, rotura, consumo interno, pérdida) es el mismo diálogo con el conmutador en **Salida**: ahí el sistema te muestra el **stock disponible en el almacén** y no te deja retirar más de lo que hay.
### Por lotes [#por-lotes]
Un producto por lotes necesita primero un **lote** que reciba las existencias. Desde la ficha del producto, o desde **Almacenes → Crear lote**:
Crea el lote: **producto**, **código / referencia**, **tipo** y **estado**, y las **fechas** que apliquen: inicio de disponibilidad, **caducidad** y límite de devolución a proveedor.
El lote **nace sin stock**. Para darle existencias, registra una **Entrada de inventario** apuntando a ese lote.
Cuando editas un lote que ya existe verás su **Disponible** y su **Físico**, y dos botones: **Agregar entrada** y **Agregar salida**. Abren el movimiento de inventario ya apuntando a ese lote, sin tener que volver a seleccionarlo.
## Compras y devoluciones [#compras-y-devoluciones]
El botón **Inventario** es para ajustes internos. Para mercancía que entra o sale por una operación comercial, en **Almacenes** tienes dos botones más:
| Botón | Entrada | Salida |
| ---------- | -------------------------------------------------------- | ---------------------- |
| **Compra** | Recepción de compra (mercancía recibida de un proveedor) | Devolución a proveedor |
| **Venta** | Devolución de cliente | Salida por venta |
En ambos eliges entrada o salida con un conmutador y rellenas el mismo formulario de producto, almacén, hueco, lote y cantidad.
Estos diálogos son para movimientos puntuales que metes a mano. En la operativa normal, vender desde el [TPV](/docs/guias/tpv) o una factura ya genera la salida de stock sola, según la política de empresa. Lo explica [Cómo funciona el stock](/docs/guias/como-funciona-el-stock).
## Revisa el stock de un almacén [#revisa-el-stock-de-un-almacén]
**Inventario → Almacenes** es el panel de control del inventario. Arriba, unos indicadores te dan la foto: número de almacenes, **referencias con stock**, **unidades disponibles**, **referencias agotadas** (candidatas a reponer) y **valor de inventario**.
Debajo, la lista de almacenes a la izquierda; al pulsar uno, a la derecha ves su **stock**, con dos columnas que no significan lo mismo:
Lo que aún puedes vender. Baja en cuanto algo se reserva o se entrega.
Lo que hay de verdad en la estantería. Solo baja cuando el producto sale.
Cada almacén lleva una etiqueta **Disponible en TPV** o **Solo interno**, y debajo verás quién **trabaja aquí** y quién **tiene acceso**. Al final de la página, la **matriz stock × almacén** cruza cada producto con cada almacén.
## Prepara las salidas pendientes (picking) [#prepara-las-salidas-pendientes-picking]
Cuando una venta reserva stock pero todavía no se ha entregado, queda como **salida pendiente**. En la pantalla del almacén, el bloque **Salidas pendientes de preparar** las cierra sin entrar venta por venta:
Localiza la salida pendiente del almacén que estás mirando.
Si el producto va por lotes, **elige el lote** del que sale. Marca la salida como **Completada**.
Si la venta se cae, puedes **Anularla** desde aquí mismo.
Al marcarla **Completada**, el stock **físico** baja y se asigna el lote. El servidor recalcula el inventario en cuanto ve el cambio: no tienes que refrescar nada a mano. El detalle de los tres estados está en [Cómo funciona el stock](/docs/guias/como-funciona-el-stock).
## Sabe qué comprar con Reposición [#sabe-qué-comprar-con-reposición]
**Inventario → Reposición** te dice qué reponer y cuánto. Compara el **disponible** de cada producto en cada almacén con su **stock mínimo**, y solo lista lo que está por debajo. Para cada producto bajo mínimo, propone **pedir** hasta llevarlo a su **stock máximo** (o al mínimo si no hay máximo definido).
Unidades totales a comprar de cada producto para abastecer todos los almacenes. Expande una fila para ver el reparto por almacén.
El detalle almacén a almacén: disponible, mínimo, máximo y cuánto pedir de cada producto.
Arriba tienes los totales: **productos a reponer**, **unidades a comprar** y **almacenes afectados**.
Reposición solo ve un producto cuando tiene un **stock mínimo** mayor que cero. Si no aparece nada y crees que debería, revisa que los productos tengan su mínimo (y, mejor, su máximo) configurados.
## Ver la ficha de un producto [#ver-la-ficha-de-un-producto]
Desde **Productos**, pulsa un producto para abrir su ficha. Es el resumen completo de su inventario:
* **Indicadores**: stock disponible, stock físico, valor de inventario, almacenes con stock y número de lotes.
* **Stock por almacén**: dónde están sus existencias.
* **Lotes del producto**: la lista de lotes con su disponible y físico; pulsa uno para editarlo.
* **Movimientos de inventario**: el histórico de entradas y salidas, paginado y filtrable.
Desde la propia ficha puedes **Crear lote** o **Editar** el producto.
Para la referencia campo a campo de cada pantalla tienes [Productos](/docs/rtg/pymes/inventario-y-precios/productos), [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos), [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes) y [Movimientos de inventario](/docs/rtg/pymes/inventario-y-precios/movimientos-de-inventario).
# Montar tu inventario de cero (/docs/guias/montar-tu-inventario)
Vas a montar el inventario en seis pasos, en orden: primero defines **dónde** guardas el stock (almacenes), luego **qué** guardas (productos y, si aplica, lotes), después **cuánto** tienes (stock inicial), y por último la **reposición**, que te avisa de qué pedir.
## Antes de empezar [#antes-de-empezar]
Necesitas acceso a **Inventario y Precios** en tu cuenta. Si no ves la sección, pídele al administrador que la active.
Con un solo punto de venta te basta un almacén único y productos sin lotes. Los almacenes adicionales y los lotes suman cuando manejas varias tiendas, caducidades o trazabilidad.
***
## El recorrido completo [#el-recorrido-completo]
### Crea tus almacenes [#crea-tus-almacenes]
Un **almacén** es cualquier lugar desde el que gestionas stock: un depósito, una tienda o una sucursal. Cada uno lleva su inventario por separado, así sabes cuántas unidades hay y dónde.
Da de alta uno por cada punto donde guardas o mueves mercancía. Ponle un nombre claro (la tienda, el depósito central, cada sucursal) y decide si su stock **vende en el TPV** o es de uso interno.
👉 [Ver detalle: Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
### Da de alta tus productos [#da-de-alta-tus-productos]
Un **producto** es cualquier artículo o servicio que tu empresa compra, vende o controla en inventario. Crear las fichas mejora tus estadísticas, automatiza categorías contables y te deja fijar precios en el TPV.
Crea una ficha por artículo. Si quieres que Reposición te avise (paso 6), fija aquí su **stock mínimo** y, si lo deseas, su **stock máximo**.
👉 [Ver detalle: Productos](/docs/rtg/pymes/inventario-y-precios/productos)
Los precios de compra y venta no se ponen aquí: se gestionan con tus catálogos y se aplican solos en el TPV. Cómo configurarlos, en la página de Productos.
### Si lo necesitas, crea lotes [#si-lo-necesitas-crea-lotes]
Un **lote** es una partida concreta de un producto: unidades que comparten origen, fecha y características. Te dan **trazabilidad** (de qué partida salió cada unidad, cuándo caduca, en qué estado está) y son la base para controlar caducidades y stock fino por almacén.
No todos los productos los necesitan. Actívalos solo donde importe la caducidad, el origen de la partida o el control por estado. El resto se gestiona con el producto y su stock.
👉 [Ver detalle: Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
**Un lote recién creado nace sin stock.** Crearlo solo da de alta la partida con sus datos; las unidades entran en el paso siguiente, cuando registras una entrada sobre ese lote.
### Carga el stock inicial con un movimiento de inventario [#carga-el-stock-inicial-con-un-movimiento-de-inventario]
Ya tienes almacenes y productos, pero las existencias están a cero. Para meter tu **inventario de partida** registras un **movimiento de inventario** de tipo **entrada**: añades las unidades con las que arrancas sin que medie una compra.
Por cada producto, registra una **entrada** indicando el **almacén** donde está el stock, la **cantidad** inicial y, si el producto va por lotes, el **lote** afectado (puedes crearlo desde el mismo formulario). Repítelo para cada ubicación con existencias.
👉 [Ver detalle: Movimientos de inventario](/docs/rtg/pymes/inventario-y-precios/movimientos-de-inventario)
Estos mismos movimientos sirven para los ajustes del día a día: una **salida** para una merma o rotura, una **entrada** para una producción interna, o un ajuste para cuadrar un recuento. Mover stock entre dos almacenes es una salida en el origen y una entrada en el destino.
### Entiende tu stock por almacén [#entiende-tu-stock-por-almacén]
Con el inventario cargado, la vista de **stock por almacén** te dice cuántas unidades hay de cada referencia en cada ubicación. Ese número no se teclea: Dinaup lo **calcula sumando tus movimientos**, así que el stock siempre refleja las entradas y salidas.
El centro de la vista es una matriz con tus productos en las filas y tus almacenes en las columnas, más unos indicadores de cabecera (referencias con stock, unidades disponibles, referencias agotadas, valor de inventario). Para cada producto verás dos cifras que conviene no confundir:
* **Disponible**: lo que puedes vender o usar ahora mismo.
* **Físico**: lo que hay realmente en la estantería.
Normalmente coinciden; se separan cuando hay unidades reservadas o comprometidas que siguen en el almacén pero ya no puedes disponer de ellas.
👉 [Ver detalle: Stock por almacén](/docs/rtg/pymes/inventario-y-precios/stock-por-almacen)
### Deja que Dinaup te diga qué reponer [#deja-que-dinaup-te-diga-qué-reponer]
Cuando un producto cae por debajo de su **stock mínimo** en un almacén, la herramienta de **Reposición** te lo marca como pendiente y calcula las unidades a pedir. Preparas tus compras con datos, no a ojo.
Para esto, el producto necesita un **stock mínimo** definido en su ficha (paso 2): Reposición solo vigila lo que le dices. Mira la **Vista global** si vas a lanzar un pedido único al proveedor, o **Por almacén** si gestionas las compras ubicación por ubicación.
👉 [Ver detalle: Reposición](/docs/rtg/pymes/inventario-y-precios/reposicion)
Reposición es una herramienta de **decisión, no de ejecución**: te dice qué y cuánto comprar. El pedido de compra y la entrada del stock que llega los registras tú en tu flujo de compras habitual.
***
## Qué tienes al terminar [#qué-tienes-al-terminar]
* **Sabes dónde está cada cosa.** Cada almacén lleva su recuento y la matriz te cruza producto y almacén.
* **El stock se mueve solo con tu operativa.** Compras, ventas y ajustes recalculan las existencias; el número nunca se edita a mano.
* **Distingues disponible de físico**, así que sabes qué puedes vender ahora y qué contar en un recuento.
* **Reposición te avisa de qué pedir** antes de quedarte sin existencias, siempre que hayas fijado mínimos.
¿Un número no te cuadra? No lo edites en la pantalla de stock: corrige el movimiento que lo causó o registra un ajuste de inventario.
***
## Sigue explorando [#sigue-explorando]
Cada paso tiene su página de detalle con todas las opciones, las cifras de cabecera y las preguntas frecuentes:
* [Cómo funciona el stock](/docs/guias/como-funciona-el-stock): el modelo de inventario por dentro: venta vs movimiento, disponible vs físico, lotes y devoluciones.
* [Inventario y Precios](/docs/rtg/pymes/inventario-y-precios): el índice de toda la sección.
* [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes): crear ubicaciones y controlar quién ve qué.
* [Productos](/docs/rtg/pymes/inventario-y-precios/productos): fichas, categorías y precios.
* [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos): trazabilidad, caducidad y estado.
* [Movimientos de inventario](/docs/rtg/pymes/inventario-y-precios/movimientos-de-inventario): entradas, salidas, ajustes y traspasos.
* [Stock por almacén](/docs/rtg/pymes/inventario-y-precios/stock-por-almacen): la matriz de existencias por ubicación.
* [Reposición](/docs/rtg/pymes/inventario-y-precios/reposicion): qué comprar y cuánto.
# Gestión de nóminas (/docs/guias/nominas)
Defines una vez los **conceptos** de tu empresa (salario base, pluses, IRPF, Seguridad Social) y cada nómina se construye eligiendo entre ellos y tecleando importes. Dinaup calcula al guardar los totales, el **líquido a percibir** y el **coste real de empresa**, y deja la nómina lista para contabilizar.
## Antes de empezar [#antes-de-empezar]
* Los **empleados** dados de alta en **Pymes → Empleados**, con su **NIF**: es el dato con el que la IA asocia cada PDF a su empleado.
* Los **tipos de concepto** configurados (siguiente sección). Sin ellos no se puede clasificar ninguna línea.
Todo lo demás vive en **Pymes → Nóminas**.
## Los conceptos: las piezas de la nómina [#los-conceptos-las-piezas-de-la-nómina]
Un **tipo de concepto** es cada línea que puede aparecer en una nómina: Salario base, Plus de transporte, Retención IRPF, Seguridad Social del trabajador, Seguridad Social a cargo de la empresa. Se define una vez, en **Pymes → Nóminas → Tipos de Conceptos**, y se reutiliza en todas las nóminas.
El campo que marca cómo se comporta en el cálculo es el **Tipo**:
| Tipo | Qué hace | Ejemplo |
| ---------------------- | -------------------------------------------------------------- | ----------------------------------------- |
| **Devengo** | Suma a lo que gana el trabajador | Salario base, pluses, horas extra |
| **Deducción empleado** | Resta al trabajador | Anticipos, embargos |
| **Retención empleado** | Se le retiene al trabajador y se ingresa a un organismo | IRPF, cuota obrera de la Seguridad Social |
| **Retención empresa** | Coste a cargo de la empresa; no toca el líquido del trabajador | Cuota patronal, FOGASA, desempleo |
El resto de campos afinan cada concepto:
* **Destino pago retención**: a quién se ingresa la retención (**TGSS**, **AEAT** o **terceros**). Dinaup suma por destino cuánto pagarás a cada organismo.
* **Afecta al neto**: si un devengo entra o no en el líquido a percibir.
* **Especie**: retribución en especie (ticket restaurante, seguro médico). Se acumula en su propio total.
* **Aplica a todas las nóminas**: márcalo en los conceptos que van siempre (salario base, IRPF).
* **Cuenta Debe** y **Cuenta Haber**: las cuentas contables contra las que anota cada línea. Sin ellas, el asiento no sabe dónde imputar el importe.
* **Anotaciones para IA**: pistas para el lector de PDF, por ejemplo "la cuota patronal aparece en el bloque de aportación de la empresa".
Al contabilizar, cada concepto anota su importe contra las dos cuentas que definas aquí. Un salario base puede ir a Debe 640 / Haber 465; la cuota patronal, a Debe 642 / Haber 476. Configurado el catálogo, el asiento sale solo.
Si al registrar una nómina falta un concepto en el catálogo, pulsa el **+** junto al selector de tipo de esa línea. Se abre un alta rápida de cuatro campos (nombre, naturaleza, destino y cuentas) y, al crearlo, queda asignado a la línea. Cuando la nómina viene de un PDF, la naturaleza llega ya propuesta por la IA.
## Registrar una nómina a mano [#registrar-una-nómina-a-mano]
En **Pymes → Nóminas**, pulsa **Nuevo**.
Selecciona el **empleado** y el periodo (**Desde** y **Hasta**, normalmente el mes natural). La **fecha contable** llega rellenada con el día de hoy.
Elige el **tipo de nómina** (mensual, paga extra, finiquito) y el **estado**. El estado llega puesto con el que hayas fijado como inicial en la configuración de la empresa.
Añade los conceptos: elige el **tipo**, ajusta la descripción si quieres y teclea el **importe**. Siempre hay una fila libre al final para seguir tecleando sin pulsar **Agregar**.
Comprueba el **líquido (orientativo)** que se muestra bajo la tabla y pulsa **Guardar**. Dinaup recalcula entonces los totales oficiales de la nómina.
Los importes van **en positivo**: el tipo de cada concepto ya dice si suma o resta. Solo una devolución o regularización (por ejemplo, una devolución de IRPF) se teclea en negativo.
**Ejemplo.** Nómina de marzo de una administrativa:
| Concepto | Tipo | Importe |
| --------------------------- | ------------------------- | ------- |
| Salario base | Devengo | 1.500 € |
| Plus de asistencia | Devengo | 150 € |
| Retención IRPF | Retención empleado (AEAT) | 198 € |
| Seguridad Social trabajador | Retención empleado (TGSS) | 105 € |
| Seguridad Social empresa | Retención empresa (TGSS) | 510 € |
Líquido a percibir: 1.500 + 150 − 198 − 105 = **1.347 €**. Coste de empresa: 1.650 + 510 = **2.160 €**. La cuota patronal no baja el líquido del trabajador: es coste tuyo, y Dinaup lo separa para que el gasto real de plantilla no quede infravalorado.
## Digitalizar nóminas con IA [#digitalizar-nóminas-con-ia]
Si tu gestoría te manda las nóminas en PDF, no las copies a mano. En **Pymes → Nóminas → Archivos** tienes la cola de digitalización:
**Sube los PDF** con el botón de subida. Admite PDF, PNG y JPG de hasta 20 MB, y puedes subir el mes entero de golpe. Si un archivo ya estaba subido, Dinaup lo detecta y no lo duplica.
Pulsa **Analizar** en un documento, o **Analizar N** para el lote. Al analizar en lote eliges el nivel de IA: **Rápido** (0,05 € por nómina), **Equilibrado** (0,10 €, recomendado) o **Profundo** (0,15 €). La IA extrae empleado, DNI, periodo y cada concepto con su importe.
Cada tarjeta analizada muestra el empleado, el periodo y el importe estimado. Pulsa **Revisar**: se abre el editor con los datos precargados y el **PDF original al lado**, para comparar línea a línea.
Comprueba el empleado (lo asocia por DNI), asigna el tipo a cualquier concepto que la IA no haya casado con tu catálogo y pulsa **Guardar**. El documento pasa a **Procesada** y el PDF queda anclado a la ficha de la nómina.
La IA prioriza los conceptos de tu catálogo y lee sus **Anotaciones para IA**. Si un concepto sale mal clasificado, añade la pista en su ficha y en la empresa (**Configuración del negocio → RRHH → Instrucciones IA**) y la siguiente lectura saldrá más fina.
Un documento que no proceda (duplicado, ilegible, de otra empresa) se **Rechaza** y queda consultable en la pestaña **Rechazadas**.
## Contabilizar las nóminas [#contabilizar-las-nóminas]
Cada nómina genera su **asiento contable** a partir de las cuentas Debe y Haber de sus conceptos.
Ve a **Pymes → Contabilidad → Contabilidad automática** y elige el periodo.
Abre la pestaña **Nóminas**: lista las nóminas del periodo que aún no tienen asiento.
Marca las que quieras y pulsa **Procesar**. Dinaup crea los asientos en bloque, con barra de progreso, y cada nómina queda enlazada a su asiento.
Si en la ficha del empleado tienes configuradas sus subcuentas (sueldos 640, anticipos 460, pendiente de pago 465), el asiento baja de la cuenta genérica a la subcuenta del trabajador. El estado de esa configuración lo ves en **Contabilidad → Cuentas contables automáticas**, grupo RRHH.
## No se te escapa ningún mes [#no-se-te-escapa-ningún-mes]
**Pymes → Ponerse al día** comprueba cada mes dos cosas: qué empleados con contrato vigente aún no tienen nómina este mes, y qué nóminas de los últimos tres meses siguen sin asiento contable. Cada aviso lleva su botón para ir directo a resolverlo.
La referencia del módulo, con sus pantallas y catálogos, está en [Nóminas](/docs/rtg/pymes/nominas) y [Registrar nómina](/docs/rtg/pymes/nominas/registrar-nomina).
# Poner en marcha tu empresa (/docs/guias/poner-en-marcha-tu-empresa)
Hay un orden que evita rehacer trabajo: cuenta, licencia, asistente 1Click, Mi Empresa y equipo. Cada tramo enlaza a la página que lo cuenta a fondo.
## Antes de empezar [#antes-de-empezar]
* Un navegador de escritorio o móvil: Chrome, Edge o Firefox. No se instala nada.
* Tu NIF/CIF, razón social y dirección fiscal a mano para el asistente.
* Si te llegó una **invitación** de tu empresa, no registres nada: usa el enlace del email y sáltate al tramo 3.
Dinaup tiene **dos portales**. En [dinaup.com](https://dinaup.com) gestionas la cuenta (usuarios, suscripción, claves API); en [play.dinaup.com](https://play.dinaup.com) trabajas cada día. Esta guía cruza los dos: el registro empieza en dinaup.com y la empresa se configura en Play.
***
## El recorrido [#el-recorrido]
### Crea tu cuenta y entra [#crea-tu-cuenta-y-entra]
Regístrate, confirma el correo e inicia sesión. Si tu empresa exige verificación en dos pasos (2FA), la activas en este primer acceso.
### Registra o activa la empresa [#registra-o-activa-la-empresa]
Da de alta la licencia de tu empresa, o únete a una que ya existe con una invitación.
### Pasa el asistente 1Click [#pasa-el-asistente-1click]
La primera vez que abres Pymes, un asistente te pide los datos esenciales y prepara la base contable: datos fiscales con validación AEAT, forma jurídica, actividad, cuentas, categorías de gasto y plan contable.
### Completa Mi Empresa [#completa-mi-empresa]
Repasa la ficha de identidad fiscal y sube el logo. Es lo que sale en cada factura.
### Invita a tu equipo [#invita-a-tu-equipo]
Añade a tus compañeros con el tipo de usuario adecuado para que cada uno vea solo lo suyo.
***
## 1. Crea tu cuenta y entra [#1-crea-tu-cuenta-y-entra]
El registro completo (formulario, confirmación de correo y primer login) está en [Crear cuenta y unirte a tu empresa](/docs/cuenta/crear-cuenta).
### Regístrate y confirma el correo [#regístrate-y-confirma-el-correo]
Crea la cuenta con tu nombre, email y contraseña, y confirma tu dirección desde el email de activación.
### Inicia sesión [#inicia-sesión]
Entra con tu **email y contraseña**, o con tu cuenta de **Google** si registraste así el acceso.
### Activa el doble factor (si te lo pide) [#activa-el-doble-factor-si-te-lo-pide]
Si tu empresa exige verificación en dos pasos, Dinaup te guía para activarla en este primer acceso. Recibes el código por **SMS** o lo generas con una **app autenticadora**. A partir de ahí, cada inicio de sesión pide ese segundo código además de la contraseña. Lo gestionas luego desde tu perfil.
**Deja tu perfil listo.** Desde tu foto en la barra superior ajustas nombre visible, idioma y notificaciones. Pon tu foto: aparece en comentarios, menciones y planificación, y un equipo con caras se entiende mejor que uno con iniciales.
***
## 2. Registra o activa tu empresa [#2-registra-o-activa-tu-empresa]
Con la cuenta creada, das de alta la **licencia** de tu empresa: tu negocio entra en Dinaup como entidad propia.
### Registra la licencia [#registra-la-licencia]
Completa el formulario de **"Registrar mi empresa"** con la razón social, el NIF/CIF, el teléfono y la dirección fiscal. El proceso campo a campo está en [Registrar tu empresa](/docs/cuenta/registrar-empresa).
### Crea el perfil de empresa [#crea-el-perfil-de-empresa]
Al finalizar, Dinaup activa tu licencia y crea el perfil. Si gestionas varias empresas o quieres ajustar el plan, lo ves en [Configurar tus licencias](/docs/guias/configurar-licencias).
### Entra en Play [#entra-en-play]
Abre [play.dinaup.com](https://play.dinaup.com) en tu navegador, también desde tablet o móvil. Si perteneces a varias empresas, elige con cuál vas a trabajar.
¿No tienes claro qué plan necesitas? Revisa qué incluye cada solución en [Precios](/docs/cuenta/precios). Aquí solo defines la identidad de tu empresa; el plan lo contratas tú.
***
## 3. Pasa el asistente 1Click [#3-pasa-el-asistente-1click]
La **primera vez que entras en Pymes**, Dinaup abre el **asistente de arranque** (1Click). Te pide los datos esenciales y prepara la base contable, apoyándose en la IA para sugerirte categorías y reglas según tu actividad.
### Datos fiscales con validación AEAT [#datos-fiscales-con-validación-aeat]
Introduce el **NIF/CIF**, la **razón social** y la **dirección fiscal**. Dinaup **valida el NIF/CIF contra la AEAT** para asegurar que es correcto desde el principio. Estos datos se usan en todas tus facturas.
### Forma jurídica y actividad [#forma-jurídica-y-actividad]
Indica tu **forma jurídica** (autónomo, sociedad limitada, etc.) y tu **actividad principal**. Con esto Dinaup adapta el resto de sugerencias del asistente a tu tipo de negocio.
### Cuentas bancarias [#cuentas-bancarias]
Añade tus **cuentas bancarias** principales. Las usarás después para registrar cobros y pagos y para la conciliación.
→ [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias)
### Categorías de gasto [#categorías-de-gasto]
Dinaup te **propone categorías de gasto** según tu sector. Acéptalas tal cual o ajústalas. Las categorías determinan cómo se contabilizan tus compras.
### Plan contable [#plan-contable]
El asistente prepara el **plan contable base** sobre el que se apoya toda la contabilidad. Queda listo para empezar y lo afinas más adelante.
El asistente se ejecuta solo la primera vez, pero puedes **reabrirlo** cuando quieras desde la configuración de Pymes para completar lo que te dejaste.
Esta información tiene carácter orientativo. Consulta con tu asesor fiscal antes de aplicarla a tu caso concreto.
***
## 4. Completa Mi Empresa [#4-completa-mi-empresa]
La ficha de **Mi Empresa** es tu identidad fiscal definitiva: lo que aparece como **emisor en cada factura y documento oficial**. Repásala antes de emitir nada.
Está en **Pymes → Mi Empresa** y contiene la denominación, el NIF/CIF, la forma jurídica, el domicilio fiscal, la actividad y el logo. El detalle de qué dato alimenta qué está en [Mi Empresa](/docs/rtg/pymes/mi-empresa).
Sube también el **logo**: se incrusta en las facturas y documentos en PDF que envías a tus clientes.
Antes de emitir tu primera factura, comprueba que la **denominación, el NIF/CIF y el domicilio fiscal** son exactos. Corregir la ficha luego **no reescribe** las facturas ya emitidas: una factura con datos erróneos hay que rectificarla.
La ficha define **quién eres**. Cómo numeras y clasificas tus facturas (series, tipos de venta y libros registro) se define aparte en la [configuración de Pymes](/docs/rtg/pymes/configuracion).
***
## 5. Invita a tu equipo [#5-invita-a-tu-equipo]
Los usuarios se gestionan desde el **Panel de administración** en [dinaup.com](https://dinaup.com).
### Invita por email [#invita-por-email]
En el panel de [dinaup.com](https://dinaup.com), abre **Usuarios** e **Invita usuario**. Introduce el **email** del compañero.
### Elige tipo de usuario y módulos [#elige-tipo-de-usuario-y-módulos]
Asigna su **tipo de usuario** (Administrador, Estándar, Básico o Lectura) y marca los **módulos** a los que tendrá acceso. El invitado solo verá lo que le habilites.
### Espera a que active su cuenta [#espera-a-que-active-su-cuenta]
El compañero recibe un **email de invitación**. Cuando entre, podrás afinar sus permisos por sección y rol.
**Da el mínimo, no el máximo.** Asigna el tipo de usuario más bajo que le permita hacer su trabajo y sube permisos solo si hacen falta. No invites a todo el mundo como Administrador "por si acaso".
Para los tipos de usuario, los roles por sección y cómo afinar permisos, sigue [Usuarios, roles y permisos](/docs/guias/usuarios-roles-y-permisos). El detalle de cada apartado está en [Gestión de Usuarios](/docs/cuenta/gestion-de-usuarios) y [Permisos y roles](/docs/cuenta/permisos-y-roles).
***
## Siguientes pasos [#siguientes-pasos]
Con la empresa en marcha, elige el camino según lo que necesites ahora.
### Empezar a facturar [#empezar-a-facturar]
* [ ] Revisa tus [impuestos](/docs/rtg/pymes/configuracion/impuestos) y [retenciones](/docs/rtg/pymes/configuracion/retenciones)
* [ ] Repasa los [tipos de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) y las [categorías de compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra)
* [ ] Sigue el recorrido hasta emitir tu primera factura en la [Guía de inicio rápido](/docs/guias/guia-de-inicio-rapido)
### Controlar el inventario [#controlar-el-inventario]
* [ ] Da de alta tus [productos](/docs/rtg/pymes/inventario-y-precios/productos)
* [ ] Configura [almacenes y stock](/docs/rtg/pymes/inventario-y-precios) si tienes varias ubicaciones
### Vender en mostrador con TPV [#vender-en-mostrador-con-tpv]
* [ ] Monta tu punto de venta táctil para cobros rápidos: [TPV](/docs/rtg/tpv)
* [ ] Deja la caja lista con la [configuración del TPV](/docs/rtg/tpv/procesos/configuracion-tpv)
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Crea la cuenta y registra la empresa para empezar; el resto (impuestos, inventario, TPV) lo añades cuando lo necesites. El asistente 1Click se puede reabrir desde la configuración de Pymes.
Usa el enlace del email de invitación. Te añade a la empresa con los permisos que te haya dado el administrador, así que no registras ninguna licencia ni pasas el asistente.
No. Los cambios afectan a lo que emitas a partir de ese momento. Una factura ya emitida con un dato erróneo se corrige rectificándola, no editando la ficha.
Para asegurar que el identificador fiscal de tu empresa es correcto antes de que figure en las facturas. Dinaup lo valida contra la AEAT, tanto en el asistente como en la ficha de empresa.
Cambias de una a otra desde la barra superior, sin cerrar sesión. Dinaup recuerda en cuál estabas la última vez.
***
→ [Guía de inicio rápido](/docs/guias/guia-de-inicio-rapido)
→ [Configurar tus licencias](/docs/guias/configurar-licencias)
→ [Usuarios, roles y permisos](/docs/guias/usuarios-roles-y-permisos)
→ [Mi Empresa](/docs/rtg/pymes/mi-empresa)
# Cobra lo que te deben (/docs/guias/por-cobrar)
La pantalla **Por cobrar** reúne tus facturas de venta pendientes, las agrupa por cliente y las ordena por urgencia: lo más vencido, arriba. Ves cuánto te deben, quién y desde cuándo, y reclamas el pago desde ahí mismo.
## Antes de empezar [#antes-de-empezar]
* Necesitas acceso a la app **PyMES**.
* Las facturas de venta con importe pendiente alimentan la lista solas. No hay nada que cargar a mano.
## Abre la pantalla [#abre-la-pantalla]
Entra en la app **PyMES**.
En el menú, despliega **Ventas & Ingresos** y pulsa **Por cobrar**.
La lista se carga con todo lo pendiente. Si registras un cobro y quieres ver el cambio al momento, usa el botón **refrescar** que hay junto al título.
Cualquier factura de venta con importe pendiente aparece aquí, asociada a su cliente. En cuanto la cobras del todo, desaparece de la lista.
## Lee la salud de tus cobros [#lee-la-salud-de-tus-cobros]
Arriba hay una fila de indicadores. Cada uno te dice si hoy toca preocuparse o no.
El dinero que ya deberías haber cobrado. Si está en rojo, empieza por aquí.
Todo lo que te deben, esté vencido o no.
Lo que entra (o debería entrar) la próxima semana. Para anticiparte.
A cuánta gente le estás esperando un pago ahora mismo.
Los días que de media tardas en cobrar. Cuanto más bajo, mejor cobras.
El **DSO** (Days Sales Outstanding) es la media de días desde que emites una factura hasta que la cobras. Por debajo de 30 días va verde, entre 30 y 60 amarillo, por encima de 60 rojo: el dinero tarda demasiado en entrar. Compáralo de un mes a otro para saber si tu cobro mejora o empeora.
## Ataca primero lo más urgente [#ataca-primero-lo-más-urgente]
Debajo de los indicadores, los clientes vienen ya **ordenados por urgencia** y agrupados por antigüedad de la deuda (el *aging*). Empieza por arriba.
| Tramo | Qué significa | Cómo se marca |
| ---------------------- | -------------------------------------------------- | ------------- |
| **Vencido +60 días** | Lo más crítico. Dinero que llevas mucho esperando. | Rojo |
| **Vencido 30-59 días** | Empieza a preocupar. | Naranja |
| **Vencido 1-29 días** | Se ha pasado de fecha hace poco. | Amarillo |
| **Al día** | Pendiente, pero todavía no ha vencido. | Verde |
Cada grupo te dice cuántos clientes contiene y cuánto suman, así sabes dónde está el grueso del problema sin contar a mano.
Trabaja de arriba abajo. Un cliente en **Vencido +60 días** te cuesta dinero real, y cada día que pasa es más difícil de cobrar. Con los de **Al día** lo único que cabe hacer es anticiparte.
## Encuentra un cliente o un tramo concreto [#encuentra-un-cliente-o-un-tramo-concreto]
Cuando la lista es larga, la barra de filtros te centra:
* **Buscar cliente**: escribe el nombre y te quedas solo con ese cliente.
* **Antigüedad**: filtra por tramo de vencimiento: más de 90 días, 60-89, 30-59, 1-29, al día, o sin vencimiento.
* **Importe**: filtra por cuánto te deben: más de 10.000, entre 5.000 y 9.999, entre 1.000 y 4.999, o menos de 1.000.
Los filtros activos aparecen como **chips** debajo de la barra. Quitas uno haciendo clic en él, o pulsas el botón de limpiar para volver a verlo todo.
Combina los filtros. *Vencido +90 días* **y** *más de 10.000* te deja delante los pocos casos que más te duelen, para llamarlos uno a uno.
## Abre una factura para cobrarla [#abre-una-factura-para-cobrarla]
Cada cliente trae el detalle de sus facturas pendientes: fecha, número, vencimiento, días de retraso, cuánto se ha cobrado ya con una barra de progreso, y lo que falta.
Haz clic en cualquier **fila de factura** dentro de la tarjeta del cliente.
Se abre la **factura de venta** completa. Desde ahí registras el cobro, revisas las líneas o consultas su estado. El registro del cobro se hace en la propia factura: lo tienes en [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas).
Si una factura no tiene fecha de pago asignada, Dinaup no puede calcular su retraso: la marca con la etiqueta **Sin vencimiento** y la deja aparte del control de antigüedad. Para que entre en el aging, abre la factura y asígnale una fecha de vencimiento.
## Reclama el pago sin salir de la pantalla [#reclama-el-pago-sin-salir-de-la-pantalla]
Cada cliente tiene dos botones para reclamar la deuda desde su tarjeta.
### Por email [#por-email]
El botón **Email** abre un recordatorio de pago listo para ese cliente, partiendo de una plantilla de documento.
Si configuras tu propia plantilla de recordatorio de pago en los datos de tu empresa, se usa esa. Si no, Dinaup usa una por defecto. El aviso sale con tu tono y tu imagen.
### Por WhatsApp, con el tono adecuado [#por-whatsapp-con-el-tono-adecuado]
El botón de **WhatsApp** abre un asistente que redacta el mensaje por ti. Eliges cómo de duro quieres ser según el caso:
**Elige el tono.** Arriba ves el cliente y el total que te debe. Debajo, cuatro tonos:
| Tono | Cuándo usarlo |
| ----------- | ---------------------------------------------- |
| **Cordial** | Primer aviso, amable. |
| **Formal** | Trato de usted, profesional. |
| **Directo** | Al grano, sin rodeos. |
| **Urgente** | Deuda vencida que necesita atención inmediata. |
**Revisa la vista previa.** Cada tono muestra el mensaje tal cual le llegará al cliente, con forma de chat. Ya incluye el nombre de tu empresa, el importe total y el detalle de las facturas pendientes.
**Pulsa Enviar por WhatsApp.** Se abre WhatsApp con el mensaje ya escrito. Eliges el contacto del cliente y le das a enviar.
Si alguna de las facturas del cliente tiene **enlace de pago**, el recordatorio lo incluye. El cliente paga desde el propio mensaje.
Dinaup prepara el mensaje y abre WhatsApp, pero no manda nada solo: eliges el contacto y confirmas el envío. Mantienes el control de qué se dice y a quién.
## Anticípate a lo que vence [#anticípate-a-lo-que-vence]
El indicador **Vence en 7 días** y el tramo **Al día** son tu radar de cobros que aún no han vencido. Una rutina que funciona:
1. Cada lunes, mira **Vence en 7 días**. Es el dinero que debería entrar esa semana.
2. A los clientes de **Al día** con vencimiento cercano, mándales un recordatorio **Cordial** *antes* de que venza. Llega como un favor, no como una reclamación.
3. Lo que cruce a vencido, súbelo de tono según cuánto se pase de fecha.
Si te sale este mensaje, tienes un volumen muy alto de facturas sin cobrar, más de lo que la pantalla muestra de golpe. Trabaja primero los clientes y los tramos más vencidos para reducir el bulto.
Para el detalle exacto de cada métrica, columna y filtro, ver la [referencia de Por cobrar](/docs/rtg/pymes/por-cobrar).
# Programar peticiones HTTP (/docs/guias/programar-peticiones-http)
El servidor de Dinaup puede llamar solo a una URL cada cierto tiempo, sin que tú hagas nada. Sirve para disparar flujos externos (n8n, Make, Zapier), sincronizar con otra API tuya o hacer comprobaciones periódicas.
Para la visión general de lo que corre en segundo plano, mira → [Automatizaciones del servidor](/docs/desarrollo/automatizaciones-del-servidor).
## Antes de empezar [#antes-de-empezar]
Necesitas tres cosas:
* Acceso a la sección de peticiones HTTP programadas.
* La URL de destino ya lista.
* Si el destino requiere autenticación, el token Bearer a mano.
## Crear la petición [#crear-la-petición]
### Abre la sección de peticiones HTTP programadas [#abre-la-sección-de-peticiones-http-programadas]
Crea un nuevo registro en la sección de peticiones HTTP programadas. En el sistema, la plantilla se llama **HTTP CRON**.
¿No encuentras la sección? La habilita tu administrador. Suele vivir en el módulo de desarrollo. Si no aparece, pide acceso a quien gestiona tu cuenta.
Ponle un **Nombre** descriptivo para identificarlo en la lista.
### Define destino y método [#define-destino-y-método]
Rellena la dirección y cómo se llama:
| Campo | Qué pones |
| ---------- | --------------------------------------------------------------------------------------- |
| **URL** | La dirección completa. Debe empezar por `http` o `https`, si no, el servidor la ignora. |
| **Método** | `GET`, `POST` o `PUT`. |
El cron solo dispara la URL: no envía cuerpo ni cabeceras propias. `POST` y `PUT` salen con cuerpo vacío. Si el destino necesita datos, mételos en la propia URL como parámetros.
### Autenticación (opcional) [#autenticación-opcional]
Si el destino pide autenticación, rellena el campo **Bearer** con el token. El servidor añade la cabecera `Authorization: Bearer ` a cada llamada.
Si lo dejas vacío, la petición sale sin autenticación. Bearer es el único método soportado: no hay Basic ni cabeceras personalizadas.
### Frecuencia, días y horario [#frecuencia-días-y-horario]
Aquí controlas cada cuánto se dispara y cuándo:
| Campo | Qué controla |
| ------------------------------ | ------------------------------------------------------------------------------- |
| **Intervalo en segundos** | Cada cuánto se dispara dentro del horario. |
| **Intervalo fuera de horario** | Otro ritmo para fuera de la franja. Ej.: cada 60 s de día, cada 600 s de noche. |
| **Lunes** a **Domingo** | Días activos. Un día sin marcar usa el intervalo de fuera de horario. |
| **Hora inicio** y **Hora fin** | Definen la franja "dentro de horario". |
Si dejas **Hora inicio** u **Hora fin** vacías, ese día cuenta como dentro de horario las 24 horas. El reloj usa la zona horaria configurada en tu cuenta.
El intervalo mínimo real es 10 segundos. Si pones menos, el servidor lo sube a 10. Un intervalo de 0 o menos hace que la petición no se ejecute.
### Activa y guarda [#activa-y-guarda]
Marca la casilla **Activo** y guarda. El servidor solo considera los crons activos.
Empieza a tenerlo en cuenta casi de inmediato. La primera ejecución ocurre en cuanto le toca por su horario e intervalo.
### Revisa el resultado de cada ejecución [#revisa-el-resultado-de-cada-ejecución]
Tras cada llamada, el servidor guarda tres datos en el propio registro:
| Campo | Qué ves |
| --------------------------- | ------------------------------------------- |
| **Última ejecución** | Fecha y hora de la última llamada (en UTC). |
| **Último código de estado** | El código HTTP real: `200`, `404`, `500`... |
| **Última duración** | Cuánto tardó, en milisegundos. |
Úsalos para diagnosticar:
| Código | Qué significa |
| ------------- | ----------------------------------------------- |
| `2xx` | Todo correcto. |
| `401` / `403` | Revisa el Bearer. |
| `-1` | Error de red o timeout: el destino no responde. |
Cada llamada tiene un límite de 30 segundos. Si lo supera, se registra como `-1`.
## Una sola ejecución con varios servidores [#una-sola-ejecución-con-varios-servidores]
Aunque tu cuenta tenga varios servidores, cada petición se dispara una sola vez, no se duplica. El detalle está en → [Automatizaciones del servidor](/docs/desarrollo/automatizaciones-del-servidor).
## Relacionado [#relacionado]
* → [Automatizaciones del servidor](/docs/desarrollo/automatizaciones-del-servidor): todo lo que Dinaup ejecuta en segundo plano.
* → [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n): el destino típico de un cron saliente.
* → [Webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes): la alternativa: aquí tú preguntas cada X; con un webhook, Dinaup te avisa cuando algo cambia.
* → [Conectar una integración](/docs/guias/conectar-una-integracion): pasos generales para enlazar Dinaup con otra herramienta.
# RTG vs Flex: qué elijo para mi empresa (/docs/guias/rtg-vs-flex)
La respuesta corta: **casi todo el mundo empieza por Ready To Go**, y recurre a Flex solo cuando un proceso suyo no encaja en lo estándar. Y no es una decisión cerrada: lo uno está construido sobre lo otro.
## El árbol de decisión [#el-árbol-de-decisión]
* ¿Tu negocio es **estándar** (facturas, stock, equipo, clientes)? → **Ready To Go**, a trabajar hoy.
* ¿Tienes un **proceso único** que ningún ERP cubre? → **Flex**, lo modelas a tu medida.
* ¿No lo sabes? → empieza por **Ready To Go**. Flex sigue ahí debajo cuando lo necesites.
## Negocio estándar → Ready To Go [#negocio-estándar--ready-to-go]
Los módulos Ready To Go (Pymes, TPV, CRM, RRHH, Proyectos) cubren las necesidades habituales de cualquier empresa. Se activan y funcionan desde el primer día (la facturación solo pide una configuración fiscal mínima).
→ [Ready To Go: lo estándar listo para usar](/docs/guias/rtg)
## Proceso único → Flex [#proceso-único--flex]
Cuando lo estándar no cubre una necesidad concreta, **Dinaup Flex** te deja crear secciones (tablas de datos) con campos, fórmulas, validaciones, informes y automatizaciones, sin programar y sobre una base de datos real (PostgreSQL).
→ [¿Qué es Dinaup?](/docs/rtg/que-es-dinaup)
## El dato clave: RTG está construido sobre Flex [#el-dato-clave-rtg-está-construido-sobre-flex]
Esto es lo que cambia la decisión: los módulos Ready To Go **no son otra cosa** que secciones Flex ya diseñadas y optimizadas. Un usuario avanzado puede modificar cualquier sección del sistema o crear secciones nuevas junto a las estándar.
No eliges "RTG o Flex" como dos productos distintos. Eliges empezar con lo ya montado y personalizar encima cuando haga falta. Misma plataforma, mismos datos.
## ¿Y si empiezo en uno y luego quiero el otro? [#y-si-empiezo-en-uno-y-luego-quiero-el-otro]
No pasa nada: es el camino normal. Empiezas con Ready To Go para facturar ya, y el día que un proceso se te queda corto lo personalizas con Flex **sin migrar nada**. No cambias de sistema ni vuelves a empezar.
## Sigue por aquí [#sigue-por-aquí]
* [Ready To Go](/docs/guias/rtg): lo estándar listo para usar.
* [¿Qué es Dinaup?](/docs/rtg/que-es-dinaup): la visión completa de la plataforma.
# Ready To Go: lo estándar listo para usar (/docs/guias/rtg)
Dinaup trae módulos **Ready To Go**: soluciones ya diseñadas que activas y empiezas a usar el mismo día. No se compran por separado ni hay que conectarlas entre ellas: viven en la misma plataforma y comparten tus datos.
## Todo lo que necesitas, ya montado [#todo-lo-que-necesitas-ya-montado]
Ventas, compras, presupuestos y tus libros, al día y con cumplimiento fiscal.
Productos, stock por almacén, lotes, pedidos y reposición.
Cobros en mostrador, gestión de cajas y cierres diarios.
Fichajes, control horario, turnos, vacaciones y nóminas.
Tareas y trabajo del equipo en tablero Kanban configurable.
Oportunidades, seguimientos y fidelización, con ayuda de IA.
Activas los que te hacen falta hoy; los demás siguen ahí para cuando los necesites.
## Cumple con la ley por ti [#cumple-con-la-ley-por-ti]
Lo que da más respeto ya viene resuelto, sin que tengas que entender la letra pequeña:
* **Verifactu**: cada factura se emite con su huella encadenada, su QR y su firma, según marca el Reglamento. Tú facturas con normalidad.
* **Registro horario**: los fichajes quedan guardados de forma que aguantan una inspección.
* **Libros y modelos**: tus libros de ventas y compras se mantienen solos a partir de lo que facturas.
## Conéctalo con lo que ya usas [#conéctalo-con-lo-que-ya-usas]
Dinaup no es una isla. Puede hablar con otros programas para que las cosas pasen solas:
* Emails automáticos al entrar una venta o vencer un cobro.
* Avisos por WhatsApp a un cliente o a tu equipo.
* Conexión con miles de apps vía Zapier, Make o n8n, sin programar.
* Una **API REST** y un **SDK .NET** para automatizar lo que quieras.
## Construido sobre Flex: creces sin migrar [#construido-sobre-flex-creces-sin-migrar]
Los módulos Ready To Go están construidos sobre **Dinaup Flex**. Significa que el día que necesites algo a medida (un proceso propio, un campo que no existe, una pantalla para tus clientes) lo personalizas sobre lo que ya tienes. No cambias de programa, no migras tus datos, no empiezas de cero.
## Sigue por aquí [#sigue-por-aquí]
* [¿Qué es Dinaup?](/docs/rtg/que-es-dinaup): la visión completa: Ready To Go y Flex.
* [RTG vs Flex: qué elijo](/docs/guias/rtg-vs-flex). El árbol de decisión.
* [Documentación de Pymes](/docs/rtg/pymes), [TPV](/docs/rtg/tpv), [CRM](/docs/rtg/crm), [RRHH](/docs/rtg/recursos-humanos) y [Proyectos](/docs/rtg/proyectos).
# SDK .NET y API (/docs/guias/sdk-api)
El SDK .NET te da modelos fuertemente tipados, generados a partir de tu estructura, para operar Dinaup desde C#. Esta página es un recetario: copia el bloque que necesitas.
## Antes de empezar [#antes-de-empezar]
* **Instala los dos paquetes NuGet.** El base más el modelo tipado de tu organización:
```bash
dotnet add package Dinaup
dotnet add package Demoup.MyDinaup
```
`Dinaup` trae el cliente (conexión, informes, archivos, anotaciones, WriteOperations). El paquete [`*.MyDinaup`](/docs/desarrollo/dotnet/mydinaup) trae las clases con los nombres reales de tus secciones (`APIVentasC`, `ProductosES`, etc.), generadas a partir de tu esquema. Para un modelo neutro válido en varias empresas, usa `ReadyToGo.MyDinaup` en su lugar.
* **Añade los `using`:**
```csharp
using Dinaup; // cliente, WriteOperation, VaultData
using DemoUp.MyDinaup.Reports.FuncionalidadD; // informes tipados de tu modelo
```
Las clases de informe (`API…C`) y de sección (`…ES`) viven en el espacio de nombres de tu paquete `MyDinaup`, ajusta la categoría (`VentasD`, `ImpuestosD`…) a la sección que uses.
* **Consigue las tres credenciales.** `ConnectAsync` pide `endPoint`, `publicKey` y `secretKey`. Salen de una **clave API** que creas en Dinaup, vinculada a un usuario: la clave hereda sus permisos. El `endPoint` es `https://api.dinaup.com/v2/{tu-codigo}`. Crea un usuario específico para la integración y dale acceso solo a las secciones que toca.
Cómo crear la clave: [Claves API](/docs/cuenta/claves-api).
La clave secreta solo se muestra una vez. Guárdala en un gestor de secretos o en el Vault, nunca en el JavaScript de una web.
## Conecta [#conecta]
Conexión directa con las tres credenciales:
```csharp
var client = await DinaupClientC.ConnectAsync(
endPoint: "https://api.dinaup.com/v2/tu-codigo",
publicKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
secretKey: "tu-secret-key-aqui"
);
```
Con **Vault**, las únicas credenciales que pones en variables de entorno son las del propio Vault, el resto vive cifrado dentro:
```csharp
var vault = new VaultData(
Environment.GetEnvironmentVariable("VAULT_URL"),
Environment.GetEnvironmentVariable("VAULT_PASSWORD")
);
vault.Initialize();
var client = await DinaupClientC.ConnectAsync(
endPoint: vault.Read("dinaup.endpoint"),
publicKey: vault.Read("dinaup.publickey"),
secretKey: vault.Read("dinaup.secretkey")
);
```
Registrando el cliente como Singleton en inyección de dependencias:
```csharp
var builder = WebApplication.CreateBuilder(args);
var vault = new VaultData(
Environment.GetEnvironmentVariable("VAULT_URL"),
Environment.GetEnvironmentVariable("VAULT_PASSWORD")
);
vault.Initialize();
var client = await DinaupClientC.ConnectAsync(
endPoint: vault.Read("dinaup.endpoint"),
publicKey: vault.Read("dinaup.publickey"),
secretKey: vault.Read("dinaup.secretkey")
);
builder.Services.AddSingleton(client);
var app = builder.Build();
```
## Lee [#lee]
Ejecutar un informe y recorrer sus filas:
```csharp
var report = new APIVentasC();
await report.ExecuteQueryAsync(client);
foreach (var row in report.Rows)
{
Console.WriteLine($"{row.Factura}: {row.Total}");
}
```
Filtrar y ordenar:
```csharp
var report = new APIVentasC();
report.AddFilterBetween(VentasES.Fecha, inicioMes, finMes);
report.AddFilter(VentasES.Estado, "=", EstadoE.Completada.INT());
report.AddOrder(VentasES.Total, descending: true);
await report.ExecuteQueryAsync(client);
foreach (var row in report.Rows)
{
Console.WriteLine($"{row.Numero}: {row.Total}€");
}
```
Recorrer todas las páginas de resultados:
```csharp
var report = new APIProductosC();
await report.ExecuteQueryAsync(client);
if (report.Rows.IsNotEmpty())
{
do
{
foreach (var row in report.Rows)
{
// Procesar cada registro
}
} while (await report.ExecuteQuery_NextPageAsync());
}
```
## Agrega [#agrega]
Alta individual con `WriteOperation` (`Guid.Empty` indica alta nueva):
```csharp
var producto = new WriteOperation(Guid.Empty, new()
{
{ ProductosES.Nombre, "iPhone 16 Pro" },
{ ProductosES.Precio, 1199.00m.STR() }
});
client.RunWriteOperation(ProductosES._SectionID, producto);
```
Importar en lote por bloques. `MaxItemsPerWriteOperation` es el tope por llamada (25), parte la lista con `.Chunk(...)`:
```csharp
var externos = await http.GetFromJsonAsync>(url);
var chunks = externos.Chunk(DinaupClientC.MaxItemsPerWriteOperation);
foreach (var chunk in chunks)
{
var lote = chunk.Select(e => new WriteOperation(Guid.Empty, new()
{
{ ProductosES.CodigoExterno, e.SKU },
{ ProductosES.Nombre, e.Nombre },
{ ProductosES.Precio, e.Precio.STR() }
})).ToList();
client.RunWriteOperation(ProductosES._SectionID, lote, false);
}
```
## Edita [#edita]
Editar un registro pasando su ID:
```csharp
var cambios = new WriteOperation(productoId, new()
{
{ ProductosES.Precio, 999.00m.STR() }
});
client.RunWriteOperation(ProductosES._SectionID, cambios);
```
Actualizar precios en lote:
```csharp
var cambios = productosIds.Select(id => new WriteOperation(id, new()
{
{ ProductosES.Precio, nuevoPrecio.STR() },
{ ProductosES.FechaActualizacion, DateTime.Now.STR() }
})).ToList();
client.RunWriteOperation(ProductosES._SectionID, cambios, false);
```
## Factura [#factura]
Cabecera con líneas en una sola llamada:
```csharp
var factura = new WriteOperation(Guid.Empty, new()
{
{ FacturasES.Numero, "F-2024-0042" },
{ FacturasES.ClienteID, clienteId.STR() },
{ FacturasES.Fecha, DateTime.Now.STR() }
});
var lineas = new List
{
new(Guid.Empty, new() {
{ LineasES.Descripcion, "Consultoría" },
{ LineasES.Cantidad, 10.STR() },
{ LineasES.Precio, 80m.STR() }
}),
new(Guid.Empty, new() {
{ LineasES.Descripcion, "Desarrollo" },
{ LineasES.Cantidad, 25.STR() },
{ LineasES.Precio, 60m.STR() }
})
};
client.RunWriteOperation(FacturasES._SectionID, factura, lineas);
```
## Archivos [#archivos]
Subir desde un array de bytes:
```csharp
var bytes = System.Text.Encoding.UTF8.GetBytes("contenido del archivo");
var upload = await client.File_UploadBytesAsync(bytes, "documento.txt");
Guid fileId = upload.FileId;
```
Subir desde una URL externa:
```csharp
var upload = await client.File_UploadURLAsync(
"https://ejemplo.com/imagen.png",
"imagen.png"
);
Guid fileId = upload.FileId;
```
Obtener una URL firmada para lectura:
```csharp
var signed = await client.File_SignURLGetAsync(fileId);
var url = signed.url_original;
```
## Anotaciones [#anotaciones]
Agregar un comentario de solo texto:
```csharp
var params = new AnotationParameters(sectionId, rowId, AnnotationTypeE.Comments)
.WithText("¡Hola! Este es mi comentario.");
await client.Annotation_PutAsync(params);
```
Comentario con archivo adjunto:
```csharp
var upload = await client.File_UploadBytesAsync(bytes, "documento.pdf");
var params = new AnotationParameters(sectionId, rowId, AnnotationTypeE.Comments)
.WithText("Adjunto el contrato firmado")
.WithFile(upload.FileId);
await client.Annotation_PutAsync(params);
```
Leer las anotaciones de un registro:
```csharp
var resultado = await client.Annotations_GetAsync(
sectionId,
rowId,
AnnotationTypeE.Comments
);
foreach (var anotacion in resultado.Annotations)
{
var texto = anotacion.Text;
var adjuntos = anotacion.AttachedFiles;
}
```
## Documentos dinámicos [#documentos-dinámicos]
Generar el HTML de una factura:
```csharp
var doc = new DynamicDocuments.PaginasInformesD.FacturaModernaC(ventaId);
var response = await doc.ExecuteAsync(client);
var html = response.Content;
```
## Patrones [#patrones]
Servicio con inyección de dependencias:
```csharp
public class ProductosService(DinaupClientC client)
{
public async Task> GetProductosAsync()
{
var report = new APIProductosC();
await report.ExecuteQueryAsync(client);
return report.Rows;
}
public void AddProducto(string nombre, decimal precio)
{
var op = new WriteOperation(Guid.Empty, new() {
{ ProductosES.Nombre, nombre },
{ ProductosES.Precio, precio.STR() }
});
client.RunWriteOperation(ProductosES._SectionID, op);
}
}
```
Sincronizar desde una API externa, mismo método para crear y para actualizar (ID vacío crea, ID existente actualiza):
```csharp
public async Task SyncProductosAsync(List externos)
{
var operaciones = externos.Select(e => new WriteOperation(
e.DinaupId ?? Guid.Empty,
new() {
{ ProductosES.CodigoExterno, e.SKU },
{ ProductosES.Nombre, e.Nombre },
{ ProductosES.Precio, e.Precio.STR() }
})).ToList();
client.RunWriteOperation(ProductosES._SectionID, operaciones, false);
}
```
Worker en segundo plano para procesar tareas pendientes:
```csharp
public class TareasWorker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (ct.IsCancellationRequested == false)
{
var pendientes = await GetPendientesAsync();
foreach (var tarea in pendientes)
await ProcesarAsync(tarea);
await Task.Delay(TimeSpan.FromMinutes(5), ct);
}
}
}
```
## Avanzado [#avanzado]
Búsqueda libre, filtro IN, OR implícito, filtros por relaciones encadenadas y solapamiento de fechas:
```csharp
// Búsqueda de texto libre
report.QuerySearch = "iPhone Pro Max";
// Filtro IN (múltiples valores)
report.AddFilter(ProductosES.CategoriaId, new[] { categoria1Id, categoria2Id });
// OR implícito: mismo campo, varias llamadas → devuelve ES e IT
report.AddFilter(PaisesES.Codigo, "=", "ES");
report.AddFilter(PaisesES.Codigo, "=", "IT");
// Filtro por relaciones encadenadas
var keyPath = $"{PedidosES._SectionID}.{PedidosES.ClienteId}.{ClientesD._SectionID}.{ClientesES.VIP}";
report.AddFilter(keyPath, "=", 1);
// Solapamiento de rangos de fechas
report.AddFilterDateRangeOverlapFilter(
EventosES.FechaInicio, EventosES.FechaFin,
rangeStart: new DateOnly(2024, 1, 1),
rangeEnd: new DateOnly(2024, 12, 31)
);
// Incluir eliminados
report.AddFilter(ProductosES.Eliminado, "<>", -1); // Todos
```
Escritura avanzada: `DynamicSelector` para resolver una relación por texto, editar por campo alternativo, actualizar un solo campo, limpiar una relación y leer el resultado:
```csharp
// DynamicSelector: busca la relación por un campo de texto
var op = new WriteOperation(Guid.Empty, new() {
{ ProductosES.Nombre, "Mi producto" },
{ ProductosES.UnidadMedidaID, $"[{UnidadesMedidaES.TextoPrincipal}=Litros]" }
});
// Editar por campo alternativo (ej. SKU)
client.RunWriteOperation(
ProductosD._SectionIDGUID, op,
runScripts: false,
identifierFieldKey: ProductosES.CodigoExterno
);
// Actualizar un solo campo
await client.RunInlineWriteOperationAsync(
ProductosD._SectionIDGUID, productoId,
ProductosES.Precio, 1299.00m.STR()
);
// Limpiar una relación con string vacío
valores.Add(ProductosES.ClienteID, "");
// Leer el resultado
op.WriteOperationResult.RowID // Guid del registro
op.WriteOperationResult.Confirmed // bool
op.WriteOperationResult.AError // string (si hay error)
```
Relaciones, variables de informe y propiedades del informe:
```csharp
// Cabecera + líneas en una llamada
var factura = await FacturasD.GetRowByIdWithListAsync(client, facturaId);
Console.WriteLine($"Factura: {factura.MainRow.Numero}");
foreach (var linea in factura.ListRows) { }
// GetRowsAsync con labels de relaciones
var productos = await ProductosD.GetRowsAsync(client, params);
foreach (var p in productos)
{
Console.WriteLine($"{p.TextoPrincipal}: {p.ReferenciaCliente.Label}");
}
// Variables de informe
var report = new VentasPorClienteC();
report.AddVariable("ClienteId", clienteId.ToString());
report.AddVariable("FechaDesde", "2024-01-01");
// Propiedades del informe
report.Rows // List
report.RowsDic // Dictionary
report.TotalResults // int
report.ExistNextPage // bool
```
Utilidades: verificar conexión, conexión síncrona, conversión de enums, deduplicación por SHA1 y propiedades de archivo:
```csharp
// Verificar conexión
if (client.IsConnected) { /* OK */ }
// Connect síncrono (alternativa a ConnectAsync)
var client = DinaupClientC.Connect(endpoint, publicKey, secretKey);
// Conversión de enums
{ FacturasES.Estado, EstadoFacturaE.Borrador.INT().STR() }
// Deduplicación con SHA1
string sha1 = Dinaup.extensions.ToSHA1(contenido);
// URL firmada con parámetros
var url = await client.File_SignURLGetAsync(fileId, cachear: false);
// Propiedades de archivo subido
upload.FileData.Id // Guid
upload.FileData.CRC // SHA1
upload.FileData.IsImage // bool
upload.FileData.url_1080 // Redimensionado
```
Ejecutar como un usuario concreto. Afecta al autor del alta, al histórico, a las anotaciones y a los filtros de sesión:
```csharp
// Solo userId
using (DinaupContext.WithUser(userId))
{
client.RunWriteOperation(...);
}
// Con IP
using (DinaupContext.WithUser(userId, "192.168.1.1"))
{
client.RunWriteOperation(...);
}
// Con IP y UserAgent
using (DinaupContext.WithUser(userId, "192.168.1.1", "Mozilla/5.0..."))
{
client.RunWriteOperation(...);
}
```
## Otras formas de conectar [#otras-formas-de-conectar]
Si no programas en .NET o no quieres el SDK, Dinaup expone los mismos datos por otros canales:
| Quieres… | Canal | Dónde |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| Probar una petición sin escribir código | Zona de pruebas dentro de Dinaup: eliges qué pedir, pulsas y ves la respuesta | Panel de Dinaup |
| Que Dinaup avise a otro programa cuando entra un pedido o cambia una ficha | Webhooks salientes: eliges qué vigilar y a dónde enviarlo, con botón de prueba | [Integraciones](/docs/desarrollo/integraciones) |
| Reaccionar a miles de cambios casi al instante | Eventos Redis, el mismo aviso por un canal más rápido | [Eventos Redis](/docs/desarrollo/integraciones/eventos-redis) |
| Que otro programa empuje datos a Dinaup sin programar | Webhooks entrantes con Zapier, Make o n8n | [Zapier, Make y n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n) |
| Usar la API desde cualquier lenguaje | API HTTP, sin el SDK | [Integraciones](/docs/desarrollo/integraciones) |
| Pedir datos en lenguaje natural | Consulta con IA, Dinaup arma la query | [IA](/docs/guias/ia) |
Para el detalle de cada clase, método y propiedad, ver [Desarrollo · Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
# Stock: lo esencial (/docs/guias/stock-lo-esencial)
Vendes y el stock baja solo. Si te equivocas, lo corriges con una **devolución**, sin tocar la venta original.
## El recorrido [#el-recorrido]
## Vender: baja al instante [#vender-baja-al-instante]
* Cobras y el producto sale del inventario en ese mismo momento.
* No tienes que confirmar nada después: la venta ya descuenta.
* Si un producto **no lleva control de stock**, no se mueve nada. Es a propósito.
## ¿Te equivocaste? No edites, devuelve [#te-equivocaste-no-edites-devuelve]
Para corregir cualquier error de cantidad, haz una devolución. Así todo queda cuadrado.
**Regla de oro:** vendiste 10 y eran 8 → haz una **devolución de 2**. La venta original queda intacta y el stock se reajusta solo.
## Dos números: lo que puedes vender y lo que tienes [#dos-números-lo-que-puedes-vender-y-lo-que-tienes]
A lo largo del inventario verás dos cantidades para el mismo producto:
* **Lo que puedes vender** (disponible): lo que te queda libre para seguir vendiendo en el mostrador.
* **Lo que tienes guardado** (físico): lo que hay de verdad en la estantería o el almacén.
En el día a día van iguales. Empiezan a diferenciarse cuando reservas algo o pones algo "en revisión": eso ya es terreno de la guía avanzada.
## Qué pasa cuando… [#qué-pasa-cuando]
| Situación | Qué pasa |
| ----------------------------------------------- | ------------------------------------------------------------------------------- |
| Vendes en el mostrador y el cliente se lo lleva | El stock baja al instante, sin pasos extra. |
| Vendiste 10 por error y eran 8 | No editas nada: devolución de 2 y el stock se reajusta solo. |
| Un cliente devuelve un producto | Suma de vuelta al stock, pero pasa por una revisión antes de volver a venderse. |
| El producto no lleva control de stock | No se mueve nada. Es normal. |
| Se corta a media venta (luz, conexión) | No se pierde nada y no se descuenta dos veces. |
## Cuando se te quede pequeña esta guía [#cuando-se-te-quede-pequeña-esta-guía]
El sistema también sabe:
* Trabajar con **lotes** y fechas de **caducidad**.
* Vender hoy y entregar más tarde (**reservar**).
* Vender en **kilos** controlando en **gramos**.
* Tener **varios almacenes**.
👉 [Cómo funciona el stock](/docs/guias/como-funciona-el-stock): el modelo completo, con lotes, reservas, devoluciones y multi-almacén.
***
→ [Montar tu inventario](/docs/guias/montar-tu-inventario)
→ [Cómo funciona el stock](/docs/guias/como-funciona-el-stock)
# Dinaup Terminal (/docs/guias/terminal)
Con Terminal creas las tablas y campos de tu negocio, les pones cálculos e informes, y lo empaquetas todo como un módulo para instalarlo donde quieras. Es para gente técnica (informáticos, desarrolladores, partners), no para quien factura o vende: eso se hace desde la web.
## Antes de empezar [#antes-de-empezar]
* **Licencia Flex activa.** Sin ella abres el programa, pero no editas la estructura.
* **Un entorno de pruebas.** Lo que tocas afecta a todos los usuarios de la cuenta. No practiques en el de un cliente real.
## Instalar [#instalar]
Es un único programa para Windows. Se instala en tu usuario (sin permisos de administrador) y se actualiza solo.
La forma recomendada es **winget**:
```bash
winget install Dinaup.CLI
```
¿Sin winget? Descárgalo a mano: [Descargar Dinaup Terminal](https://dinaupcdn.com/dl/latest/DinaupLauncher.exe). El archivo es el *launcher* (`DinaupLauncher.exe`): trae la versión correcta y abre el programa. La primera vez te pide los datos de conexión.
## Conecta [#conecta]
El launcher se instala como un comando: `dl`.
**Abre Dinaup Terminal** una vez instalado.
**Inicia sesión:** ejecuta `dl login`. Te pide un alias, tu usuario y tu clave, y coge tu licencia.
**Abre Dinaup:** con `dl` a secas entras con esa licencia.
Hay más comandos (guardar otra licencia, limpiar, actualizar…); para el día a día basta con `dl login` y `dl`.
Según quién entra, hay tres papeles:
| Papel | Acceso |
| ------------- | --------------------- |
| Administrador | Total. |
| Desarrollador | Configurar y adaptar. |
| Lectura | Solo consultar. |
## Qué puedes construir [#qué-puedes-construir]
Diseñas el negocio pieza a pieza, sin escribir una aplicación entera:
Las "tablas" de tu negocio: vehículos, expedientes, fincas… lo que sea.
Las columnas de cada tabla, con su tipo, su papel y sus validaciones.
Cálculos automáticos: totales, estados que se rellenan solos, reglas.
Listados a medida y plantillas de documentos que se generan solas.
Cada cosa que creas aparece sola en el panel de gestión (formularios, listados, permisos) sin programar la pantalla.
## Módulos y canales [#módulos-y-canales]
Cuando tienes algo montado, lo empaquetas en un **módulo**: un paquete con versión que junta secciones, campos y algoritmos. Vive en una galería compartida, y cualquier licencia compatible lo instala desde ahí.
Cada versión va por un **canal**, según lo madura que esté:
| Canal | Estado | Para |
| ---------- | -------------------- | --------------------------- |
| Desarrollo | En construcción. | Ti, mientras lo montas. |
| Beta | En validación. | Probar antes de publicarlo. |
| Producción | Estable ("release"). | Clientes de verdad. |
Una licencia de producción no puede instalar versiones a medio hacer: el selector queda bloqueado. El núcleo de Dinaup se actualiza a la versión vigente de su canal sin reinstalar nada. Al publicar, Terminal revisa las dependencias y te recomienda empezar en Desarrollo e ir promocionando a Beta y Producción.
## Seguir [#seguir]
Para crear tu propia app sobre estos datos, mira el [SDK .NET y API](/docs/guias/sdk-api) y [DinaZen](/docs/guias/dinazen).
# El TPV de principio a fin (/docs/guias/tpv)
Un turno tiene cuatro tramos: caja, venta, cobro y cierre. Van aquí seguidos, en el orden real del mostrador.
## Antes de empezar [#antes-de-empezar]
* El TPV es una de las apps de **play.dinaup.com**: entra con tu cuenta.
* Necesitas el **tipo de venta predeterminado** configurado en Empresa (impuestos y numeración del ticket).
* Si buscas la referencia de cada pantalla y opción, está en [TPV](/docs/rtg/tpv).
## Lo primero: vincula una caja a este navegador [#lo-primero-vincula-una-caja-a-este-navegador]
La caja es el cajón de dinero. En Dinaup una caja vive en la empresa, pero **cada navegador** (cada puesto) tiene que decir con qué caja trabaja. Hasta que no lo hagas, el TPV te lo recuerda con un aviso y no te deja cobrar.
Entra en la app **TPV** y, si no hay caja vinculada, verás el aviso **"Este navegador no esta vinculado a ninguna caja"**.
Si todavía no existe ninguna caja, el aviso te lleva a crearla en **Cajas → Cajas** (botón **Configurar cajas**). En la ficha de la caja asígnale una **cuenta bancaria**: es lo que hace que, al cobrar con tarjeta, el dinero se registre en la cuenta correcta.
Vuelve al aviso y pulsa **Vincular**. Si solo hay una caja, el botón ya trae su nombre; si hay varias, eliges cuál en el desplegable. A partir de ahí este navegador queda asociado a esa caja.
Si abres el TPV en otra tablet o en otro PC, tendrás que volver a vincular ahí la caja que corresponda a ese puesto. Es lo que permite que dos puestos del mismo local trabajen con cajones distintos.
## Arranca el punto de venta [#arranca-el-punto-de-venta]
Con la caja vinculada, abres el TPV de venta de dos formas:
El botón
**Iniciar**
abre la venta en una ventana sobre la app, sin perder el menú lateral.
**Iniciar Pantalla Completa**
entra en modo POS a pantalla entera, ideal para mostrador o barra. Sales con el botón
**Salir**
o con la tecla
**Esc**
.
Lo que arranca por defecto (venta, pedido o presupuesto) depende de la configuración de la empresa. Desde el menú lateral puedes lanzar cada uno por separado en **Ventas → Ventas / Pedidos / Presupuestos**.
Si al pulsar **Iniciar** Dinaup te avisa de *"Configura el tipo de venta predeterminado"*, ve a la configuración de Empresa y elige el tipo de venta que usará el TPV. Sin él, el punto de venta no sabe con qué impuestos y numeración trabajar.
## Monta la venta [#monta-la-venta]
Ya dentro, la pantalla tiene una cabecera (cliente, tipo, fecha…), la lista de líneas y el pie con los botones de acción. El recorrido es siempre el mismo:
### Elige el cliente [#elige-el-cliente]
En la cabecera, en el selector de cliente. Puedes dejar el **genérico** para un ticket anónimo de mostrador, o buscar un **cliente registrado** por nombre para que traiga sus datos fiscales y su tarifa. Si no existe, puedes darlo de alta desde ahí mismo (el botón **+** del selector).
### Añade los productos [#añade-los-productos]
Usa el buscador **"¿Qué desea Vender?"**: escribe parte del nombre o el código y selecciona. Si tu catálogo está organizado por categorías con imagen, vendes tocando la pantalla sin teclear. Cada producto que añades es una línea editable.
### Ajusta cada línea [#ajusta-cada-línea]
Sobre la línea cambias **cantidad**, **precio** y **descuento**, o la eliminas. Revisa que las unidades y los importes cuadran antes de cobrar. El total se actualiza solo en la cabecera.
### Comprueba el estado y la fecha [#comprueba-el-estado-y-la-fecha]
En la cabecera tienes el **estado** de la venta y la **fecha** del documento. Junto a ellos, una pastilla de validación te avisa en verde, ámbar o rojo de si algo bloquea el cobro (datos fiscales incompletos, stock, etc.).
Si vas a vender por encima de lo disponible en tu almacén, el TPV te lo señala, pero no te corta la venta: tú decides. La baja de stock se aplica al cobrar. Para descuentos por línea, globales y de cliente VIP, tienes [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida).
## Cobra [#cobra]
Con la venta montada, pulsa **Cobrar** en el pie. Si la pastilla de validación está en rojo, el botón abre primero el detalle de lo que falta; si está en verde, abre directamente la pantalla de cobro. Eliges entre dos formas de pago:
Tecleas el dinero que te da el cliente y Dinaup calcula el
**cambio**
a devolver. Ese efectivo se suma a la caja del puesto.
Procesas el pago en el datáfono y confirmas. El importe se anota contra la
**cuenta bancaria**
, no contra la caja.
En efectivo, la pantalla te marca el estado del pago: mientras el recibido no llega al total, una insignia roja parpadea con **"Falta por cobrar"**; cuando lo supera, te muestra el **cambio** a devolver; y cuando es exacto, un **"Perfecto"** en verde.
* **Finalizar** cierra la venta con los datos que has tecleado.
* **Automático** (solo en efectivo) cobra el importe exacto, imprime el ticket y te deja listo para la siguiente venta sin confirmar nada. Si lo recibido es menor que el total, Dinaup no te deja finalizar y avisa de *"Falta por cobrar"*: evita cerrar tickets a medio cobrar por un despiste con el teclado.
Tras cobrar se imprime (o se reimprime desde el histórico) el **ticket**. Para las formas de pago menos directas (pago mixto, link de pago, cobro parcial dejando saldo pendiente) y para convertir un ticket en factura simplificada, el detalle está en [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro).
## DataFlow: cobro, stock y devolución en un panel [#dataflow-cobro-stock-y-devolución-en-un-panel]
No todo se cobra de un golpe sobre el mostrador. Para una venta a crédito, un pedido que se sirve por partes o una devolución, tienes el **Flujo** (DataFlow): un panel que reúne en un solo sitio el dinero y el inventario de una operación.
Lo abres con el botón **Flujo** del pie de la venta. Ahí ves tarjetas con su distintivo de estado:
| Tarjeta | Para qué |
| ---------------------- | ---------------------------------------------------------------------------------------- |
| **Cobro** | Total, cobrado y pendiente. Registras cobros parciales eligiendo caja o cuenta bancaria. |
| **Salidas / Entradas** | Mueves el stock contra un lote y un almacén, con su pendiente y su historial. |
| **Devolución** | Generas la rectificativa sin volver a teclear cliente ni productos. |
Si una tarjeta está en verde (**Completado**), la operación está cerrada por ese lado; si ves un **Pendiente**, ahí tienes trabajo. El recorrido completo de cada tarjeta está en [DataFlow](/docs/rtg/tpv/dataflow).
Primero registras la venta, compra, pedido o presupuesto; después abres su Flujo para cobrarla, mover el stock y gestionar devoluciones. No crea la operación, la completa.
## Cierra el turno cuadrado [#cierra-el-turno-cuadrado]
Al final del turno haces el **cierre de caja**: cuentas el dinero real y Dinaup lo compara con lo que debería haber.
En el menú del TPV, entra en **Cajas → Cierres de Caja** y pulsa **+ NUEVO**.
Elige el **depósito** que cierras (la caja de efectivo o la cuenta bancaria), el **rango de fechas** del turno y el **responsable** del dinero.
Pulsa **Recalcular** para que sume todas las entradas, salidas, cobros y pagos del periodo. Revisa saldo inicial y final, total de entradas y salidas.
Escribe el **importe confirmado** (el dinero que has contado físicamente) y Dinaup calcula la **diferencia**. Si hay descuadre, lo ves antes de guardar.
Pulsa **Guardar** para confirmar el cierre.
El efectivo entra en la caja y la tarjeta va a la cuenta bancaria. Si en el mismo puesto cobras de las dos maneras, haces **un cierre por la caja** (cuentas los billetes) y **otro por la cuenta bancaria** (la tarjeta y los links). Mezclarlos en uno solo es lo que hace que "no cuadre".
El detalle de todos los campos está en [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja).
## El recorrido de un turno [#el-recorrido-de-un-turno]
Una vez por puesto. Con su cuenta bancaria para la tarjeta.
Cliente, productos, cantidades y descuentos.
Efectivo (con cambio) o tarjeta, con su ticket.
Cuenta el dinero y cuadra. Un cierre por depósito.
Cada venta baja stock del [inventario](/docs/guias/montar-tu-inventario), queda asociada al cliente y genera su asiento contable sola. Y el efectivo del cierre se vuelca a tu caja de tesorería. No tecleas el mismo dato dos veces.
# Usuarios, roles y permisos (/docs/guias/usuarios-roles-y-permisos)
Dar acceso a una persona tiene cinco partes: invitarla, elegir su nivel, abrir los módulos que use, afinar con roles y, llegado el momento, darla de baja.
El trabajo se reparte en dos sitios. La gestión de usuarios (invitar, nivel, permisos de app, baja) va en la web, [dinaup.com](https://dinaup.com). La configuración fina (roles, diseños de sección, menús) va en **Dinaup Desktop**. Cada paso indica dónde toca.
## Antes de empezar [#antes-de-empezar]
* Una cuenta de **administrador**, o el permiso **Administrar usuarios**.
* Una **licencia libre** en tu suscripción para cada persona nueva.
* Para los pasos de roles y diseños: **Dinaup Desktop** instalado.
***
## El recorrido completo [#el-recorrido-completo]
### Invita al usuario por email [#invita-al-usuario-por-email]
Entra en [dinaup.com](https://dinaup.com) con una cuenta de administrador y ve al panel de **Gestión de usuarios**. Añade a la persona con su correo electrónico. Recibirá una invitación para unirse a tu empresa en Dinaup.
### Elige su nivel de acceso [#elige-su-nivel-de-acceso]
El **nivel** define el alcance general de lo que la persona puede hacer:
| Nivel | Para quién |
| ----------------- | ------------------------------------------------------------------- |
| **Administrador** | Acceso total a la cuenta. Resérvalo para responsables de confianza. |
| **Estándar** | El día a día: crear, editar y consultar según sus permisos. |
| **Básico** | Operativa limitada. |
| **Lectura** | Solo consulta. No puede modificar datos. |
Empieza por el nivel **más bajo** que permita a la persona hacer su trabajo. Siempre puedes ampliarlo después.
### Decide a qué módulos entra (permisos de app) [#decide-a-qué-módulos-entra-permisos-de-app]
El nivel marca el alcance; los **permisos** marcan a qué aplicaciones entra. Activa solo las que necesite: Pymes, CRM, TPV, RRHH, Marketing, ToDo, Servicios de IA, etc. Si alguien solo factura, no le des acceso al CRM.
Estos permisos son **sensibles** y solo deben ir a personal de confianza o técnico:
* **Desarrollador** y **Dinaup Flex**: alteran el funcionamiento del sistema y pueden generar costes adicionales.
* **Administrar usuarios**: quien lo tiene puede crear, editar y dar de baja a otras personas.
* **Gestionar Suscripción Dinaup**: da acceso a la facturación, métodos de pago y al alta/baja de licencias.
Asígnalos solo cuando haya una razón clara.
👉 [Ver todos los permisos: Gestión de usuarios](/docs/cuenta/gestion-de-usuarios)
### Afina con roles (permisos finos) [#afina-con-roles-permisos-finos]
¿Necesitas más detalle que "entra o no entra a la app"? Crea un **rol**. Un rol controla a qué **secciones** accede la persona y qué puede hacer en cada una (agregar, eliminar, ver histórico…), además del menú y el diseño que ve.
Los roles se crean y configuran desde **Dinaup Desktop** (en **Configuración → Roles**) y luego se asignan a cada usuario desde la web.
👉 [Ver detalle: Permisos y roles](/docs/cuenta/permisos-y-roles) · [Guía rápida con vídeo](/docs/cuenta/permisos-y-roles/como-crear-y-asignar-roles-de-usuario-en-dinaup)
### Personaliza lo que ve cada rol (diseños de sección) [#personaliza-lo-que-ve-cada-rol-diseños-de-sección]
Dentro de un rol puedes definir un **diseño de sección**: qué campos y pestañas aparecen, cuáles van bloqueados y cuáles son obligatorios. Así un comercial ve una ficha simplificada y un administrador la ve completa.
Usa el diseño **Sistema** (por defecto) siempre que puedas. Si Dinaup actualiza la distribución de campos, un diseño personalizado no recoge el cambio y tendrás que mantenerlo a mano.
👉 [Ver detalle: Crear diseño de sección](/docs/cuenta/permisos-y-roles/crear-diseno-de-seccion)
### Da de baja o bloquea cuando haga falta [#da-de-baja-o-bloquea-cuando-haga-falta]
Cuando alguien deja el equipo o necesitas cortarle el acceso, **desactívalo** desde la gestión de usuarios en la web. Deja de poder entrar al instante, pero su histórico de actividad se conserva.
Si esa persona tenía una **clave API** asociada, al desactivarla las peticiones con esa clave también dejarán de funcionar.
👉 [Ver detalle: Gestión de usuarios](/docs/cuenta/gestion-de-usuarios)
***
## Nivel, permiso y rol: qué controla cada uno [#nivel-permiso-y-rol-qué-controla-cada-uno]
Es la confusión más habitual:
| Pieza | Controla | Ejemplo |
| ------------------ | ----------------------------------------------------------------------- | -------------------------------------------- |
| **Nivel** | Cuánto puede hacer en general | Administrador, Estándar, Básico, Lectura |
| **Permiso de app** | A qué aplicaciones entra | Pymes, CRM, TPV… |
| **Rol** | El detalle: a qué secciones accede, qué acciones hace y qué interfaz ve | Ficha de cliente simplificada para comercial |
Empieza por el nivel y los permisos de app. Si necesitas más control, crea un rol.
***
## Integraciones y sistemas externos [#integraciones-y-sistemas-externos]
Para que un sistema externo (una integración, un script, una conexión con n8n/Make/Zapier) acceda a Dinaup, no le des un usuario normal: crea una **clave API** vinculada a un usuario específico. La clave hereda los permisos de ese usuario, así que aplica la misma lógica de mínimos privilegios.
👉 [Ver detalle: Claves API](/docs/cuenta/claves-api)
***
## Preguntas frecuentes [#preguntas-frecuentes]
El nivel define el alcance general (cuánto puede hacer). El rol define el detalle (a qué secciones entra y qué acciones hace en cada una). Puedes usar solo el nivel, o combinarlo con un rol para afinar.
Los informes y documentos dinámicos no se controlan por roles. Para dar acceso, añade al usuario al dashboard correspondiente: verá todos los informes de sus dashboards.
Los administradores, y cualquier usuario con el permiso **Administrar usuarios**. Trátalo como un permiso sensible: quien lo tiene controla los accesos de todo el equipo.
No. Al desactivar un usuario pierde el acceso, pero su actividad registrada se conserva.
# Verifactu + Stripe (/docs/guias/verifactu-stripe)
Stripe cobra online; Dinaup emite la factura conforme. Cuando los juntas, una decisión manda sobre el resto: quién emite la factura definitiva. La respuesta para Verifactu es **Dinaup**, y esta guía configura justo eso.
## Antes de empezar [#antes-de-empezar]
* **Verifactu activo** en tu empresa (cumplimiento fiscal = VeriFactu y autorización firmada). El alta completa está en [Facturación y Verifactu](/docs/guias/verifactu).
* Una **cuenta de administrador**: solo un administrador conecta Stripe.
* Una **empresa española**: si no lo es, la capa Verifactu no aparece, pero la integración de Stripe sí funciona.
Aquí solo cubrimos el punto donde Stripe y Verifactu se tocan. El flujo completo de importar facturas está en [Integración con Stripe](/docs/desarrollo/integraciones/stripe).
## Stripe cobra, Dinaup factura [#stripe-cobra-dinaup-factura]
Stripe genera sus propias "facturas", pero **no valen para Verifactu**: no llevan la huella encadenada ni el QR de la AEAT, y no se remiten a Hacienda. La integración de Dinaup es de **solo lectura desde Stripe**: trae lo que cobraste, y la factura conforme la emite Dinaup.
Cobra al cliente online. Su factura es un comprobante de pago, no un registro Verifactu.
Toma ese cobro, lo convierte en una venta y emite la factura: huella, QR y envío a la AEAT.
El orden importa: primero Verifactu activo, luego conectas Stripe y eliges **cómo** se importa, y solo entonces importas cobros conformes.
## Paso 1: conecta tu cuenta de Stripe [#paso-1-conecta-tu-cuenta-de-stripe]
En el menú de Pymes, abre **Más → Stripe**.
Sin cuenta vinculada, verás la tarjeta **Conectar cuenta de Stripe**. Pulsa **Conectar con Stripe**.
Stripe te pide autorizar la conexión. Al volver, Dinaup muestra **Cuenta Stripe conectada** con el identificador de tu cuenta.
Hasta que haya cuenta conectada, no puedes importar nada. Si no eres administrador, la integración te avisa de que la conexión la configura un administrador.
## Paso 2: configura el tipo de venta de Stripe [#paso-2-configura-el-tipo-de-venta-de-stripe]
Este paso decide si tus cobros de Stripe cumplen Verifactu. Al importar, Dinaup necesita saber con qué **tipo de venta** dar de alta cada factura.
La primera vez, Stripe muestra **Se requiere configurar el tipo de venta para Stripe**. Elige en el desplegable el **tipo de venta** que se usará para todo lo que importes desde Stripe, y guarda.
También puedes fijarlo desde la configuración de la empresa, como **tipo de venta predeterminado para Stripe**.
Ese tipo de venta tiene que cumplir tres condiciones, o la importación se bloquea con un aviso:
| Condición | Por qué |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Impuestos incluidos** | Los importes de Stripe vienen con el impuesto dentro. El tipo de venta debe tener la inclusión marcada como *incluidos* para que los totales cuadren. |
| **Sin "Factura emitida con otro software"** | Con esa opción marcada, Dinaup asume que la factura la emitió otro sistema y **no** la envía a Verifactu. Déjala desmarcada. |
| **El tipo de venta existe** | Si lo borraste o cambiaste, Dinaup avisa de que el predeterminado de Stripe ya no es válido. |
Esa opción sirve para registrar en tus libros una factura que **ya** emitió un tercero, sin volver a generarla. Stripe no emite facturas Verifactu, así que si la marcas te quedas sin registro en Hacienda. Al importar verás: *"Stripe no es compatible con Verifactu. Desmarcar esta opción para que Dinaup emita y envíe la factura a Verifactu con normalidad."* Desmarcada, el cobro entra como venta normal y sigue el camino Verifactu completo.
## Paso 3: importa un cobro como factura Verifactu [#paso-3-importa-un-cobro-como-factura-verifactu]
En **Más → Stripe**, pestaña **Facturas**. Por defecto se muestran las **pendientes de importar**. Las que aún no están en Dinaup salen marcadas como **Nueva**.
En la factura que quieras traer, pulsa **agregar al ERP**. Si el cliente de Stripe no está vinculado a un cliente de Dinaup, se abre el diálogo **Vincular cliente** para emparejarlos sin duplicar fichas.
Dinaup la da de alta con su tipo de venta, importe y cliente, y abre la venta. A partir de ahí la factura sigue el flujo Verifactu igual que una venta normal: clave de tipo de factura, huella, QR y cola de envío a la AEAT.
Dinaup reconoce por el **número de factura** lo que ya importaste, así que aunque recargues no se duplica. Y no hay botón de "enviar a Hacienda": al guardar la venta, el registro Verifactu entra en cola y se procesa solo.
## Paso 4: comprueba que el registro cuajó [#paso-4-comprueba-que-el-registro-cuajó]
La AEAT tiene que aceptar el registro. Lo ves en **Pymes → Verifactu**:
| Pestaña | Qué muestra |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Facturas** | Las facturas Verifactu cuyo estado **aún no es "Correcto"**. Si una factura que acabas de importar aparece aquí, falta por cuajar o tiene un problema. |
| **Registros** | Un gráfico de **Verifactu por estado** y el listado de envíos, filtrable por fechas. |
Un registro recién enviado tarda un poco en pasar a *Correcto*; Dinaup lo refleja en cuanto la AEAT responde. Si algo se **rechaza**, lo resuelves con **Reenviar** o **Subsanar** desde la ficha del registro: ese flujo está en [Facturación y Verifactu](/docs/guias/verifactu#arregla-un-registro-rechazado).
Si cobras por Stripe importes pequeños sin datos fiscales del cliente, encajan como factura simplificada. Dinaup elige la clave que corresponde según los datos de la operación; no la indicas tú.
## Suscripciones y pagos recurrentes [#suscripciones-y-pagos-recurrentes]
La integración te muestra las **suscripciones** de Stripe (mensuales, anuales) en su pestaña, con su estado e impuesto. Ahí ves la suscripción tal como vive en Stripe. La factura conforme de cada cobro recurrente la emites importándola desde la pestaña **Facturas**: cada renovación genera su propia venta y su propio registro Verifactu. No importas "la suscripción", importas las facturas que va generando.
## Resumen del flujo [#resumen-del-flujo]
Cumplimiento fiscal = VeriFactu y autorización firmada.
Más → Stripe → Conectar con Stripe (admin).
Impuestos incluidos y SIN 'emitida con otro software'.
Agregar al ERP, y revisar en Pymes → Verifactu.
Para el detalle de cada pieza:
* Operar Verifactu en el día a día → [Facturación y Verifactu](/docs/guias/verifactu).
* Importar y reconciliar todo lo de Stripe → [Integración con Stripe](/docs/desarrollo/integraciones/stripe).
* La nomenclatura oficial de claves F1–F3 y R1–R5 → [Tipos de factura Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu).
# Facturación y Verifactu (/docs/guias/verifactu)
Con Verifactu activado facturas como siempre: Dinaup genera la huella encadenada y el QR de cada factura, la firma y la remite a la AEAT en segundo plano. Esta guía cubre el flujo completo: activarlo, ver el estado y arreglar lo que la AEAT rechace.
## Antes de empezar [#antes-de-empezar]
* Tu empresa debe estar registrada en **España**. La activación de Verifactu solo aparece en empresas españolas.
* Necesitas tu **certificado digital** para firmar la autorización.
Dinaup no es compatible con SII ni con TicketBAI. Si tu empresa tiene uno de esos seleccionado, te avisa de que no son válidos y te pide cambiar a Verifactu.
## Elige Verifactu como sistema de cumplimiento [#elige-verifactu-como-sistema-de-cumplimiento]
Indícale a Dinaup que quieres facturar bajo Verifactu desde la tarjeta **Configuración** del panel de tu empresa.
Entra en **Pymes** y abre la vista general de la empresa. En la tarjeta **Configuración** verás el bloque **Cumplimiento fiscal**.
En el desplegable **Sistema de Cumplimiento**, elige **VeriFactu**.
Pulsa **Aplicar**. La tarjeta pasa a mostrar el distintivo **VeriFactu Activado** y un resumen del estado de tus registros.
Con el cumplimiento en Verifactu, aparece una nueva entrada **Verifactu** en el menú de Pymes (icono de registros). Ahí vive todo el seguimiento del que habla el resto de esta guía.
## Activa Verifactu firmando la autorización [#activa-verifactu-firmando-la-autorización]
Para enviar en tu nombre a la Agencia Tributaria, Dinaup necesita una **autorización firmada digitalmente** por ti: un PDF que Dinaup genera, tú firmas con tu certificado y vuelves a subir. Esa firma es lo que permite que, a partir de ahí, cada factura se firme y se remita sola. El proceso vive en el asistente **Activar Verifactu**, en cuatro pasos.
**Información.** El asistente te explica qué es el documento y qué vas a hacer: rellenar unos datos, descargar un PDF, firmarlo y volver a subirlo.
**Generar PDF.** Dinaup precarga los datos fiscales de tu empresa. Elige si eres **persona física** o **entidad jurídica** y completa lo que falte:
* **Persona física:** nombre y apellidos, NIF, municipio, calle y número.
* **Entidad jurídica:** datos de la entidad (nombre, NIF, dirección) **y** los del **representante** que firma (nombre, NIF y dirección).
Pulsa **Generar y Descargar PDF**. Dinaup crea el documento de representación y lo descarga.
**Firma el PDF** con tu certificado digital, fuera de Dinaup. Vale cualquiera de estas herramientas:
* **Adobe Acrobat Reader** (gratis), con la opción *Usar un certificado*.
* **AutoFirma**, la utilidad oficial del Gobierno de España.
* La **utilidad de Verifacti** (ejecutable Windows o script Python).
**Subir PDF firmado.** Vuelve al asistente, selecciona el PDF ya firmado (máximo 10 MB) y pulsa **Enviar PDF Firmado**. Si la validación es correcta, verás *Verifactu está activado*.
## Factura como siempre: Dinaup pone la clave y el QR [#factura-como-siempre-dinaup-pone-la-clave-y-el-qr]
Una vez activado, no cambia tu forma de facturar. Cuando emites una factura, Dinaup hace por debajo todo el trabajo de Verifactu:
* Elige la **clave de tipo de factura** que corresponde (F1, F2, F3 para las emitidas; R1–R5 para las rectificativas) según los datos de la operación.
* Genera la **huella encadenada** y el **código QR** de la factura.
* **Pone el registro en cola** y lo envía a la AEAT en segundo plano, con reintentos automáticos si hay un fallo temporal.
No hay un botón de "enviar a Hacienda": al guardar la factura, el registro entra en cola y se procesa solo.
Las claves **F1/F2/F3** y las rectificativas **R1–R5** son la nomenclatura oficial de la AEAT. Dinaup las elige por ti; si quieres entender qué representa cada una, tienes el catálogo completo en [Tipos de factura Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu).
## Revisa el estado de tus registros [#revisa-el-estado-de-tus-registros]
En **Pymes → Verifactu** tienes el seguimiento completo, repartido en dos pestañas.
Las facturas Verifactu cuyo estado
**aún no es "Correcto"**
: lo que falta por cuajar o tiene algún problema.
Un gráfico de
**Verifactu por estado**
y el listado de registros enviados, filtrable por rango de fechas.
El gráfico agrupa los registros por estado, así que sabes cuántos van bien y cuántos están rechazados sin abrir nada. Para entrar en el detalle de una factura, **haz clic sobre ella** en la pestaña *Facturas*: se abre la ficha con todos sus registros.
Cuando un registro está recién enviado, la AEAT tarda un poco en devolver el estado; Dinaup lo refleja en cuanto llega. Lo normal es que no necesites entrar aquí salvo que algo se rechace.
## Mira el detalle de un registro [#mira-el-detalle-de-un-registro]
Al abrir un registro concreto ves su ficha con varias vistas:
* **Respuesta**: la respuesta JSON que devolvió el envío.
* **Estado (AEAT)**: el estado que la Agencia Tributaria ha devuelto para ese registro.
* **Error**: solo aparece si el registro trae un error; te muestra el mensaje concreto.
* **Raw**: el contenido técnico en bruto, por si necesitas inspeccionarlo.
Desde el pie de la ficha puedes abrir la **Ficha completa** del registro, ir a la **factura** asociada con *Ver*, **Actualizar** para refrescar el estado, o lanzar las acciones de corrección que verás a continuación.
## Arregla un registro rechazado [#arregla-un-registro-rechazado]
Si la AEAT rechaza un registro, su estado pasa a **Rechazada** y tienes dos vías para resolverlo, según el caso.
**Reenviar.** Si el rechazo fue por algo temporal y el contenido era correcto, el botón **Reenviar** (solo visible en registros rechazados) vuelve a poner el registro en cola para un nuevo intento. No tienes que tocar los datos.
**Subsanar.** Si hay que corregir el contenido del registro, usa **Subsanar**. Se abre un editor con el JSON del registro y un selector de **Acción**:
* **Subsanar**: corrige un registro previamente rechazado. Requiere que el JSON incluya la marca `rechazo_previo`.
* **Crear**: genera un nuevo registro para esa factura. En este caso el JSON **no** debe llevar `rechazo_previo`.
Puedes dejar el JSON tal cual para que se genere solo, o ajustarlo. Pulsa **Subsanar** para enviarlo.
Si una factura fue **emitida con otro software** e importada a Dinaup, no se puede subsanar ni regenerar desde aquí: ese registro lo gestiona el sistema que la emitió originalmente. Lo mismo aplica a cualquier factura que no sea de cumplimiento Verifactu.
## Rectificativa no es lo mismo que devolución [#rectificativa-no-es-lo-mismo-que-devolución]
Un error habitual: tratar una **devolución** como si fuera una rectificación de Verifactu. No lo es.
* Una **factura rectificativa** (R1–R5) corrige una factura ya emitida: un error en los datos, una modificación de la base imponible, un crédito incobrable... Lleva serie específica y se registra con su clave R correspondiente.
* Una **devolución o abono** es una operación comercial: el cliente devuelve mercancía o le abonas un importe. Tiene su propio flujo en Dinaup.
Dinaup asigna la clave R que toca cuando de verdad estás rectificando. Para el qué y el cuándo de cada tipo, mira [Devoluciones y abonos](/docs/rtg/pymes/facturacion/ventas/devoluciones-y-abonos) y el catálogo de [Tipos de factura Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu).
## Garantías del sistema [#garantías-del-sistema]
Dinaup opera **solo en modo Veri\*Factu**: cada registro queda firmado por su remisión autenticada a la AEAT, la factura y su registro se guardan de forma inmediata, y un servicio en segundo plano se encarga del envío y de reintentar con espera creciente hasta tener el acuse de Hacienda.
El sistema cumple lo exigido por el RD 1007/2023 y la Orden HAC/1177/2024. Puedes consultar la [Declaración responsable del sistema informático de facturación](/docs/cuenta/legal/declaracion-verifactu) con la versión, el productor y el detalle técnico del cumplimiento.
Para la nomenclatura oficial de claves tienes [Tipos de factura Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu); para el resto de facturación de ventas, la sección [Pymes · Facturación](/docs/rtg/pymes/facturacion/ventas).
# Yudo (/docs/guias/yudo)
Yudo mira la misma pantalla que tú. Le cuentas con palabras normales lo que necesitas y lo deja hecho: rellena formularios, busca datos y pulsa botones. Lo importante lo confirmas tú con el último clic.
## Antes de empezar [#antes-de-empezar]
* La IA de tu empresa tiene que estar encendida.
* Cada usuario tiene un cupo semanal: la IA gasta. Cuando se agota, Yudo te avisa y vuelve a estar disponible al renovarse.
Si la IA está apagada o se agotó el cupo, el botón te lo dice claro, no falla en silencio.
Si **ves** un dato en pantalla, Yudo lo lee. Si **puedes** pulsar un botón, Yudo lo pulsa. Si **editas** un campo, Yudo lo rellena. Ni más (no inventa) ni menos.
## Le hablas, y lo hace [#le-hablas-y-lo-hace]
Le cuentas con tus palabras lo que ha pasado y los cambios aparecen en tu pantalla:
Tú lo dices con palabras; Yudo busca las cuentas, monta el asiento y comprueba que cuadra. Lo ves hacerse en la misma ventana.
## Dónde lo encuentras [#dónde-lo-encuentras]
Yudo aparece de tres formas, según lo que estés haciendo:
Un botón redondo abajo en la pantalla. Lo abres, eliges
**Yudo**
y le preguntas lo que quieras en un chat.
En muchas fichas y formularios se enciende un panel de Yudo a la derecha (con un interruptor «Activar Yudo»). Ahí ve y toca
**esa**
ventana concreta.
Botones tipo «Analizar con Yudo»: pulsas uno y te resume la tabla con cifras y nombres concretos.
## Todo lo que puede hacer [#todo-lo-que-puede-hacer]
### Entiende tus datos [#entiende-tus-datos]
* Busca y lee tus facturas, clientes, productos, tareas… por nombre o por lo que le describas.
* Responde preguntas de negocio: «¿cuánto me deben los clientes?», «¿cuántas vacaciones me quedan?», «¿qué turno tengo mañana?».
* Analiza un informe y te cuenta lo importante (qué rinde más, qué falla) con números y 3-5 cosas que podrías hacer.
### Rellena y opera por ti [#rellena-y-opera-por-ti]
* Rellena y corrige los campos del formulario que tienes delante.
* Monta **asientos contables** a partir de una frase y comprueba que el Debe y el Haber cuadran al céntimo.
* Arregla **fichajes**: cierra una jornada olvidada, registra pausas, ausencias (baja, vacaciones) o asigna un horario.
* Clasifica **movimientos del banco** y hace cambios en lote (varios registros a la vez).
### Investiga y averigua [#investiga-y-averigua]
* Busca en internet el **NIF, la razón social o la dirección** de una empresa (BORME, registro) y te propone los datos correctos.
* Cuadra tus ventas con los movimientos del banco y te dice qué falta o sobra.
* Repasa todo el histórico de un cliente (ventas, cobros, pedidos) para ver si todo encaja.
### Crea y recuerda [#crea-y-recuerda]
* Genera **imágenes** a partir de una descripción (un logo sencillo, un icono).
* Se acuerda de ti: tu nombre, tu empresa, tu forma de trabajar y tu vocabulario. Si le dices «para mí, pendiente es lo no cobrado», la próxima vez lo usa bien.
* Toma la iniciativa: si ve algo raro mientras consulta (una factura a 0 €), te lo comenta.
## Ejemplos de cosas que le puedes decir [#ejemplos-de-cosas-que-le-puedes-decir]
«Compra de material 121 € con IVA, pagado con tarjeta» → arma el asiento con las tres partidas cuadradas.
«Busca el NIF de esta empresa en internet» y «márcalo como cliente, IVA 21%, créale su cuenta contable».
«Se olvidó de fichar la salida, salió a las 18:00» → cierra la jornada. «Hoy está de baja» → registra la ausencia.
«¿Cuánto pagué a Endesa este año?» o «cuadra las ventas con el banco y dime qué falta».
«Marca como completada la tarea de revisar el almacén» → la cambia y te deja un enlace para revisar.
«¿Cuántas vacaciones me quedan?» → mira solo tus datos y te responde.
## Qué decide Yudo y qué decides tú [#qué-decide-yudo-y-qué-decides-tú]
| Tipo de acción | Quién la cierra |
| ------------------------------------------------------------------- | ---------------------------------------------------------- |
| Sencillo y reversible (marcar una tarea, mover una fecha) | Yudo lo hace solo y te avisa, con un enlace para deshacer. |
| Importante (crear una factura, dar de alta un cliente, algo fiscal) | Yudo te abre el formulario; das tú el último clic. |
| Borrar registros | Nunca lo hace Yudo: te pide que lo hagas tú. |
| Cambios sobre muchos registros | Yudo pide confirmación antes. |
Yudo solo ve **tus** datos: tus vacaciones, tus turnos. No enseña los de otros compañeros, no se inventa datos ni dice que ha hecho algo que no hizo.
## Yudo y Laia [#yudo-y-laia]
Trabaja con
**los datos de tu negocio**
: contabilidad, clientes, fichajes, banco… Hace y consulta cosas dentro de Dinaup.
Es el
**soporte**
: te ayuda a usar el programa, te explica dónde está cada cosa y cómo se hace.
Los dos conviven en el mismo botón flotante: eliges con cuál hablar.
Cada ventana le da a Yudo lo que puede tocar. Si construyes la tuya y quieres que Yudo la opere, mira la guía de [DinaZen](/docs/guias/dinazen) y el [SDK .NET](/docs/guias/sdk-api).
# Junio de 2026 (/docs/novedades/2026-06)
Notas de las versiones publicadas en junio de 2026: primero el núcleo (Terminal Windows + Server Linux) y después el SDK .NET. El detalle de las numeraciones está en [cómo leer las versiones](/docs/novedades/como-leer-las-versiones).
## 65.7545 [#657545]
*25 de junio de 2026*
**Correcciones**
* La paginación de informes se topa en 50.000 filas para frenar consultas con `OFFSET` abusivo.
## 65.7544 [#657544]
*24 de junio de 2026*
**Mejoras**
* La instalación de módulos usa un resolutor por umbral de madurez del canal.
**Correcciones**
* El server adelanta la purga de objetos que no pertenecen a módulos y añade `CASCADE` al borrado de columnas.
* El Terminal repuebla el filtro aplicado en la casilla de columna al recargar la lista de un informe.
* Desaparecen las acciones "Nuevo informe Panel" del menú de widgets del Terminal.
## 65.7543 [#657543]
*19 de junio de 2026*
**Mejoras**
* El server cachea resultados de informe por SQL: un acierto de caché evita la consulta a Postgres. La caché es LRU acotada a 256 MB, se invalida por monitorización y descarta SQL no determinista (`now()`, `random()`).
* El listado de la API expone el SQL ejecutado y los tiempos de servidor (Postgres, preparación y post-proceso) para depurar.
## 65.7542 [#657542]
*18 de junio de 2026*
**Mejoras**
* La API de informe devuelve el SQL ejecutado por el servidor (campo `sql` en el listado, para depurar).
## 65.7541 [#657541]
*18 de junio de 2026*
**Correcciones**
* El orden explícito que pides por API manda sobre el orden por defecto del informe. Evita filas repetidas al paginar por cursor.
## 65.7540 [#657540]
*18 de junio de 2026*
**Correcciones**
* Las consultas agregadas ya no reciben orden por columnas crudas, lo que provocaba el error 42803 de Postgres.
## 65.7539 [#657539]
*18 de junio de 2026*
**Correcciones**
* Orden total determinista al paginar con `LIMIT`: el `id` actúa como desempate único.
* Deduplicación por recurso en ResourceReserve con `DISTINCT ON` y orden por vencimiento.
## 65.7532 [#657532]
*6 de junio de 2026*
**Correcciones**
* Guarda contra `Cache_EmpresaAdministradas` vacío al construir la cadena Redis de empresa.
## 65.7531 [#657531]
*6 de junio de 2026*
**Mejoras**
* Los avisos push por ntfy se reorganizan por severidad en 3 topics fijos: `dp-crit`, `dp-warn` y `dp-info`. El tenant va en el título y la categoría como etiqueta: te suscribes una vez y el alta de tenants no añade topics.
* Aviso de consultas lentas: `ConsultaSQL` y `EjecutarSQL` por encima de `DINALOG_NOTIFY_SLOWMS` (5 s por defecto) disparan un push, con enfriamiento de 60 s por tenant.
* La empresa administrada principal pisa la config del server para el Redis de eventos y el repositorio MyDinaup; el server queda como respaldo.
## SDK 10.15.0.21 [#sdk-1015021]
*30 de junio de 2026*
**Mejoras**
* El sink de logs a Loki se adapta a Serilog.Sinks.Grafana.Loki 9.0.1 (nueva API de `batchSizeLimit` y etiquetas por propiedad).
* Dependencias al día: Npgsql 10.0.3 y System.Drawing.Common 10.0.9.
## SDK 10.15.0.20 [#sdk-1015020]
*25 de junio de 2026*
**Mejoras**
* `LoadAllRowsAsync` estrena guía de listados de alto rendimiento: cómo volcar un informe entero con paginación keyset y qué límites tiene (solo exportaciones, orden por `id`, sin `AddOrder`).
## SDK 10.15.0.19 [#sdk-1015019]
*19 de junio de 2026*
**Mejoras**
* `ConnectTimeoutSeconds` en `PGClientOptions`: controla el tiempo máximo de conexión a Postgres.
* Los informes exponen metadata de tiempos (observabilidad): cuánto tarda cada fase de la consulta.
## SDK 10.15.0.18 [#sdk-1015018]
*17 de junio de 2026*
**Mejoras**
* `DinaupReportBase.LoadAllRowsAsync`: vuelca un informe entero con paginación keyset (`id > último-id`) en lugar de `OFFSET`. Coste constante por página, sin duplicados ni huecos aunque el informe tenga cientos de miles de filas.
* Limpieza de `Description` en enums.
# Julio de 2026 (/docs/novedades/2026-07)
Notas de las versiones publicadas en julio de 2026: primero el núcleo (Terminal Windows + Server Linux) y después el SDK .NET. El detalle de las numeraciones está en [cómo leer las versiones](/docs/novedades/como-leer-las-versiones).
## 65.7547 [#657547]
*1 de julio de 2026*
**Mejoras**
* Los informes consumidos por API pueblan siempre las columnas estáticas ocultas obligatorias: `id`, `fechaia`, `eliminado` y `listadoreliminado`. MyDinaup y el SDK reciben identidad de fila, fecha de cambio y borrado lógico sin depender de columnas virtuales en runtime. Los informes de tipo Ordinario pueblan solo `id`.
**Correcciones**
* Al modificar la tabla `informes`, el server reconsolida estáticas y plantillas, igual que ya hacía con `camposp` y `plantillasp`.
## 65.7546 [#657546]
*1 de julio de 2026*
**Mejoras**
* MyDinaup tolera columnas ausentes en informes generados si activas `TolerateMissingColumns`, con guardas `col_N >= 0`.
* La estructura ES documenta los criterios de autorrellenado de cada campo.
* El reorganizador de formularios del Terminal estrena prompt: fases, carriles fijos y bloqueos por tipo.
**Correcciones**
* Las conversiones de columna en MyDinaup se generan como llamada a método (`STR()`, `INT(0)`, `ToDateTime_UTC()`...).
## SDK 10.15.0.22 [#sdk-1015022]
*1 de julio de 2026*
**Mejoras**
* `TolerateMissingColumns`: opción opt-in en `DinaupReportBase` para que un informe tolere columnas ausentes en vez de fallar. Se activa por informe o como default de proceso vía `DinaupReportSettings`. Emparejada con la tolerancia equivalente del núcleo 65.7546.
# Cómo leer las versiones (/docs/novedades/como-leer-las-versiones)
Cada release de Dinaup lleva un número con dos partes: `65.7547`.
| Parte | Qué es |
| ------ | --------------------------------------------------------- |
| `65` | Generación mayor del producto. Cambia pocas veces al año. |
| `7547` | Revisión. Sube en 1 con cada release publicada. |
## Qué incluye una release [#qué-incluye-una-release]
Una release publica a la vez los dos componentes del núcleo:
* **Terminal Windows**: la aplicación de escritorio para desarrollar y administrar. Se distribuye en `cdn.dinaup.com/versiones//Desktop/`.
* **Server Linux**: el servidor que ejecuta tu instancia. Imagen Docker `dinaupcom/dinaupsrv:` (también etiquetada `latest`).
Las aplicaciones web (play.dinaup.com, dinaup.com) llevan su propio ciclo y no aparecen en esta numeración.
## El SDK .NET tiene su propia numeración [#el-sdk-net-tiene-su-propia-numeración]
El paquete [Dinaup en NuGet](https://www.nuget.org/packages/Dinaup) versiona aparte, con esquema `10.15.0.22`:
| Parte | Qué es |
| ------- | ------------------------------------------------ |
| `10.15` | Línea mayor y menor del SDK. |
| `0.22` | Revisión. Sube con cada publicación del paquete. |
En estas notas, las versiones del SDK aparecen con el prefijo **SDK** (por ejemplo, `SDK 10.15.0.22`) dentro del mes en que se publicaron. Una mejora puede requerir núcleo y SDK a la vez; cuando pasa, la nota lo dice.
## Cadencia [#cadencia]
No hay fecha fija. Una revisión sale cuando hay cambios listos y verificados: algunas semanas salen varias, otras ninguna. Las correcciones urgentes se publican en cuanto existen.
## Cómo enlazar una versión [#cómo-enlazar-una-versión]
Cada versión tiene su ancla en la página del mes. Por ejemplo, la 65.7547 vive en `/docs/novedades/2026-07#657547`. Los artículos del blog que amplían una novedad enlazan a esa ancla.
# Área de Empleado (/docs/rtg/area-de-empleado)
El **Área de Empleado** es tu espacio personal dentro de Dinaup. Reúne en un solo sitio tu información laboral, las acciones del día a día (fichar, pedir vacaciones), tus documentos y la comunicación con la empresa.
Algunas secciones solo aparecen si la empresa las tiene activadas o si tu ficha cumple ciertas condiciones (por ejemplo, **Cumpleaños** solo se muestra si la empresa lo permite, y **Departamento** solo si perteneces a uno). Si no ves un apartado, es normal: depende de tu configuración.
***
## Qué puedes hacer por tu cuenta [#qué-puedes-hacer-por-tu-cuenta]
El Área de Empleado está pensada para la **autogestión**. Esto es lo que tienes a mano:
| Acción | Para qué sirve |
| --------------------------------- | ---------------------------------------------------------------- |
| **Fichar** | Registrar tu entrada y salida desde tu propio dispositivo |
| **Solicitar vacaciones** | Pedir días libres y seguir el estado de la petición |
| **Consultar tus documentos** | Ver nóminas, contratos y correspondencia que la empresa te envía |
| **Revisar tus fichajes y turnos** | Comprobar tus horas y tu planificación |
| **Gestionar tus archivos** | Guardar tus documentos y acceder a los compartidos |
***
## Inicio: tu perfil de trabajador [#inicio-tu-perfil-de-trabajador]
La pantalla de **Inicio** resume tu vida laboral en la empresa. Aquí ves:
* **Tu fichaje reciente**, con un repaso de los últimos días.
* **Tu saldo de vacaciones** y los días que te quedan.
* **Tus correspondencias** y notificaciones internas más recientes.
* **Tus nóminas y contratos**, listos para consultar o descargar.
* **Tu horario** y la planificación que tienes asignada.
Si quieres entender en detalle cada bloque de tu ficha personal (saldos, contratos, nóminas, correspondencia), tienes una guía dedicada en **[Perfil de trabajador](/docs/rtg/recursos-humanos/perfil-de-trabajador)**.
***
## Fichar [#fichar]
Desde el Área de Empleado puedes **fichar tu entrada y salida**. El acceso al fichaje aparece en el menú cuando tu empresa tiene activado el control horario.
Al fichar, tu jornada queda registrada y se refleja en tu resumen de Inicio y en tus fichajes. La empresa obtiene el registro legal y tú llevas el control de tus horas.
→ [Fichaje](/docs/rtg/recursos-humanos/fichaje)
***
## Vacaciones [#vacaciones]
El apartado de **Vacaciones** es el registro central de tus días libres: lo que has pedido, lo que te han concedido y lo que tienes pendiente.
### Listado y estado [#listado-y-estado]
Ves **todas tus vacaciones**: las solicitudes realizadas, su **estado** (solicitada, aceptada o rechazada), las fechas y el motivo de la ausencia.
### Solicitar vacaciones [#solicitar-vacaciones]
Desde el formulario de solicitud eliges las **fechas**, añades un comentario si hace falta y envías la petición.
### Seguimiento del estado [#seguimiento-del-estado]
Una vez enviada, su estado se actualiza solo en tu perfil: **pendiente, aprobada o rechazada**, sin preguntar a Recursos Humanos.
Para el detalle de la solicitud, consulta la guía de Vacaciones y ausencias.
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
***
## Correspondencias [#correspondencias]
En **Correspondencias** recibes las **comunicaciones formales** que la empresa te dirige: avisos de Recursos Humanos, solicitudes de documentación, mensajes internos y cualquier notificación relevante para tu relación laboral. Queda todo registrado en tu buzón interno.
→ [Correspondencias](/docs/rtg/recursos-humanos/correspondencias)
***
## Tus archivos [#tus-archivos]
El Área de Empleado incluye un espacio de documentos organizado por ámbito, para que cada archivo esté donde toca.
| Carpeta | Qué contiene | Quién la ve |
| ------------------- | ----------------------------------------------------------------- | ------------------ |
| **Mis archivos** | Tus documentos personales | Solo tú |
| **Compartidos** | Documentos que la empresa pone a disposición de toda la plantilla | Toda la empresa |
| **Departamento** | Archivos de tu departamento | Tu departamento |
| **Subdepartamento** | Archivos de tu subdepartamento | Tu subdepartamento |
En cada carpeta puedes navegar entre los documentos, abrirlos y subir los tuyos. **Mis archivos** es privado; **Compartidos** te da acceso a lo que la empresa publica para todos; y **Departamento** y **Subdepartamento** aparecen solo si perteneces a uno y agrupan la documentación de tu equipo.
***
## Cumpleaños de compañeros [#cumpleaños-de-compañeros]
Cuando la empresa lo activa, el Área de Empleado muestra los **cumpleaños de tus compañeros**.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Sí. Si tu empresa tiene activado el control horario, el acceso a fichar aparece en el menú y registras tu entrada y salida tú mismo, desde tu dispositivo.
El estado se actualiza solo en tu perfil: verás si la solicitud está pendiente, aprobada o rechazada, sin necesidad de preguntar a Recursos Humanos.
En la pantalla de Inicio, dentro de tu perfil de trabajador, tienes tus nóminas y contratos para consultar o descargar. Tienes el detalle en la guía de Perfil de trabajador.
Son secciones condicionales. Departamento y Subdepartamento aparecen solo si tu ficha pertenece a uno; Cumpleaños solo si la empresa lo activa. Si no aplican a tu caso, no se muestran.
Los documentos de "Mis archivos" son privados: solo tú accedes a ellos. Los "Compartidos" son de toda la empresa, y los de Departamento o Subdepartamento, de tu equipo.
***
→ [Recursos Humanos](/docs/rtg/recursos-humanos)
→ [Perfil de trabajador](/docs/rtg/recursos-humanos/perfil-de-trabajador)
→ [Fichaje](/docs/rtg/recursos-humanos/fichaje)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
→ [Correspondencias](/docs/rtg/recursos-humanos/correspondencias)
# Inicio (/docs/rtg)
Desde aquí accedes a las soluciones Ready To Go, las integraciones y Dinaup Flex.
## Soluciones listas para empezar [#soluciones-listas-para-empezar]
ERP ligero: facturación, inventario y contabilidad.
Kanban, time‑tracking y reporting de equipos.
Captación y fidelización de clientes.
Control horario y Fichajes
Punto de venta táctil para comercio y hostelería.
Copiloto de IA en cada módulo: OCR de facturas, sugerencias y agentes.
## Integraciones [#integraciones]
Replica tus datos de Dinaup en una base PostgreSQL de solo lectura.
Conecta Dinaup con Power BI y crea paneles interactivos.
Diseña flujos automáticos y vincula Dinaup con +1000 apps usando Make, sin código.
Orquesta workflows de código abierto entre Dinaup y cualquier servicio con n8n.
Integra Dinaup con miles de aplicaciones y automatiza tareas en minutos mediante Zapier.
Genera un SDK a medida y mantén tu repositorio GitHub siempre sincronizado con tu esquema de datos.
Crea webhook entrantes y salientes
Paquetes NuGet oficiales: cliente API, logging, validaciones y base de datos.
DinaZen: componentes Blazor sobre Radzen con el aspecto de Play Dinaup.
***
## Dinaup Flex [#dinaup-flex]
Crea tablas de datos y personaliza sus campos sin programar.
Listados y consultas sobre cualquier sección, sin escribir SQL.
Facturas, emails y PDFs generados con plantillas.
# Preguntas frecuentes (/docs/rtg/preguntas-frecuentes)
Si no encuentras aquí la respuesta, escribe a `soporte@dinaup.com` o abre el chat de ayuda en [play.dinaup.com](https://play.dinaup.com).
Algunas áreas tienen su propia FAQ con más detalle:
* Empleados, fichajes, horarios y vacaciones → [FAQ de Recursos Humanos](/docs/rtg/recursos-humanos/faq-recursos-humanos)
* Dispositivos, impresoras, cajas y ventas en mostrador → [FAQ del TPV](/docs/rtg/tpv/faq-tpv)
* Fiscalidad, tipos de venta y precios → [FAQ de Pymes](/docs/rtg/pymes/preguntas-frecuentes)
* Cuenta, usuarios y permisos → [FAQ de Cuenta](/docs/cuenta/preguntas-frecuentes)
* API, webhooks e integraciones → [FAQ de Desarrollo](/docs/desarrollo/preguntas-frecuentes)
***
## Configuración inicial [#configuración-inicial]
La primera vez que entras en una empresa nueva, Dinaup lanza el **asistente 1Click**: un setup rápido que deja tu empresa lista para trabajar. Te pide:
* **Datos fiscales** (CIF, razón social, dirección), que se validan contra la AEAT
* **Forma jurídica** (autónomo, SL, SA…)
* **Actividad principal**
* **Cuentas bancarias** principales
* **Categorías de gasto** sugeridas según tu sector (las aceptas o ajustas)
* **Reglas de clasificación** iniciales para los movimientos bancarios
La IA propone categorías y reglas según la actividad que elijas, así que no partes de cero. Si lo cierras a medias o quieres repasarlo más tarde, puedes reabrirlo desde **Pymes → Configuración**.
→ [Registrar empresa](/docs/cuenta/registrar-empresa)
Los datos fiscales y de identificación de la empresa (razón social, CIF, dirección, actividad) se editan desde **Pymes → Configuración → Empresa** en [play.dinaup.com](https://play.dinaup.com). Guarda los cambios y se aplicarán a las nuevas facturas y documentos que generes.
***
## Facturación y ventas [#facturación-y-ventas]
* Ve a **Pymes → Facturación → Ventas**
* Haz clic en "+ Nueva Venta"
* Selecciona el tipo de venta apropiado (Nacional, Intracomunitaria, etc.)
* Añade el cliente (o créalo si no existe)
* Agrega las líneas de producto o servicio
* Revisa los importes e impuestos
* Guarda y emite la factura
De forma predeterminada, Dinaup trae configurados:
* **Nacional**: ventas dentro de España con IVA
* **Simplificada / Ticket**: para ventas menores sin datos del cliente
Puedes crear tipos de venta personalizados, por ejemplo:
* **Intracomunitaria (VIES)**: ventas a empresas de la UE
* **Exportación**: ventas fuera de la UE
* **OSS**: ventas a particulares de la UE (One Stop Shop)
* **REBU**: régimen especial de bienes usados
* **Exportación Canarias/Ceuta/Melilla**: ventas a territorios especiales
Una factura rectificativa corrige o anula, total o parcialmente, una factura ya emitida. En Dinaup la generas a partir de la factura original: la abres y eliges la opción de rectificarla, indicando qué corriges. La rectificativa queda enlazada a la factura de origen, con su propia numeración, para mantener la trazabilidad fiscal.
* Abre la factura que deseas enviar
* Haz clic en el botón "Imprimir / Exportar"
* Haz clic en "Adjuntar y enviar por email"
* La factura se adjunta en PDF
Verifactu es el sistema de la Agencia Tributaria para la emisión de facturas verificables, parte de la normativa antifraude. Dinaup cumple con Verifactu y la facturación española (IVA, VIES, OSS, REBU). Su comportamiento se gobierna desde la configuración fiscal de la empresa, en **Pymes → Configuración**.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
Cada tipo de venta lleva asociada su propia serie y numeración, de modo que las facturas se numeran de forma correlativa según el tipo. La configuración de tipos de venta y sus series vive en **Pymes → Configuración → Tipos de Venta**.
***
## Compras y gastos [#compras-y-gastos]
* Ve a **Pymes → Compras y Gastos → Compras**
* Haz clic en "+ Nueva Compra"
* Selecciona o añade el proveedor (configura su tipo de compra y datos fiscales para que se rellenen automáticamente)
* Revisa el tipo de compra
* Introduce los datos de la factura (número, fecha, importes)
* Agrega las líneas de concepto
* Guarda la compra
Cada compra o gasto se clasifica en una **categoría de gasto**. Dinaup propone un juego de categorías según tu sector durante el asistente 1Click, y puedes ajustarlas o crear las tuyas. Al registrar una compra, seleccionas la categoría correspondiente, lo que ordena tus gastos y facilita los informes y la contabilización.
***
## Fiscalidad e impuestos [#fiscalidad-e-impuestos]
* Ve a **Pymes → Configuración → Retenciones**
* Crea o edita los tipos de retención que necesites (7 %, 15 %, 19 %, etc.)
* Asigna la retención por defecto al proveedor o cliente
* Al crear facturas, la retención se aplica sola
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
***
## Tesorería y bancos [#tesorería-y-bancos]
* Ve a **Pymes → Tesorería → Cuentas Bancarias**
* Pulsa "+ Nuevo"
* Rellena los datos: nombre, IBAN, banco, subcuenta contable
* Guarda la cuenta
Una caja es el depósito del dinero físico (billetes y monedas) de un punto del negocio. Para crearla:
* Ve a **Pymes → Tesorería**
* Crea un depósito de tipo **caja**
* Asígnale un nombre descriptivo que identifique el punto de efectivo (por ejemplo, "Mostrador" o "Caja tienda 1")
* Descarga el extracto de tu banco en formato compatible (CSV o Excel)
* Ve a **Pymes → Tesorería → Cuentas Bancarias**
* Selecciona la cuenta bancaria destino
* Pulsa el botón "Importar extracto bancario"
* Sube el archivo del extracto
* Revisa los movimientos importados
* Confirma la importación
La conciliación relaciona los movimientos de tu extracto bancario con operaciones reales (cobros, pagos, ingresos o devoluciones). Dinaup analiza el extracto, busca coincidencias con tus ventas y compras y te las muestra como **sugerencias**, para que las confirmes, corrijas o rechaces. Así cuadras la cuenta bancaria sin tener que puntear movimiento a movimiento.
La conciliación trabaja con cuentas bancarias. Las cajas de efectivo no se concilian: se cuadran contando el dinero en su cierre.
Las reglas automatizan la clasificación del extracto: reconocen conceptos recurrentes (un proveedor, un banco, un servicio) y les asignan automáticamente entidad y tipo. Cuanto mejores son tus reglas, menos trabajo manual exige la conciliación. Puedes crear reglas generales (para todas las cuentas) o específicas de una cuenta, y revisarlas con la herramienta de clasificación.
Cuando un cobro o pago no llega por el extracto bancario (por ejemplo, un movimiento en efectivo), lo registras directamente sobre el depósito correspondiente de **Pymes → Tesorería**: como entrada o salida en una caja, o como cobro o pago en una cuenta bancaria. El apunte suma o resta sobre el saldo de ese depósito.
***
## Inventario y stock [#inventario-y-stock]
El modelo completo (disponible vs físico, estados de una salida, FIFO/FEFO, cuarentena) está explicado en [Cómo funciona el stock](/docs/guias/como-funciona-el-stock). Aquí, las dudas rápidas.
### Productos y precios [#productos-y-precios]
* Ve a **Pymes → Precios → Catálogos de Venta**
* Crea un nuevo catálogo o edita uno existente
* Asigna precios por producto
* Puedes crear diferentes catálogos para distintos clientes o canales
* Ve a **Pymes → Precios → Catálogos de Compra**
* Crea catálogos por proveedor
* Asigna precios de compra por producto y guarda
* Cuando abras una compra y selecciones al proveedor, se aplican los precios de su catálogo
### Conceptos básicos [#conceptos-básicos]
Un almacén es un lugar donde guardas existencias. Puede ser tu tienda, una bodega, una furgoneta o una sucursal. El sistema es multi-almacén: puedes tener tantos como necesites, y cada producto tiene su propio stock en cada almacén. Para empezar a trabajar con inventario necesitas al menos un almacén.
Una zona es una agrupación lógica dentro de un almacén, como "Recepción", "Devoluciones", "Estanterías" o "Picking". Sirve para organizar. Las zonas son opcionales: puedes usar un almacén sin definir ninguna zona.
Un hueco es una ubicación física concreta dentro de un almacén, por ejemplo "Pasillo A, Estante 1" o "REC-01". Sirve para saber dónde está colocada la mercancía. Los huecos son opcionales: solo los necesitas si quieres control de ubicación física. Para vender o llevar el stock no hace falta usar huecos.
Un producto es un artículo que compras, vendes o almacenas. Cada producto tiene una configuración que decide cómo se controla su inventario (sin control, por cantidad, o por lotes). Hay también "servicios" o conceptos que no llevan stock.
Un lote es una partida de unidades de un mismo producto que comparten datos comunes: un código de referencia, fechas (como la caducidad), un estado y, opcionalmente, avisos. Sirve para trazabilidad y control de caducidad. Un lote pertenece a un producto. No todos los productos usan lotes: solo los que configuras como "gestión por lotes".
El stock son las unidades que tienes de un producto. El sistema lleva el stock por almacén: un mismo producto puede tener 10 unidades en un almacén y 3 en otro. Verás distintos números (físico, disponible, mínimo, máximo) que se explican más abajo.
### Modos de gestión de stock del producto [#modos-de-gestión-de-stock-del-producto]
Cada producto se configura en uno de estos modos:
* **Sin gestión de stock**: el sistema no controla existencias. Se usa para servicios o cosas que no quieres inventariar (una reparación, una consultoría, un porte).
* **Por cantidad**: el sistema controla cuántas unidades tienes en total, sin distinguir partidas. Ideal para artículos simples sin caducidad (tornillos, café a granel, consumibles).
* **Por lotes**: cada partida que entra se identifica con un lote. Se usa cuando necesitas caducidad o trazabilidad (alimentos, medicamentos, productos por número de serie o por proveedor).
Se configura en la ficha del producto. Elige "sin gestión" para servicios, "por cantidad" para artículos sencillos, y "por lotes" cuando necesites controlar caducidad o saber de qué partida procede cada unidad.
Usa lotes solo si el producto tiene caducidad, viene en partidas distintas que necesitas diferenciar, o requieres trazabilidad (saber exactamente de qué entrada salió cada unidad). Si vendes algo sencillo donde una unidad es igual que otra, usa "por cantidad" y te ahorras trabajo.
Depende del producto. Si está en modo "por cantidad" o "sin gestión", no se pide lote. Si está en modo "por lotes", el sistema sí pide indicar de qué lote sale la mercancía cuando preparas la salida.
No. Un producto o concepto "sin gestión de stock" (como un servicio) no descuenta existencias ni genera movimientos de inventario. Puedes venderlo sin límite de cantidad.
### Los números de stock: físico, disponible, mínimo y máximo [#los-números-de-stock-físico-disponible-mínimo-y-máximo]
* **Stock físico** (o inventario): las unidades reales que hay en el almacén ahora mismo.
* **Stock disponible**: lo que puedes vender hoy, es decir, el físico menos lo que ya está comprometido en operaciones pendientes.
Ejemplo: si tienes 100 unidades físicas pero 5 ya están apartadas para pedidos sin entregar, tu disponible es 95.
El stock mínimo es el nivel a partir del cual conviene reponer. Cuando el stock cae por debajo del mínimo, el sistema te avisa (por ejemplo, marcando el producto en rojo). Es tu "punto de reposición". Se configura por producto y almacén.
El stock máximo es el tope recomendado de existencias, para no sobrecargar el almacén. Sirve como referencia visual: la barra de nivel de stock va de cero hasta el máximo, así ves si estás lleno o vacío. Se configura por producto y almacén.
Se configuran en los niveles de stock del producto para cada almacén. Si no los configuras, no se muestran alertas ni la barra de niveles para ese producto.
Es el stock disponible de ese producto en el almacén con el que estás operando, descontando además lo que ya has añadido en el mismo ticket. Por ejemplo, si el almacén tiene 10 unidades y añades una línea de 5, el número pasa a mostrar 5 libres.
Porque el stock se lleva por almacén. Cada almacén tiene sus propias existencias. Si cambias el almacén de trabajo, los números de stock se actualizan a los de ese almacén.
### Sobreventa y control de existencias [#sobreventa-y-control-de-existencias]
Sobrevender es intentar vender más unidades de las que tienes disponibles. Por ejemplo, tienes 5 y el cliente quiere 7. El sistema te deja decidir qué hacer en estos casos mediante la "política de sobreventa".
* **Permitir**: vende igual, aunque el stock quede en negativo. Lo que falta sale sin lote asignado.
* **Avisar**: vende y deja constancia para que lo revises después.
* **Bloquear**: recorta la venta a lo disponible. Nunca deja el stock en negativo.
* **Indefinido**: si un producto está en "indefinido", hereda la política de la empresa.
Por defecto el control es un "tope blando": te avisa, pero no te impide vender. Solo con la política en "Bloquear" la cantidad se recorta a lo disponible. Esto es así porque, en muchos negocios, quien atiende es quien decide si vende lo último que queda.
Manda el producto. Si un producto tiene una política concreta (permitir, avisar o bloquear), esa se aplica. Solo cuando el producto está en "indefinido" se usa la política general de la empresa.
Porque la política de sobreventa de ese producto (o la heredada de la empresa) estaba en "Permitir" o "Avisar". Si quieres impedir vender sin existencias, cambia la política del producto a "Bloquear".
Por la misma razón: la política está en "Permitir". Cámbiala a "Avisar" (vende y deja constancia) o "Bloquear" (recorta a lo disponible y nunca deja el stock en negativo).
### Cómo entra el stock [#cómo-entra-el-stock]
Registrar una compra crea el documento de compra, pero la mercancía entra al stock cuando confirmas la recepción (la "entrada"). Abre el flujo del documento de compra y, en la sección de entradas, confirma la cantidad recibida indicando el almacén (y el lote, si el producto va por lotes). Hasta que no confirmas la entrada, el stock no sube.
Es manual y a propósito: tú confirmas qué cantidad recibes y en qué almacén. Esto permite recibir de forma parcial y repartir entre almacenes. El sistema te facilita el trabajo proponiendo la cantidad que falta por recibir.
Sí. No tienes que entrar toda la cantidad de golpe. Puedes confirmar entradas parciales según vayan llegando; el sistema lleva la cuenta de cuánto falta por recibir.
Sí. Cada entrada se asigna a un almacén. Crea varias entradas del mismo producto, cada una con su almacén y cantidad, para repartir la mercancía recibida.
Con un movimiento de inventario de tipo "entrada". Indica el producto, el almacén, la cantidad y el motivo. Sirve para cargar el inventario inicial, registrar producción propia o regularizar al alza cuando encuentras más unidades de las registradas.
Sí, pero pasa por cuarentena. La devolución genera una entrada hacia un hueco de devoluciones: lo devuelto suma al stock físico (está en tu almacén) pero queda fuera del disponible hasta que lo revisas. Así no revendes por error algo sin comprobar su estado.
### Cómo sale el stock [#cómo-sale-el-stock]
Al vender se crea una salida, que normalmente queda "pendiente" hasta que se prepara (se decide de dónde sale y se confirma). El stock físico baja de forma definitiva cuando esa salida pasa a "completada". En productos sencillos la salida puede completarse directamente; en productos por lotes se prepara eligiendo el lote.
* **Pendiente**: la salida está registrada pero todavía no se ha preparado ni recogido del almacén.
* **Completada**: la mercancía se ha preparado y el stock se ha descontado definitivamente.
* **Anulada**: la salida se canceló y no afecta al stock.
En el flujo del documento, en la sección de salidas, pulsa preparar sobre la salida pendiente. Si el producto va por lotes, el sistema los consume en el orden que marca la estrategia del producto (FIFO o FEFO), usando varios lotes si hace falta. Al confirmar, la salida pasa a completada y el stock baja.
Son las dos estrategias para decidir de qué lote sale la mercancía, y se eligen en la ficha del producto:
* **FIFO** ("primero en entrar, primero en salir"): sale antes lo que entró antes.
* **FEFO** ("primero en caducar, primero en salir"): sale antes lo que antes caduca. Es la opción natural para productos con caducidad.
Con un movimiento de inventario de tipo "salida". Indica el producto, el almacén, la cantidad y el motivo (rotura, merma, pérdida, consumo interno). El sistema no te deja retirar más de lo disponible en ese almacén.
Sí. Una devolución de compra (al proveedor) genera una salida de tu almacén cuando la confirmas en el flujo de la devolución.
### El flujo del documento (DataFlow) [#el-flujo-del-documento-dataflow]
Es la pantalla que centraliza todo lo relacionado con un documento: lo que se ha cobrado o pagado, las entradas y salidas de stock, y las devoluciones. Desde ahí confirmas recepciones, preparas salidas, registras cobros/pagos e inicias devoluciones.
* **Pendiente**: muestra lo que aún puedes hacer (por ejemplo, una entrada o salida que falta por confirmar) y el botón para añadirlo.
* **Historial**: muestra lo que ya se ha hecho, como consulta.
El flujo del documento calcula lo pendiente: cuántas unidades faltan por entrar o salir, y cuánto dinero falta por cobrar o pagar. Lo verás en la sección correspondiente como cantidad pendiente.
### Devoluciones [#devoluciones]
Desde el flujo de la venta, inicia una devolución. Se genera una venta rectificativa con las unidades e importes a devolver. Al confirmarla, la mercancía entra en tu almacén en cuarentena: suma al stock físico pero no al disponible hasta que la revisas.
Desde el flujo de la compra, inicia una devolución. Se genera una compra rectificativa. Esa devolución produce una salida de tu stock (la mercancía sale hacia el proveedor) cuando la confirmas.
No. No se puede rectificar un documento que ya es una rectificativa. Si necesitas corregir, trabaja sobre el documento original.
### Almacenes, zonas, huecos y plano [#almacenes-zonas-huecos-y-plano]
No. Los huecos son opcionales y solo sirven para control físico de ubicación. Para vender y llevar el stock basta con tener al menos un almacén; el sistema funciona sin huecos.
Son los huecos a los que va a parar la mercancía que entra, según el tipo de entrada (por ejemplo, un hueco de recepción para las compras y otro para las devoluciones de venta). Sirven para que, al confirmar una entrada, ya venga propuesto un destino dentro del almacén. Siempre puedes cambiarlo.
El plano es una representación visual de las zonas y huecos de un almacén. Sirve para que quien trabaja en el almacén vea de un vistazo dónde está cada ubicación. Es opcional: el inventario funciona aunque no dibujes ningún plano.
Sí. El diseñador de plano no es un boceto: cada hueco o zona que colocas se da de alta como ubicación real en el sistema. Colocarlo en el plano solo añade su posición visual.
Sí. Cada hueco puede tener un estado (por ejemplo, disponible, bloqueado, en mantenimiento) con un color asociado, para verlo rápidamente en el plano.
Sí, mediante movimientos de inventario: una salida en el almacén de origen y una entrada en el de destino. Son dos movimientos que reflejan el traslado.
El almacén de trabajo se asocia a cada empleado y se puede cambiar en la cabecera del TPV. El stock que ves en pantalla corresponde al almacén seleccionado.
### Lotes en detalle [#lotes-en-detalle]
Desde la gestión de inventario o al preparar un movimiento de un producto que va por lotes, usa la opción de crear lote. Indicas su código de referencia y los datos que quieras (tipo, estado, caducidad, avisos).
No. Un lote nace vacío. Para darle existencias, registra una entrada de inventario (o una entrada de compra) sobre ese lote indicando la cantidad. A partir de ahí el lote tiene stock.
Un código de referencia, un tipo, un estado (con color), fecha de inicio de disponibilidad, fecha de caducidad, fecha límite para devolver al proveedor, un aviso que se muestra al vender y observaciones internas. Solo el código y el producto son imprescindibles; el resto es opcional según lo que necesites controlar.
Para controlar productos perecederos. Con la fecha de caducidad registrada en cada lote y la sugerencia FIFO al preparar salidas (primero los lotes más antiguos), reduces el riesgo de que caduque mercancía.
Los estados (por ejemplo, disponible, en cuarentena, defectuoso) los define el administrador como un catálogo. Cada estado tiene un color y puede permitir o no la venta. Sirven para avisar al vendedor o para impedir vender lotes que no deben salir.
No en el uso actual. Se trabaja con un único tipo de lote: el lote de producto. Los lotes se crean igual tanto si la mercancía entra por una compra como si entra por un ajuste de inventario.
El lote pertenece al producto, no a un almacén. Lo que se lleva por almacén son las existencias: cuántas unidades hay de cada producto (y de cada lote) en cada almacén. Si quieres precisar la ubicación física dentro de un almacén, eso lo indican los huecos, no el lote.
### Movimientos manuales y ajustes [#movimientos-manuales-y-ajustes]
Es un movimiento manual para cuadrar el stock del sistema con lo que hay de verdad en el almacén. Un "ajuste de entrada" suma unidades (encontraste más de las registradas) y un "ajuste de salida" resta unidades (merma, rotura, pérdida).
Cuenta físicamente las unidades y compáralas con el sistema. Si sobran, registra una entrada de inventario por la diferencia; si faltan, una salida. Usa el motivo de ajuste correspondiente para dejar constancia.
El stock se recalcula solo. Tras registrar la entrada o salida, el sistema actualiza el stock disponible y físico del producto en ese almacén sin que tengas que hacer nada más.
No hay un "deshacer" directo, pero puedes corregirlo registrando el movimiento contrario (si sumaste de más, registra una salida por esa cantidad) o editando el movimiento desde el historial del producto.
En la ficha del producto, donde se listan sus entradas y salidas: qué cantidad, en qué almacén, con qué lote (si aplica) y por qué motivo.
Un ajuste puro de inventario (entrada o salida manual) regulariza existencias, pero no es una compra ni una venta. Los movimientos que sí afectan a ingresos o gastos son los de compra y venta.
### Multi-almacén [#multi-almacén]
Sí. El sistema es multi-almacén. Cada almacén tiene su propio stock de cada producto, y puedes controlar a qué almacenes accede cada empleado.
En la ficha del producto se muestra el stock por almacén: cuántas unidades hay en cada uno. Así ves dónde está repartida tu mercancía.
Sí. Los niveles de reposición (mínimo y máximo) se configuran por producto y almacén, porque cada almacén puede necesitar cantidades distintas.
### Problemas frecuentes (resumen rápido) [#problemas-frecuentes-resumen-rápido]
La compra es solo el documento. Entra al flujo de la compra y confirma la entrada (recepción) indicando almacén y, si procede, lote. El stock sube al confirmar la entrada.
La salida queda pendiente hasta que se prepara. El stock físico baja cuando la salida pasa a "completada". Prepara la salida desde el flujo de la venta.
La política de sobreventa del producto (o de la empresa) está en "Permitir" o "Avisar". Cámbiala a "Bloquear" en el producto: recorta la venta a lo disponible y nunca deja el stock en negativo.
No se pierde nada y no se descuenta dos veces. Un repaso periódico de seguridad recupera las ventas que quedaron sin movimiento, y cada movimiento es único: reprocesarlo no lo duplica.
Está en cuarentena: lo devuelto suma al stock físico pero queda fuera del disponible hasta que lo revisas. Es el comportamiento esperado, no un error.
Configura el stock mínimo de tus productos. Cuando el disponible baje del mínimo, el sistema te lo marca (por ejemplo en rojo) para que repongas.
Porque ese producto se gestiona "por cantidad" (sin lotes). El lote solo aparece en productos configurados en modo "por lotes".
Usa huecos. Crea las ubicaciones (y, si quieres, el plano) y asigna el hueco al confirmar las entradas. No es obligatorio para vender, solo para control físico.
***
## CRM y gestión comercial [#crm-y-gestión-comercial]
Una oportunidad representa una posible venta que sigues hasta cerrarla (ganada o perdida). Se crea desde la app de **CRM**, asociándola a un cliente y a un proceso de venta, y avanza por las fases de ese proceso a medida que progresa la negociación.
→ [CRM](/docs/rtg/crm)
El Kanban muestra tus oportunidades como tarjetas repartidas en columnas, una por cada fase del proceso de venta. Arrastras una tarjeta de una columna a otra para avanzar la oportunidad de fase, lo que te da una vista visual e inmediata de en qué punto está tu pipeline comercial.
Los seguimientos son las interacciones que mantienes con un cliente u oportunidad: llamadas, emails, reuniones o notas. Se registran desde la ficha del cliente o de la oportunidad en el CRM, y quedan en su historial para que todo el equipo vea el contexto de la relación.
Un proceso de venta define las fases por las que pasa una oportunidad, de principio a cierre. Configuras tus procesos y sus fases en el CRM para adaptarlos a tu forma de vender, y al crear una oportunidad eliges el proceso que debe seguir.
***
## Proyectos [#proyectos]
Los proyectos agrupan el trabajo de tu equipo en tareas. Se crean desde la app de **Proyectos**, dándole un nombre al proyecto y el flujo de trabajo con el que quieres organizar sus tareas.
→ [Proyectos](/docs/rtg/proyectos)
Cada proyecto se organiza con un tablero **Kanban**: las tareas son tarjetas que avanzan por columnas según su estado. Asignas cada tarea a una persona, sigues su progreso y registras el tiempo dedicado para tener un reporting de productividad.
Un flujo es el conjunto de estados (columnas) por los que pasa una tarea dentro de un proyecto, de inicio a fin. Los flujos son configurables, así que adaptas las fases del tablero a la forma de trabajar de cada equipo o tipo de proyecto.
***
## Contabilidad [#contabilidad]
Con la contabilización automática activada, las facturas de compra y venta generan sus asientos contables solas, según las cuentas que hayas configurado para cada tipo de operación. Se activa y configura desde **Pymes → Configuración → Contabilidad**.
* Ve a **Pymes → Contabilidad → Inmovilizados**
* Crea un nuevo inmovilizado
* Indica: descripción, valor de adquisición, fecha y vida útil
* Selecciona el método de amortización
* Las amortizaciones se calculan solas
* Ve a **Pymes → Procesos → Exportación**
* Selecciona el formato deseado (Excel, CSV o formatos contables estándar)
* Indica el período a exportar
* Descarga el archivo para enviarlo a tu asesor
***
## Nóminas [#nóminas]
Las nóminas viven en el módulo de Pymes, junto al resto de la gestión laboral y la documentación oficial del empleado. Desde ahí registras las nóminas de tu personal y las conservas asociadas a cada trabajador.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
***
## Inteligencia artificial [#inteligencia-artificial]
La IA de Dinaup te ayuda a no perder tiempo en lo repetitivo. Ya trabaja desde el primer día: durante el asistente 1Click sugiere categorías de gasto y reglas de clasificación según tu sector. Además, dispones de chat y agentes que operan sobre tus datos.
→ [Inteligencia Artificial](/docs/rtg/ia)
Sí. Sube la factura como foto o PDF en **IA → Digitalización** y la IA extrae el proveedor, la fecha, la base, el IVA y las líneas, y prepara el gasto listo para guardar. Tú revisas los datos y confirmas antes de grabar.
→ [Digitalización de facturas (OCR)](/docs/rtg/ia/digitalizacion-ocr)
***
# ¿Qué es Dinaup? (/docs/rtg/que-es-dinaup)
Dinaup es el **ERP** con el que llevas tu empresa: facturación, contabilidad, clientes, inventario, equipo, ventas. La diferencia con un ERP cerrado es que no te obliga a encajar tu negocio en su molde: **no adaptas tu empresa al software, adaptas el software a tu empresa**. Y lo haces sin programar, con la soltura de una hoja de cálculo.
Así encajan las piezas:
## Ready To Go: lo que toda empresa necesita [#ready-to-go-lo-que-toda-empresa-necesita]
Toda empresa necesita lo mismo de base: facturar, llevar la contabilidad, cobrar y pagar, gestionar clientes, organizar el trabajo. Reconstruir todo eso desde cero, solo para acabar personalizando una parte, no tiene sentido.
Por eso Dinaup incluye **Ready To Go**: módulos ya diseñados que cubren esas necesidades comunes y funcionan desde el primer día, sin desarrollo.
Facturación, inventario, contabilidad y tesorería.
Captación, seguimiento y fidelización de clientes.
Punto de venta táctil para comercio y hostelería.
Fichajes, horarios, turnos y vacaciones.
Tareas, Kanban y seguimiento de equipos.
Activas los que necesitas y empiezas a trabajar. Para facturar, solo hace falta una configuración fiscal mínima.
## Flex: lo que te hace único [#flex-lo-que-te-hace-único]
Lo estándar no cubre lo que de verdad diferencia a tu negocio: los procesos que solo tienes tú. Cada empresa los suyos. **Por ejemplo:**
Llevar las **bajas**, los **vehículos** y los **recambios**: qué entra, qué se despieza y qué se vende.
Las **partidas** y los **socios**, cuántos **hoyos** tiene cada pista y el **tiempo medio** que se pasa en ella.
Las **rutas**, los **albaranes** firmados y el estado de cada entrega.
Piénsalo un momento:
* ¿Qué llevas hoy en hojas sueltas, en un cuaderno o en la cabeza?
* ¿Qué te preguntan tus clientes que no sabes responder de un vistazo?
* ¿Qué tarea repites cada semana copiando datos de un sitio a otro?
Eso es lo que digitalizas con Flex.
Eso lo añades tú con **Flex**, la parte de Dinaup que te deja crecer sin programar. Igual que en una hoja de cálculo creas las hojas que necesitas, en Dinaup creas tantas **secciones, campos e informes** como te haga falta.
Y no es un Excel glorificado: lo que montas con Flex tiene la misma solidez que lo estándar.
PostgreSQL por debajo: ni se corrompe ni se atasca con millones de registros.
Quién ve qué, y cada cambio registrado: quién, cuándo y qué tocó.
Lees y escribes tus datos desde otras aplicaciones a través de su API.
Tus datos se copian en varias ubicaciones en cuanto cambian.
## Todo conectado [#todo-conectado]
Lo que añades con Flex se conecta con lo que ya tienes. Si montas las **rutas**, sus desplegables ya ofrecen los **empleados** y los **clientes** que tienes registrados.
No vuelves a teclear lo que Dinaup ya sabe: cada dato vive en un sitio y todo lo demás tira de ahí.
## Abierto: conéctalo y prográmalo [#abierto-conéctalo-y-prográmalo]
Tus datos no se quedan encerrados: salen y entran de Dinaup por varias vías.
Avisos en tiempo real cuando se crea o cambia un registro.
Automatiza con miles de apps, sin programar.
Programa tu propia lógica sobre tus datos.
Para perfiles técnicos: una biblioteca .NET generada a partir de tus secciones, campos e informes.
## Por dónde seguir [#por-dónde-seguir]
Crea tu cuenta y da tus primeros pasos.
Pymes, CRM, TPV, RRHH y Proyectos en detalle.
Secciones, campos, informes y automatizaciones.
Qué incluye cada plan.
# Configuración de Play (/docs/cuenta/gestion-de-usuarios/configuracion-de-play)
La **Configuración de Play** reúne los ajustes que se aplican a toda la empresa. Es un diálogo con pestañas y solo la ve el administrador.
***
## Antes de empezar [#antes-de-empezar]
* Necesitas ser **administrador** de la empresa.
***
## Pestañas [#pestañas]
### General [#general]
* **Aviso global**: un aviso con un tipo y un texto que se muestra a todos.
* **Elementos de interfaz**: mostrar cumpleaños de compañeros, desactivar la presencia de usuarios y desactivar las notas personales o de empresa.
* **Footer**: desactivar el chat de IA, las tareas, el soporte o las notas del pie.
### TPV [#tpv]
* **Comportamiento**: el modo de interfaz y el destino del botón de inicio.
* **Políticas**: solo el administrador edita precios, requerir cobrar para guardar e impresión automática del ticket.
### Pymes [#pymes]
* **Direcciones**: direcciones estrictas, validadas contra el callejero INE.
* **Ventas y pedidos**: mostrar "Crear Sustitutivas", número de pedido editable y los días del ciclo de vida del pedido.
* **Estados personalizados**: estados de venta, de compra y de pedido personalizados.
* **Inventario**: gestión de inventario físico.
* **Contabilidad**: gestión contable.
* **Tesorería**: gestión de tesorería.
* **Legacy**: desactivar los valores estrictos en facturas rectificativas.
### Email [#email]
* **Envío de facturas**: email de respuesta (Reply-To) y recibir copia al enviar.
* **Recursos Humanos**: email para la auditoría de eventos.
* **SMTP personalizado**: servidor, puerto, SSL/TLS, usuario, contraseña y datos del remitente.
### Integraciones [#integraciones]
* **Documenso**: la clave API.
* **Ntfy**: la URL y el token.
### Ritmos [#ritmos]
* **Ejecución**: requerir observaciones al ejecutar un ritmo y que solo el responsable asignado pueda ejecutar.
* **Visibilidad**: ocultar la sección de plantillas.
### RRHH [#rrhh]
Políticas de empleados para horarios, doble factor de autenticación, localización de trabajo, almacén predeterminado de TPV y calendario de festivos.
### IA [#ia]
* **Contexto de análisis**: el texto de contexto para el análisis de ventas y el de compras.
* **Límites de gasto**: el máximo de euros semanales por usuario.
* **Eliminación de fondo**: la calidad del modelo.
* **Voz**: la calidad de voz.
* **Modelo por defecto**: el modelo de IA para los agentes.
***
Los cambios se aplican con **Guardar**.
# Gestión de Usuarios (/docs/cuenta/gestion-de-usuarios)
Cada usuario de tu empresa tiene un **nivel de acceso** y un conjunto de **permisos** que determinan a qué aplicaciones y funciones puede entrar.
## Tipos de usuario [#tipos-de-usuario]
El nivel define el alcance general del acceso, de mayor a menor.
| Nivel | Acceso |
| ------------- | ---------------------------------------------------- |
| Administrador | Acceso total. Incluye App Live. |
| Estándar | Acceso de trabajo a las aplicaciones según permisos. |
| Básico | Acceso limitado a las aplicaciones según permisos. |
| Lectura | Solo acciones de lectura. |
## Permisos [#permisos]
Cada permiso habilita una aplicación o una capacidad concreta. Los marcados como peligrosos dan acceso a información sensible o a configuración crítica.
| Permiso | Qué habilita |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| RTG Pymes | Acceso a [Ready To Go Pymes](/docs/rtg/pymes). |
| RTG Desktop / Flex | Acceso a la aplicación Desktop. |
| RTG Marketing | Acceso a la aplicación de Marketing. |
| RTG CRM | Acceso a [Ready To Go CRM](/docs/rtg/crm). |
| RTG ToDo | Acceso a la aplicación ToDo. |
| RTG RRHH | Acceso a [Ready To Go Recursos Humanos](/docs/rtg/recursos-humanos). |
| RTG TPV | Acceso a [Ready To Go TPV](/docs/rtg/tpv). |
| Live | Monitorizar en tiempo real la actividad de los usuarios. Solo administradores. |
| Servicios de IA | Funciones de Dinaup que usan Inteligencia Artificial. Puede tener cargos extra por uso. |
| Desarrollador (peligroso) | Herramientas de desarrollo, personalización avanzada y configuración técnica (puede incluir Flex, SDKs). Puede dar acceso a información sensible o configuración crítica. |
| Soporte (peligroso) | Funciones de soporte técnico: ver y gestionar tickets, herramientas de asistencia. |
| Administrar usuarios (peligroso) | Crear, editar, desactivar y gestionar permisos de otros usuarios de la empresa. Puede dar acceso a información sensible o configuración crítica. |
| Dinaup Flex (muy peligroso) | Acceso a [Dinaup Flex](/docs/desarrollo/flex) para personalización avanzada (Secciones, Informes, Documentos Dinámicos, Scripts, Flujos). Permite alterar la funcionalidad central del sistema e incurrir en gastos de desarrollo. Asignar solo a personal técnico cualificado. |
| Gestionar Suscripción Dinaup | Ver y administrar la facturación y la suscripción de la empresa: costes, métodos de pago, alta/baja de licencias o módulos y cambio de plan. |
# Declaración responsable del sistema informático de facturación. (/docs/cuenta/legal/declaracion-verifactu)
#### DECLARACIÓN RESPONSABLE [#declaración-responsable]
DEL SISTEMA INFORMÁTICO DE FACTURACIÓN
1.a) **Nombre del sistema informático:** Dinaup\
1.b) **Código identificador del sistema informático:** UP\
1.c) **Identificador completo de la versión del sistema informático:** 62.6856
1.d) **Componentes, hardware y software, descripción y principales funcionalidades:**
* **Dinaup SRV:** servicio cloud que guarda las facturas, genera la huella SHA-256 y el código QR y, **según la configuración**,\
– **envía/reintenta directamente** los registros a la AEAT, **o bien**\
– **los remite al componente funcional externo “Verifacti Bilbabit”** para que éste los empaquete y los envíe a la AEAT.
* **play.dinaup.com:** aplicación web para usuarios finales (expedición/consulta de facturas, estadísticas, exportaciones).
* **api.dinaup.com** y **webhook.dinaup.com:** endpoints REST y Webhooks para alta masiva de facturas desde otras aplicaciones.
1.e) **Indicación de si el sistema solo puede funcionar como «VERI\*FACTU»:** S – Sí
1.f) **Indicación de si el sistema permite facturar a varios obligados tributarios:** S – Sí
1.g) **Tipos de firma utilizados si no se empleara «VERI\*FACTU»:** No aplica. Al operar exclusivamente en modo «VERI\*FACTU», los registros quedan firmados mediante su remisión autenticada a la AEAT con certificado cualificado.
1.h) **Razón social de la entidad productora:** Dinaup Software SL\
1.i) **NIF de la entidad productora:** B09689647\
1.j) **Dirección postal de contacto de la entidad productora:**\
C/ Vicente Blasco Ibáñez 98, 4º P2, 03201 Elche (Alicante), España
1.k) **Manifestación de cumplimiento normativo:**\
La entidad productora declara que este sistema informático, en la versión indicada, cumple lo dispuesto en el artículo 29.2.j) de la Ley 58/2003 (LGT), en el Reglamento aprobado por RD 1007/2023, de 5 de diciembre, en la Orden HAC/1177/2024, de 17 de octubre, y en las especificaciones complementarias publicadas en la sede electrónica de la AEAT.
1.l) **Fecha y lugar de suscripción de la declaración responsable:**\
Elche (Alicante, España), 14 de julio de 2025
***
**ANEXO**
2.a) **Otras formas de contacto con la entidad productora:**\
- **Teléfono**: 687 29 55 37\
- Correo electrónico: [info@dinaup.com](mailto:info@dinaup.com)
2.b) **Direcciones de internet de la entidad productora:**\
- Sitio web corporativo: [https://www.dinaup.com/](https://www.dinaup.com/)\
- Información del producto: [https://play.dinaup.com/](https://play.dinaup.com/)\
- Histórico de declaraciones responsables: [https://dinaup.com/verifactu/historico-drs](https://dinaup.com/verifactu/historico-drs)
2.c) **Descripción técnica del cumplimiento de especificaciones:**\
– **Persistencia inmediata** de la factura y del registro de facturación en PostgreSQL dentro de la misma transacción.\
– Tras la confirmación de escritura, **un servicio en segundo plano** intenta remitir el registro a la AEAT (o al CF externo “Verifacti Bilbabit”).\
– Si no hay conexión o se recibe un error temporal, el registro queda marcado como “pendiente” y se reintenta con back-off exponencial hasta recibir el acuse de la AEAT.
***
**Firma:**\
*Ángel Albaladejo Belmonte*\
Administrador, Dinaup Software SL
# Legal (/docs/cuenta/legal)
Términos, políticas y declaraciones que rigen el uso de Dinaup por parte de tu empresa.
# Manifiesto de Privacidad, Soberanía y Seguridad de Datos (/docs/cuenta/legal/manifiesto-de-privacidad-soberania-y-seguridad-de-datos)
En **Dinaup Software SL** nos comprometemos a proteger la privacidad, soberanía y seguridad de los datos de nuestros clientes. Creemos firmemente que la información es un activo valioso y personal, y es nuestra responsabilidad garantizar su integridad y confidencialidad.
**Dinaup Software SL** a partir de ahora **Dinaup.**
***
**1. Introducción**\
En **Dinaup**, entendemos que la confianza es la base de cualquier relación. Este manifiesto expone nuestro compromiso con la transparencia, la integridad y la protección de la información que nos confían nuestros clientes.
***
**2. Principios Fundamentales**
* **Transparencia:** Informamos de forma clara y accesible sobre la recopilación, uso y protección de los datos.
* **Integridad:** Actuamos con los más altos estándares éticos y de seguridad en todas nuestras operaciones.
* **Responsabilidad:** Nos comprometemos a gestionar la información de manera segura y respetuosa, reconociendo su valor para nuestros clientes.
***
**3. Privacidad de los Datos**
* **Recopilación Responsable:** Solo recopilamos los datos estrictamente necesarios para ofrecer nuestros servicios.
* **Uso Restringido:** Los datos se utilizan exclusivamente para los fines establecidos y en beneficio directo del cliente.
* **Confidencialidad:** No compartimos la información con terceros sin el consentimiento expreso del cliente, salvo lo requerido por la ley.
***
**4. Soberanía de los Datos**
* **Control del Cliente:** Los clientes mantienen el control absoluto sobre sus datos, decidiendo cómo y cuándo se utilizan.
* **Respeto a la Autonomía:** Nos comprometemos a no utilizar la información de manera que pueda interpretarse como una apropiación indebida o alteración del control del cliente sobre sus propios datos.
***
**5. Medidas de Seguridad**
* **Protección Tecnológica:** Implementamos sistemas de encriptación, firewalls y otras tecnologías de seguridad de última generación para resguardar la información.
* **Auditorías Regulares:** Realizamos revisiones y auditorías periódicas para garantizar la integridad de nuestros sistemas y procesos.
* **Formación Continua:** Nuestro equipo se capacita constantemente en las mejores prácticas de seguridad y privacidad.
***
**6. Cumplimiento Normativo**\
Nos adherimos a todas las normativas y regulaciones vigentes en materia de protección de datos, tales como el GDPR, CCPA y otras leyes locales aplicables, colaborando activamente con las autoridades competentes para asegurar el cumplimiento de nuestras políticas.
***
**7. Actualización y Retroalimentación**
* **Revisión Periódica:** Este manifiesto se revisa y actualiza regularmente para adaptarse a las nuevas tecnologías, normativas y mejores prácticas.
* **Contacto Abierto:** Invitamos a nuestros clientes a enviar cualquier consulta, sugerencia o inquietud a través de [info@dinaup.com](mailto:info@dinaup.com) , para seguir mejorando nuestros procesos.
# Política de Impagos de Dinaup (/docs/cuenta/legal/politica-de-impagos-de-dinaup)
Este documento detalla las medidas que se aplican en caso de facturación vencida, las consecuencias en el uso de la plataforma y los pasos para reactivar el servicio.
### 1. Facturas vencidas y acceso limitado [#1-facturas-vencidas-y-acceso-limitado-]
Si una factura llega a su fecha de vencimiento sin haberse abonado, la cuenta correspondiente entrará temporalmente en modo de solo lectura. Esto significa que se desactivarán las opciones de creación o edición de contenido en su cuenta, y solo podrá consultar o leer los datos ya existentes en la plataforma. Del mismo modo, cualquier otro servicio o proceso en curso entre el cliente y Dinaup quedará suspendido mientras exista la factura impagada.
Adicionalmente, para garantizar la seguridad y un control centralizado en situaciones de impago, se podrán limitar los usuarios que tienen permitido iniciar sesión en la cuenta. En estos casos, únicamente el empleado principal o el dueño de la licencia estará autorizado para acceder al sistema, asegurando así que la gestión de la cuenta se realice de forma concentrada hasta regularizar la situación.
Este cambio de estado es una medida preventiva y reversible: no implica la pérdida de sus datos ni la cancelación inmediata de su licencia. La intención es recordar al cliente la necesidad de regularizar el pago pendiente, al tiempo que se protege la integridad de la plataforma y se evitan nuevos cargos o modificaciones hasta resolver la situación. Una vez realizado el pago, la cuenta saldrá del modo de solo lectura, se restaurarán las funciones completas y se restablecerá el acceso para el resto de los usuarios.
### 2. Periodo prolongado de impago (hasta 6 meses) [#2-periodo-prolongado-de-impago-hasta-6-meses-]
Entendemos que pueden surgir contratiempos, pero si la situación de impago se extiende durante un periodo prolongado (por ejemplo, alrededor de seis meses, salvo que se haya establecido un plazo distinto para su caso), existe la posibilidad de pérdida de acceso a la cuenta. En otras palabras, tras varios meses sin recibir el pago, Dinaup podría proceder a la cancelación de la licencia asociada a su cuenta, lo que conllevaría el cierre de la misma y la imposibilidad de ingresar al servicio.
No obstante, antes de llegar a ese extremo, le garantizamos que tendrá la oportunidad de resguardar sus datos. Dinaup permitirá al cliente descargar toda la información de su cuenta en formato CSV (u otro formato estándar) para que pueda conservarla localmente. Le notificaremos con antelación sobre esta opción de exportación de datos, de modo que pueda salvaguardar su información importante. Nuestro objetivo es que, incluso en caso de impago prolongado, usted no pierda sus datos y esté al tanto de la situación de su cuenta en todo momento.
### 3. Reactivación del servicio y restauración de la cuenta [#3-reactivación-del-servicio-y-restauración-de-la-cuenta-]
Si el pago pendiente se regulariza antes de la cancelación de la licencia, reactivaremos su servicio de forma normal. Esto significa que se restablecerá el acceso completo a su cuenta y todas las funcionalidades volverán a estar operativas sin inconvenientes. Sus datos, configuraciones y contenidos permanecerán intactos, por lo que podrá continuar trabajando en la plataforma una vez acreditado el pago. Ponerse al día con una factura vencida revierte inmediatamente las restricciones temporales de la cuenta.
En el caso de que la licencia ya haya sido cancelada tras un impago prolongado, el proceso es diferente. Deberá contactar a nuestro equipo de soporte para evaluar la situación y las posibles vías de solución. Nuestro equipo revisará su caso particular para determinar si es posible reactivar la cuenta, qué pasos serían necesarios y si procede la restauración de los datos. Dinaup analizará cada situación individual de forma equitativa; aunque no se garantiza la reactivación automática después de una cancelación, haremos todo lo posible por ayudarle a recuperar el acceso o, al menos, a obtener sus datos si aún no los hubiera descargado.
### 4. Información adicional, prevención y contacto [#4-información-adicional-prevención-y-contacto-]
En Dinaup creemos que la prevención y la comunicación son clave para evitar llegar a escenarios de impago prolongado. A continuación, le ofrecemos información adicional y consejos para evitar estas situaciones, así como los canales de contacto disponibles para resolver cualquier duda o inconveniente:
* Mantenga sus datos de pago actualizados: Verifique periódicamente que la forma de pago registrada (tarjeta de crédito, cuenta bancaria, etc.) esté vigente y con fondos suficientes. Una tarjeta expirada o datos desactualizados pueden derivar en un pago rechazado accidentalmente. Mantener esta información al día ayuda a evitar interrupciones en el servicio.
* Esté atento a las notificaciones de Dinaup: Nuestro sistema de facturación envía recordatorios y avisos antes y después de la fecha de vencimiento de una factura. Revise su correo electrónico (incluida la bandeja de spam) u otros medios de contacto que haya proporcionado, para no pasar por alto estas comunicaciones importantes. Estos recordatorios tienen el fin de ayudarle a regularizar el pago a tiempo y evitar medidas restrictivas.
* Comuníquese si tiene dificultades de pago: Si atraviesa por problemas financieros o cualquier circunstancia que le impida realizar un pago puntual, le animamos a que se ponga en contacto con nosotros cuanto antes. Nuestro equipo de soporte está dispuesto a escuchar y buscar soluciones. En algunos casos, podríamos evaluar opciones como establecer un plan de pagos o conceder una prórroga, siempre dentro de las políticas de la empresa, para facilitarle el cumplimiento de sus obligaciones y mantener activo su servicio.
* Derechos sobre sus datos: Recuerde que los datos que almacena en Dinaup son de su propiedad. Incluso en situaciones de impago, nos aseguraremos de que tenga la posibilidad de recuperar su información (por ejemplo, mediante la descarga de archivos CSV mencionada anteriormente). Dinaup se compromete a no eliminar ni bloquear permanentemente sus datos sin previo aviso, dándole la oportunidad de resguardarlos. Su tranquilidad y confianza son importantes para nosotros.
* Canales de contacto y soporte: Para cualquier consulta adicional, duda sobre una factura o asistencia relacionada con su cuenta, puede contactar con nuestro equipo de soporte. Estamos disponibles a través de los siguientes medios:
* Correo electrónico: [soporte@dinaup.com](mailto:soporte@dinaup.com) (responderemos a la brevedad).
# Términos y Condiciones de Uso v2.1 (/docs/cuenta/legal/terminos-y-condiciones-de-uso-v2.1)
### 1. Definiciones [#1-definiciones]
| Término | Significado |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Dinaup** | Dinaup Software, S.L., CIF B‑09689647, con domicilio en C/ Vicente Blasco Ibáñez 98, 4º 2ª, 03201 Elche (Alicante, España). |
| **Titular de la Cuenta (Cliente)** | Entidad jurídica que contrata la licencia y figura como titular de la cuenta Dinaup. |
| **Usuario** | Persona física que accede a la Plataforma bajo la responsabilidad del Titular: administradores, empleados, contratistas o Partners autorizados. |
| **Servicios** | Conjunto de soluciones SaaS ofertadas por Dinaup (CRM, ERP, Contabilidad, etc.) y los Servicios Profesionales relacionados. |
| **Módulo** | Funcionalidad individual que el Cliente puede activar o desactivar (p. ej. “Ventas”, “Facturación”). |
| **Dinaup Flex** | Herramientas internas de desarrollo/parametrización que permiten crear secciones, campos, informes y documentos dinámicos dentro de la Plataforma. |
| **Custom Solution** | Personalización o desarrollo a medida ejecutado por Dinaup sobre la Plataforma. |
| **Ready‑to‑Go Solution** | Módulo o conjunto de módulos estándar disponible sin personalización. |
| **Servicios Profesionales** | Mano de obra (consultoría, formación, integraciones, desarrollo) facturada aparte. |
| **Partner** | Tercero autorizado a comercializar, parametrizar o gestionar licencias Dinaup en nombre de un Cliente. |
| **Terceros Críticos** | Proveedores cuya infraestructura es esencial para prestar el Servicio (p. ej. OVH Cloud, Cloudflare, Stripe). |
| **Política de Uso Responsable (PUR)** | Documento que detalla los límites orientativos de recursos para entornos Dinaup “Administrados”. Disponible en: [https://www.dinaup.com/pur/v1.pdf](https://www.dinaup.com/pur/v1.pdf). |
| **Order Form** | Documento (electrónico o escrito) que recoge precios, descuentos o condiciones comerciales específicas acordadas entre Dinaup y un Cliente concreto; prevalece sobre la tarifa estándar publicada. |
***
### 2. Ámbito de aplicación y aceptación [#2-ámbito-de-aplicación-y-aceptación]
2.1. Estos Términos regulan la relación contractual entre Dinaup y el **Titular de la Cuenta ("Cliente")**, y rigen el acceso y uso de los Servicios por todos los **Usuarios autorizados** (incluidos administradores, empleados y Partners).
2.2. **Acción afirmativa.** Al marcar la casilla “Acepto los Términos y Condiciones” o al continuar utilizando el Servicio, el Usuario confirma (i) haber leído y comprendido el texto íntegro; (ii) aceptarlo sin reservas; y (iii) **ostentar poder suficiente para obligar a la entidad a la que representa.**
2.3. Dinaup mantiene una copia inmutable de cada versión en soporte duradero ([https://www.dinaup.com/tyc/v2.0.pdf](https://www.dinaup.com/tyc/v2.0.pdf)). La versión indicada en la base de datos de Dinaup junto con la marca de tiempo de aceptación será prueba plena del consentimiento.
2.4. **Firma electrónica.** Las Partes aceptan equiparar jurídicamente la firma autógrafa del Cliente a la realizada mediante cualquier sistema de firma electrónica u otro elemento de seguridad identificativo (p. ej. clic de aceptación, clave OTP, certificado digital). No obstante, Dinaup podrá exigir, cuando lo considere necesario, confirmación por escrito o documentación adicional que acredite la identidad y facultades de quien firma.
***
### 3. Registro de la Cuenta [#3-registro-de-la-cuenta]
3.1. **Requisitos.** El Servicio se dirige exclusivamente a actividad profesional o empresarial; queda excluido el uso estrictamente doméstico. El Usuario debe ser mayor de 16 años y disponer de capacidad legal para contratar. **Asimismo, el Usuario deberá proporcionar, como mínimo, la denominación social completa del Titular, un correo electrónico corporativo válido y cualquier otra información que Dinaup requiera durante el proceso de creación de la cuenta.**
3.2. **Veracidad de los datos.** El Usuario garantiza que la información facilitada (denominación social, CIF/NIF, domicilio y contacto) es exacta y se compromete a mantenerla actualizada.
3.3. **Custodia de credenciales.** El Usuario es responsable de la confidencialidad de su cuenta y contraseña. Cualquier operación realizada con sus credenciales se considerará efectuada por el Usuario o bajo su autorización. **Dinaup no será responsable de los daños, pérdidas o consecuencias que se deriven de un uso no autorizado o negligente de dichas credenciales.**
3.4. Dinaup podrá solicitar documentación acreditativa (poderes, alta censal) y **suspender provisionalmente** la cuenta hasta verificar los datos.
3.5. **Recuperación de acceso por el Titular.** A solicitud del representante legal del Titular de la Cuenta, Dinaup (una vez verificada su identidad y poderes de representación) podrá revocar las credenciales de cualquier Usuario y otorgar privilegios de administrador a la persona designada, con el único fin de salvaguardar la continuidad del servicio. Esta intervención no convierte a Dinaup en parte de las relaciones internas del Titular.
***
### 4. Modelo de Servicio (Módulos dinámicos) [#4-modelo-de-servicio-módulos-dinámicos]
4.1. El Cliente puede activar/desactivar módulos en la Plataforma. Cada módulo activo genera la cuota diaria **(i) publicada en el Panel de control y en** [**https://www.dinaup.com/pricing**](https://www.dinaup.com/pricing)**, o (ii) la cuota personalizada acordada en un Order Form firmado**; la facturación se calcula **prorrateada por días naturales**. 4.2. La Plataforma muestra en tiempo real la estimación de coste mensual según módulos y usuarios asignados.\
4.3. La activación inicial de los Servicios se produce tras introducir un método de pago válido.\
4.4. Para entornos Dinaup “Administrados” rigen los límites orientativos descritos en la PUR; para licencias *on‑premise*, los únicos límites serán los de la infraestructura del Cliente.
***
### 5. Tarifas, facturación e impuestos [#5-tarifas-facturación-e-impuestos]
5.1. **Facturación.** Las cuotas correspondientes a los módulos activos (según la tarifa estándar o la tarifa personalizada establecida en un Order Form) y, en su caso, los Servicios Profesionales se facturan mensualmente a mes vencido y se cargan automáticamente en el método de pago registrado (tarjeta o SEPA). 5.2. **Impuestos.** Todos los precios se entienden sin IVA u otros impuestos indirectos, que se repercutirán según normativa.\
5.3. **Impago.** El retraso o devolución del recibo facultará a Dinaup a (i) suspender la cuenta; y (ii) aplicar intereses legales. Si la deuda persiste 30 días, Dinaup podrá cancelar definitivamente el acceso y eliminar los datos.
***
### 6. Políticas complementarias [#6-políticas-complementarias]
6.1. **Política de Uso Responsable** – límites de CPU, memoria, peticiones API y espacio para entornos Administrados.\
6.2. **Política de Devoluciones** – reembolso completo: (i) altas nuevas ≤ 30 días; (ii) renovaciones ≤ 7 días.\
6.3. **Seguridad de claves API** – custodia, revocación y notificación de incidentes.\
Todas las políticas forman parte integrante de estos Términos y se publican en [https://www.dinaup.com/legal](https://www.dinaup.com/legal).
***
### 7. Propiedad Intelectual [#7-propiedad-intelectual]
7.1. Dinaup conserva todos los derechos de propiedad intelectual sobre la Plataforma, Dinaup Flex y cualquier Custom Solution, salvo pacto escrito contrario. El Cliente recibe una **licencia de uso limitada, no exclusiva, revocable y no transferible** para su actividad interna.\
7.2. Las contribuciones de los Usuarios en repositorios gestionados por Dinaup (p. ej. GitHub) se integrarán bajo licencia MIT o equivalente, sin que ello suponga cesión de titularidad a favor del Usuario.\
7.3. Dinaup podrá migrar o reconvertir una Custom Solution a Ready‑to‑Go cuando sea necesario para garantizar calidad o escalabilidad, notificándolo con 30 días de antelación.
***
### 8. Protección de Datos [#8-protección-de-datos]
8.1. Roles. Dinaup actúa como **Encargado del Tratamiento** respecto de los datos que el Cliente aloje en la Plataforma y como **Responsable** respecto de sus propios datos de contacto y facturación.\
8.2. Subencargados esenciales: OVH Cloud (hosting), Cloudflare (CDN), Stripe (pasarela de pago). Todos ubicados en la UE o cubiertos por cláusulas contractuales tipo.\
8.3. Dinaup accederá a los datos del Cliente solo para (i) prestar soporte; (ii) mantenimiento y mejora; o (iii) cumplir una obligación legal.\
8.4. El Cliente garantiza haber informado a los interesados y disponer de base jurídica para el tratamiento.\
8.5. El Acuerdo de Encargo de Tratamiento completo figura en el Anexo II.
***
### 9. Limitación de responsabilidad [#9-limitación-de-responsabilidad]
9.1. El Servicio se presta **“tal cual”** y **“según disponibilidad”**. Dinaup no garantiza ausencia total de errores o interrupciones.
9.2. Dinaup, sus afiliados y proveedores no serán responsables de daños indirectos, pérdida de beneficios o datos.
9.3. La responsabilidad total agregada de Dinaup por todas las reclamaciones no excederá (a) la suma pagada por el Cliente durante los 12 meses anteriores al hecho generador, excluidos Servicios Profesionales, o (b) 100 €, la que sea superior.
9.1
***
### 10. Indemnización [#10-indemnización]
El Cliente indemnizará y mantendrá indemne a Dinaup frente a reclamaciones de terceros que se deriven de (i) uso ilícito o contrario a la PUR; (ii) infracción de derechos de terceros; o (iii) incumplimiento de estos Términos.
***
### 11. Modificación de Términos y Servicios [#11-modificación-de-términos-y-servicios]
11.1. Dinaup podrá actualizar los Términos, precios o funcionalidades notificándolo con **30 días** de antelación por email y en el Panel.\
11.2. La continuación en el uso tras la fecha efectiva implica aceptación de la nueva versión. Si el Cliente no la acepta, podrá cancelar la cuenta sin penalización antes de la entrada en vigor.
***
### 12. Cancelación y portabilidad de datos [#12-cancelación-y-portabilidad-de-datos]
12.1. El Cliente puede cancelar la cuenta en cualquier momento desde el Panel.
12.2. Tras la cancelación, los datos permanecerán disponibles **30 días** para descarga en formato estándar (CSV/ZIP).
12.3. Transcurrido dicho plazo, Dinaup eliminará los datos de forma irreversible salvo obligación legal de conservación.
***
### 13. Integraciones, Terceros y Partners [#13-integraciones-terceros-y-partners]
13.1. Dinaup facilita integraciones con servicios de terceros; estos operan de forma independiente. El uso se realiza bajo riesgo exclusivo del Cliente, que deberá revisar sus políticas de seguridad y privacidad.
13.2. **Relación Partner‑Cliente independiente.** El Partner actúa siempre en nombre y por cuenta propia. Cualquier acuerdo comercial, de soporte o de nivel de servicio entre Partner y Cliente es ajeno a Dinaup. El Cliente reconoce que Dinaup no es parte de dicha relación y, por tanto, no será responsable de los actos, omisiones o incumplimientos del Partner, ni de los daños que puedan derivarse de esa relación.
13.5. **Obligaciones mínimas del Partner.** El Partner se compromete a actuar de buena fe, respetar la libertad del Cliente y garantizar el acceso a sus datos incluso tras la finalización de la relación comercial. El Partner responderá directamente frente al Cliente de cualquier perjuicio causado por su actuación.
13.4. **Indemnidad de Dinaup.** El Cliente y/o el Partner mantendrán indemne a Dinaup frente a cualquier reclamación, daño o coste (incluidos honorarios legales) que se derive de la relación entre ambos, incluyendo, pero no limitado a, incumplimientos contractuales, pérdida de datos, uso indebido de credenciales o violación de la normativa de protección de datos.13.3. En caso de conflicto Partner‑Cliente, Dinaup facilitará al Titular un acceso temporal de solo lectura previa verificación de identidad.
### **16. Claves API** [#16-claves-api]
**16.1 Creación y Custodia**\
16.1.1. Toda API Key será generada exclusivamente por un Usuario con rol de **Administrador**, mediante la funcionalidad “Integraciones/API” del Panel de Control.\
16.1.2. Las claves API quedarán bajo la responsabilidad única del Administrador que la genere, quien deberá custodiarla y protegerla de accesos no autorizados.
**16.2 Uso, Distribución y Revocación**\
16.2.1. El Administrador podrá compartir los credenciales API con terceros (Partners, desarrolladores u otros Usuarios autorizados) bajo su propio riesgo y responsabilidad.\
16.2.2. Dinaup no asumirá responsabilidad alguna por las operaciones, divulgaciones, accesos o incidentes que se deriven del uso, transmisión o gestión de las API Keys por parte de Administradores o terceros.\
16.2.3. El Administrador podrá revocar o regenerar la clave en cualquier momento desde el Panel de Control. Asimismo, Dinaup se reserva el derecho de revocar de oficio cualquier API Key si detecta un incumplimiento grave de seguridad o de las presentes Condiciones.
**16.3 Exención de Responsabilidad e Indemnidad**\
16.3.1. En ningún caso Dinaup responderá por daños, perjuicios o reclamaciones de terceros derivadas del uso o la compartición de las API Keys generadas por Administradores, incluyendo pero no limitado a terceros externos, Partners o desarrolladores.\
16.3.2. El Cliente y sus Partners indemnizarán y mantendrán indemne a Dinaup frente a cualquier coste, reclamación o pérdida que resulte de la creación, uso, gestión o divulgación de API Keys por parte de sus Administradores o terceros a quienes éstas hayan sido facilitadas.
**16.4 Buenas Prácticas (Recomendación)**\
Aunque no sea obligatorio, Dinaup recomienda:
* Rotar las API Keys al menos cada 90 días.
* Utilizar canales cifrados o gestores de secretos para su almacenamiento y transmisión.
* Documentar internamente quién, cuándo y para qué entorno se generó cada clave.
***
### 14. Ley aplicable y jurisdicción [#14-ley-aplicable-y-jurisdicción]
Estos Términos se rigen por la legislación española. Las Partes se someten a la jurisdicción exclusiva de los Juzgados y Tribunales de Alicante, con renuncia expresa a cualquier otro fuero que pudiera corresponderles.
***
### 15. Contacto [#15-contacto]
Dinaup Software, S.L.\
C/ Vicente Blasco Ibáñez 98, 4º 2ª\
03201 Elche (Alicante, España)\
[info@dinaup.com](mailto:info@dinaup.com) | +34 687 295 537
***
### Anexo I – Referencia de tarifas [#anexo-i--referencia-de-tarifas]
Las tarifas base y la metodología de cálculo (cuota diaria prorrateada por módulo) se publican y actualizan en todo momento en [https://www.dinaup.com/pricing](https://www.dinaup.com/pricing). Dinaup podrá ofrecer descuentos o precios personalizados mediante un Order Form, cuya aceptación prevalecerá sobre la tarifa base. Dinaup notificará cualquier modificación de las tarifas base con treinta (30) días de antelación a los administradores de la cuenta.
***
# Términos y Condiciones de Uso (/docs/cuenta/legal/terminos-y-condiciones-de-uso)
## 1. Definiciones [#1-definiciones]
1.1 **Dinaup**
Se refiere a la empresa, "Dinaup SOFTWARE SL", que ofrece soluciones de software como servicio (SaaS) y otros servicios relacionados. Dinaup es el proveedor de los servicios y soluciones mencionadas, operando bajo las leyes de España, con domicilio social en CALLE VICENTE BLASCO IBAÑEZ, 98 - PISO 4 2, 3201 ELCHE/ELX, Alicante, España. Representa la entidad legal que establece los términos bajo los cuales ofrece sus productos y servicios a los usuarios.
1.2 **Usuarios**
Son las personas, empresas o entidades que acceden y utilizan los servicios y soluciones ofrecidos por Dinaup. Los usuarios aceptan los términos y condiciones establecidos por Dinaup al utilizar sus servicios. Pueden incluir tanto a individuos que usan los servicios para fines personales (en la medida en que Dinaup lo permita) como a empresas que utilizan las soluciones para fines comerciales.
1.3 **Custom Solution (Solución a Medida)**
Servicio de personalización de la plataforma Dinaup para adaptar sus funcionalidades a los procesos de cada cliente. Dinaup realiza los ajustes y configuraciones necesarias para tu negocio, pero conserva todos los derechos de propiedad intelectual sobre el software resultante.
1.4 **Dinaup Flex**
Conjunto de herramientas de desarrollo de Dinaup que incluye la creación de secciones, campos, informes, documentos dinámicos y cualquier otra funcionalidad que proporcione Dinaup. Aunque los Usuarios utilicen Dinaup Flex para crear y adaptar funcionalidades, Dinaup SOFTWARE SL conserva **la propiedad intelectual exclusiva** de todos los desarrollos realizados con estas herramientas.
1.5 **Soluciones**
Se refiere a los productos y servicios de software como servicio (SaaS) proporcionados por Dinaup, incluyendo, pero no limitado a, gestión de proyectos, CRM, facturación, contabilidad y servicios de marketing. Las soluciones pueden ser personalizadas (custom solutions) o listas para usar (ready to go), dependiendo de las necesidades del usuario.
1.6 **Afiliados, partners y colaboradores**
Son otras empresas, individuos o entidades que trabajan en asociación o colaboración con Dinaup para complementar, distribuir, promocionar o mejorar las soluciones y servicios ofrecidos. Esto puede incluir desde proveedores de infraestructura hasta socios de ventas y distribuidores autorizados que ayudan a ampliar el alcance y la eficacia de las soluciones de Dinaup.
1.7 **Servicios profesionales**
Engloba los servicios adicionales ofrecidos por Dinaup que van más allá del acceso estándar a sus soluciones SaaS. Incluyen servicios personalizados como mano de obra (por ejemplo, desarrollo a medida), instalaciones, configuraciones, consultorías, formación y cualquier otro servicio facturado por Dinaup en concepto de mano de obra. Estos servicios suelen estar diseñados para adaptar las soluciones de Dinaup a las necesidades específicas del usuario, asegurando una integración efectiva y un uso óptimo de las plataformas y herramientas proporcionadas.
1.8 **Terceros**
Se refiere a empresas, organizaciones o entidades externas que proporcionan servicios esenciales o complementarios necesarios para que Dinaup pueda ofrecer sus propios servicios y soluciones a los usuarios. Estos terceros pueden incluir proveedores de infraestructura tecnológica, como OVH para servicios de hosting; plataformas de procesamiento de pagos, como Stripe; y servicios de seguridad y optimización de la entrega de contenido en línea, como Cloudflare. La relación con estos terceros es fundamental para el funcionamiento, la seguridad, la fiabilidad y la eficiencia de las soluciones y servicios ofrecidos por Dinaup, asegurando que los usuarios tengan acceso a una plataforma robusta y de alta calidad.
## 2. Introducción [#2-introducción-]
Dinaup SOFTWARE SL (CIF B09689647), con domicilio en C/ Vicente Blasco Ibáñez 98 – 4º 2ª, 03201 Elche (Alicante), ofrece soluciones SaaS y servicios relacionados bajo estos Términos y Condiciones (“Términos”), disponibles en [https://www.dinaup.com/tyc](https://www.dinaup.com/tyc). Estos Términos incluyen nuestra Política de Uso Responsable y nuestra Política de Privacidad, accesibles en nuestro sitio web.
Al marcar la casilla de aceptación y/o continuar usando el Servicio, usted declara que ha leído, comprendido y aceptado íntegramente estos Términos. Si no está de acuerdo con alguno de ellos, no podrá acceder ni utilizar los servicios de Dinaup.
## 3. Uso de los Servicios [#3-uso-de-los-servicios-]
3.1. **Destinatarios**
* Empresas y profesionales. No adecuado para uso exclusivamente personal.
3.2. **Registro y datos**
* El Usuario garantiza que la información facilitada es veraz y actualizada. Dinaup podrá suspender o eliminar cuentas con datos falsos.
* Responsabilidad del Usuario de custodiar su cuenta y contraseña.
3.3. **Edad y capacidad**
* Debe ser mayor de 16 años y tener capacidad legal para contratar.
3.4. **Firma electrónica**
* Se equipara jurídicamente a la manuscrita. Dinaup podrá solicitar confirmación por escrito de identidad.
## 4. Tipos de plan y facturación [#4-tipos-de-plan-y-facturación]
4.1. **Inicio de la suscripción**
* El servicio se activa al introducir los datos de tarjeta y realizar el primer cargo.
4.2. **Límites de cada plan**
* Consulte los límites (usuarios, proyectos, facturas…) en su panel de control dinaup.com.
* Al superarlos, se bloquearán nuevas altas hasta realizar mejora del plan.
4.3. **Cambios de tarifa**
* Dinaup podrá modificar tarifas unilateralmente, con aviso de 30 días en web y por email a administradores.
## 5. Licencia de Uso [#5-licencia-de-uso-]
Dinaup otorga a los Usuarios una licencia limitada, no exclusiva, revocable y no transferible para utilizar los Servicios conforme a estos Términos.
## 6. Pago y acceso [#6-pago-y-acceso]
6.1. **Facturación por adelantado**
* El Servicio se cobra por adelantado y no es reembolsable salvo lo previsto en la Política de Devoluciones.
6.2. **Impuestos**
* Todos los impuestos y gravámenes aplicables corren a cargo del Usuario.
6.3. **Impago**
* En caso de impago o devolución del recibo, el acceso se suspende; si no se regulariza en 30 días, los datos se eliminan.
## 7. Cambios en los Servicios y Precios [#7-cambios-en-los-servicios-y-precios-]
Dinaup se reserva el derecho de modificar o descontinuar cualquier servicio o aspecto de los mismos sin previo aviso, siempre respetando los acuerdos vigentes. Los precios de los Servicios están sujetos a cambios con previo aviso de 30 días a través de nuestro sitio web o comunicación directa con los Usuarios.
## 8. Cancelación y rescisión [#8-cancelación-y-rescisión]
Tras la cancelación desde el menú de perfil, los datos se mantienen 30 días disponibles para descarga. Después, se eliminarán de forma irreversible.
## 9. Política de Uso Responsable [#9-política-de-uso-responsable-]
Los Usuarios deben utilizar los Servicios de manera responsable, asegurándose de no comprometer la disponibilidad, integridad o seguridad de los mismos. Queda prohibido el uso excesivo de recursos que pueda resultar en una degradación del servicio para otros usuarios. Dinaup se reserva el derecho de limitar o suspender los servicios a usuarios que abusen de los recursos. Estos límites se aplican exclusivamente a los entornos Dinaup "Administrados" y se establecen para garantizar que podamos ofrecer siempre precios competitivos. No obstante, cabe aclarar que estos no son límites estrictos y pueden ser ajustados según las necesidades específicas de cada cliente.
Para facilitar una comprensión clara de las limitaciones en entornos Dinaup "Administrados", se proporcionan los siguientes límites orientativos:
| Recurso | Límite Orientativo |
| ---------------------- | ------------------------ |
| Peticiones por segundo | 100 peticiones |
| Datos no estructurados | 20TB |
| Datos estructurados | 100GB |
| Registros por sección | 50 millones de registros |
Es importante destacar que para las licencias on-premise de Dinaup, no existen límites más allá de la capacidad de cómputo del hardware donde se implementen. Esto permite una flexibilidad completa para los usuarios que optan por esta modalidad, adecuándose a las capacidades y requerimientos específicos de su infraestructura.
Además, reconocemos que ciertos usuarios pueden requerir capacidades superiores para gestionar grandes volúmenes de operaciones en entornos Dinaup "Administrados". En estos casos, instamos a los usuarios a contactar directamente con nosotros para discutir la provisión de entornos de alta capacidad y disponibilidad. Estamos comprometidos en ofrecer soluciones que se ajusten a las necesidades específicas de nuestros usuarios, garantizando así el máximo rendimiento y la mejor experiencia posible.
## 10. Propiedad Intelectual [#10-propiedad-intelectual-]
Todo el contenido proporcionado por Dinaup, incluyendo textos, gráficos, logos, software, así como todos los desarrollos a medida, integraciones, y específicamente todos los repositorios en GitHub, es propiedad de Dinaup o se utiliza con permiso y está protegido por las leyes de propiedad intelectual. A menos que un contrato determine explícitamente lo contrario, ningún servicio, personalización, o desarrollo cede de ninguna manera la propiedad intelectual al cliente.
Además, aunque los usuarios pueden hacer contribuciones en nuestros repositorios, lo cual agradecemos profundamente, es importante aclarar que no adquieren ningún tipo de propiedad sobre sus contribuciones. Las contribuciones de los usuarios a nuestros repositorios se consideran parte de la colaboración comunitaria y, como tal, permanecen bajo la propiedad de Dinaup. Esto asegura la continuidad y la coherencia en el desarrollo y la mejora de nuestros servicios, manteniendo al mismo tiempo la integridad de nuestra propiedad intelectual.
10.1. El Usuario no adquiere licencia ni derechos de propiedad intelectual sobre las “Custom Solutions”. Todos los derechos de software, código, documentación y desarrollos a medida son y seguirán siendo propiedad exclusiva de Dinaup SOFTWARE SL.
10.2. Dinaup se reserva el derecho de migrar, modificar o reconvertir en cualquier momento una “Custom Solution” a una solución “Ready to Go” si lo considera necesario para garantizar la calidad, la seguridad o la escalabilidad del servicio.
## 11. Limitación de Responsabilidad [#11-limitación-de-responsabilidad-]
Servicios "Tal Cual": Dinaup y sus afiliados proporcionan sus servicios "tal cual" y "según estén disponibles", sin garantías de ningún tipo, ya sean explícitas o implícitas, incluidas, pero no limitadas a, garantías de comerciabilidad, idoneidad para un propósito particular y no infracción. Aunque Dinaup se esfuerza por mantener sus servicios operativos, seguros y libres de errores, no podemos garantizar la ausencia total de fallos, interrupciones o la invulnerabilidad frente a ataques de seguridad.
Limitaciones Generales de Responsabilidad: Dinaup, junto con sus afiliados, proveedores y distribuidores, en las jurisdicciones que lo permitan, no serán responsables por:
Daños indirectos, especiales, incidentales, punitivos, ejemplares o consecuentes. Pérdida de uso, datos, negocios, ingresos o beneficios, independientemente de la teoría legal. Esta limitación de responsabilidad no pretende eludir nuestras obligaciones bajo la ley ni tus derechos como consumidor que no pueden ser excluidos por contrato.
Limitaciones para Usuarios Comerciales: Para los usuarios que utilicen nuestros servicios en un contexto comercial, Dinaup y sus afiliados no serán responsables de:
Pérdidas de beneficios, ingresos, oportunidades de negocio o ahorros anticipados. Interrupción de negocio. Pérdidas no financieras, como la pérdida de reputación.
Límite Monetario de Responsabilidad: Dinaup establece expresamente que, excepto donde la ley aplicable lo prohíba, su responsabilidad total frente a los usuarios por todas y cada una de las reclamaciones que surjan del uso o la incapacidad para usar los servicios no excederá el mayor entre (a) el monto total pagado por el usuario a Dinaup por los servicios durante los doce (12) meses anteriores al evento causante de la reclamación, excluyendo los pagos realizados por servicios profesionales como mano de obra, instalaciones, configuraciones, consultorías, formación y cualquier otro servicio facturado por Dinaup en concepto de mano de obra, o (b) 100 EUR. Esta limitación de responsabilidad monetaria tiene como objetivo delimitar la exposición financiera de Dinaup ante reclamaciones, reflejando un equilibrio entre el riesgo asumido por Dinaup y el compromiso con sus usuarios, asegurando al mismo tiempo que las compensaciones por reclamaciones no excedan un umbral razonable y justificado.
Resolución de Disputas: Animamos a los usuarios a contactar a Dinaup directamente para buscar una resolución de cualquier disputa antes de proceder con reclamaciones legales. Estamos comprometidos a resolver disputas de manera justa y eficiente. Si no se alcanza una resolución satisfactoria dentro de un plazo razonable, se pueden explorar opciones de mediación o arbitraje, dependiendo de la jurisdicción.
## 12. Indemnización [#12-indemnización-]
El Usuario acuerda indemnizar y eximir a Dinaup, sus directivos, empleados, y agentes, de cualquier reclamación, pérdida, daño, responsabilidad, costo y gasto (incluyendo honorarios legales) que surjan del uso indebido de los Servicios o de la violación de estos Términos.
## 13. Política de Devoluciones [#13-política-de-devoluciones]
* Suscripciones mensuales y anuales: si durante los primeros 30 días tras el alta no está satisfecho, puede solicitar un reembolso completo escribiendo a [soporte@dinaup.com](mailto:soporte@dinaup.com).
* Renovaciones automáticas: reembolso completo si se cancela en los 7 días hábiles posteriores a la renovación.
* No proceden devoluciones por impago derivado de incumplimiento de los Términos.
## 14. Legislación Aplicable y Jurisdicción [#14-legislación-aplicable-y-jurisdicción-]
Estos Términos se regirán e interpretarán de acuerdo con las leyes de España, sin dar efecto a ningún principio de conflictos de leyes. Cualquier disputa relacionada con estos Términos estará sujeta a la jurisdicción exclusiva de los tribunales de España.
## 15. Con qué terceros de confianza comparte Dinaup información [#15-con-qué-terceros-de-confianza-comparte-dinaup-información-]
* OVHcloud. (Infraestructura Cloud) Principal
* Cloudflare (Infraestructura Cloud, DRP, Backups)
* Cluding.io (DRP, Infraestructura, DRP, Backups)
* Stripe (Datos fiscales, suscripciones y pagos)
* Outlook y OVHcloud (emails)
## 16. Acceso y Uso de Datos de los Usuarios [#16-acceso-y-uso-de-datos-de-los-usuarios-]
Dinaup se compromete a respetar la privacidad y la protección de los datos personales de los usuarios. Accedemos a los datos de los usuarios únicamente en circunstancias específicas y controladas, que incluyen, pero no se limitan a, las siguientes situaciones:
Cuando se nos solicita asistencia: Accedemos a los datos de los usuarios para proporcionar soporte técnico o asistencia en caso de incidencias con nuestros servicios, siempre y cuando el usuario haya solicitado expresamente nuestra intervención.
Mantenimiento y Mejora de los Servicios: Podemos acceder a los datos necesarios para realizar mantenimiento o mejoras en nuestros servicios, asegurando su funcionamiento óptimo y la implementación de actualizaciones relevantes.
Dinaup no procesa, utiliza, ni comparte los datos personales de los usuarios para ningún propósito más allá de la prestación y mejora de nuestros servicios, salvo en las infraestructuras y hostings cloud situados en centros de datos seguros. Estas acciones se realizan con el fin exclusivo de garantizar la disponibilidad, integridad y confidencialidad de los servicios proporcionados a los usuarios.
Protección de Datos: Dinaup implementa medidas de seguridad técnicas y organizativas adecuadas para proteger los datos personales de los usuarios contra el acceso no autorizado, la divulgación, alteración o destrucción. Nos comprometemos a no compartir los datos personales de los usuarios con terceros, salvo en lo que respecta a los proveedores de infraestructura y hosting cloud necesarios para el funcionamiento de nuestros servicios, y siempre en cumplimiento con las leyes aplicables de protección de datos.
Este compromiso se extiende a cualquier operación o conjunto de operaciones que se realicen con respecto a los datos personales de los usuarios, incluyendo, pero no limitado a, su recogida, registro, organización, estructuración, almacenamiento, adaptación o modificación, recuperación, consulta, uso, divulgación por transmisión, difusión o cualquier otra forma de habilitación de acceso, alineación o combinación, restricción, borrado o destrucción.
Cualquier intercambio de datos con terceros o partners requerirá el consentimiento expreso del usuario. Dinaup no asume responsabilidad sobre sus políticas o actuaciones.
## **17. Seguridad de las claves API** [#17-seguridad-de-las-claves-api]
17.1. **Custodia y confidencialidad**
* El Usuario es responsable de mantener sus claves API seguras y confidenciales, evitando accesos no autorizados, usos indebidos o divulgación.
17.2. **Uso y autorización**
* Cualquier operación realizada con sus claves API se considerará realizada por usted o bajo su autorización expresa.
* Compártalas únicamente con partes de confianza y en contextos que requieran su uso legítimo.
17.3. **Monitoreo y notificación**
* Debe supervisar regularmente el uso de sus claves API para detectar cualquier actividad sospechosa.
* En caso de pérdida, robo o posible compromiso, notifique de inmediato a Dinaup en [soporte@dinaup.com](mailto:soporte@dinaup.com) para su revocación y reemplazo.
## 18. **Integraciones con terceros y partners** [#18-integraciones-con-terceros-y-partners-]
18.1. **Entidades independientes**
* Dinaup facilita la conexión y uso conjunto con servicios de terceros y partners externos.
* Estos terceros operan de forma independiente; Dinaup no puede garantizar sus estándares de seguridad, privacidad o calidad.
18.2. **Riesgo y responsabilidad**
* El uso de servicios de terceros es bajo su exclusiva responsabilidad y riesgo.
* Dinaup no responde de actos, omisiones, políticas de privacidad, prácticas de manejo de datos ni del contenido de los servicios externos.
18.3. **Consentimiento y control de datos**
* Dinaup no compartirá sus datos con terceros sin su consentimiento expreso, salvo cuando el partner actúe directamente en su nombre.
* Usted conserva el control total de sus datos y deberá revisar las políticas de privacidad y seguridad de cada tercero antes de autorizar cualquier intercambio.
18.4. **Asistencia en la desvinculación**
* Si desea desvincularse de un partner, Dinaup le asistirá en el proceso para garantizar el acceso continuo y la integridad de sus datos.
## 19. **Partners y gestión de licencias** [#19-partners-y-gestión-de-licencias]
19.1. **Responsabilidad del Partner**
* El Partner actúa como intermediario autorizado por el cliente final al crear o gestionar licencias.
* Asume la responsabilidad de la creación, administración y uso de la cuenta, así como de la veracidad y seguridad de los datos introducidos.
19.2. **Principios de actuación**
* El Partner se compromete a actuar con buena fe, respetando la libertad del cliente y evitando prácticas de bloqueo o dependencia forzada (“vendor lock‑in”).
* Debe garantizar el acceso del cliente a su cuenta y datos, incluso tras finalizar la relación comercial, sin barreras técnicas ni administrativas.
19.3. **Titularidad y control de datos**
* Todos los datos introducidos en la cuenta son propiedad exclusiva del cliente final.
* Dinaup garantiza el acceso a esos datos únicamente a usuarios con credenciales válidas asociadas a la cuenta.
19.4. **Acceso en caso de conflicto**
* Si surge un desacuerdo entre Partner y cliente, Dinaup facilitará al cliente final el acceso a sus datos, previa acreditación de identidad y vinculación legítima con la cuenta.
* Podrá solicitar documentación adicional para verificar y desbloquear el acceso.
19.5. **Limitación de responsabilidad**
* Dinaup no se responsabiliza de posibles usos indebidos o negligentes por parte del Partner o del cliente final, incluyendo accesos no autorizados, eliminación de datos o gestión inadecuada de la cuenta.
* Cada parte asume plena responsabilidad por sus propias acciones en la plataforma.
## 20. Titularidad y Acceso a los Datos [#20-titularidad-y-acceso-a-los-datos]
20.1. **Identificación del Titular**\
En el formulario de alta de **toda** licencia (Ready-to-Go, “Pymes Gestión Delegada”, Custom Solution u otra) el solicitante deberá indicar:
* Denominación social / nombre completo del Titular de los Datos.
* NIF/NIE/CIF.
* Domicilio fiscal.
* Persona de contacto autorizada y correo electrónico.
20.2. **Veracidad y documentación**\
El solicitante garantiza que la información facilitada es exacta **y, al aceptar los presentes Términos y Condiciones, declara que ostenta poder suficiente para vincular jurídicamente a la entidad en cuyo nombre actúa**. Podrá ser requerido a aportar documentación acreditativa (poderes, alta censal, etc.). Dinaup podrá suspender la cuenta hasta que los datos sean verificados.
20.3. **Derecho irrenunciable de acceso**\
Con independencia del tipo de licencia o de la intervención de un Partner, el Titular de los Datos (o su representante legitimado) tiene derecho a obtener, sin coste, una copia íntegra y legible de toda su información alojada en Dinaup.
20.4. **Procedimiento y plazos**
* Solicitud formal a Dinaup desde la dirección de correo asociada al Titular.
* Dinaup verificará identidad y, en un plazo máximo de **cinco (5) días hábiles**, habilitará:
* a) un usuario de solo lectura, **o**
* b) un paquete de exportación (CSV/XML/PDF/ZIP) con todos los registros.
20.5. **Cuenta temporal de cortesía**\
Si el Titular carece de credenciales, Dinaup abrirá gratuitamente una cuenta temporal de solo lectura durante **quince (15) días** para que descargue los datos.
20.6. **Prevalencia sobre acuerdos privados**\
Ninguna cláusula pactada entre Partner y Cliente podrá restringir o retrasar este derecho de acceso. En caso de conflicto, prevalecerá lo dispuesto en este artículo 19.
20.7. **Responsabilidad por denegación**\
La negativa injustificada del Partner a entregar los datos constituye incumplimiento grave. Dinaup podrá:
* Facturar al Partner la diferencia entre la licencia con descuento y la tarifa estándar desde la fecha de infracción.
* Suspender o cancelar la condición de Partner autorizado.
## 21. Contacto [#21-contacto-]
Para cualquier pregunta o preocupación relacionada con estos Términos, por favor contáctenos en:
Dirección: CALLE VICENTE BLASCO IBAÑEZ, 98 - PISO 4 2, 3201 ELCHE/ELX, Alicante, España. Teléfono: 687295537 Correo Electrónico: [info@dinaup.com](mailto:info@dinaup.com) Datos Fiscales de la Empresa:
Denominación: DINAUP SOFTWARE SL. CIF/NIF: B09689647 Domicilio Social Actual: CALLE VICENTE BLASCO IBAÑEZ, 98 - PISO 4 2, 3201 ELCHE/ELX, Alicante, España. Código Postal: 3201 Municipio: ELCHE/ELX Provincia: Alicante
# Partners (/docs/cuenta/partners)
Un partner es un colaborador autorizado que puede dar soporte y servicios sobre tu cuenta de Dinaup.
# Cómo crear y asignar roles de usuario en Dinaup (/docs/cuenta/permisos-y-roles/como-crear-y-asignar-roles-de-usuario-en-dinaup)
* Inicia sesión en **Dinaup Desktop** con una cuenta de administrador.
* Ve al menú **Configuración** → **Roles**.
* Haz clic en **Agregar**.
* Escribe un nombre para el nuevo rol (por ejemplo: `Enfermero`) y pulsa **Enter**.
* Abre el rol que acabas de crear haciendo doble clic sobre el nombre en el listado.
* Configura el rol y pulsa **Guardar**.
* Entra en [www.dinaup.com](https://www.dinaup.com) con tu cuenta de administrador.
* Busca al usuario al que quieras asignar el rol.
* Haz clic en **Editar**.
* En el campo **Rol**, selecciona el nombre del rol que creaste (por ejemplo: `Enfermero`).
* Guarda los cambios.
# Crear Diseño de Sección (/docs/cuenta/permisos-y-roles/crear-diseno-de-seccion)
Puedes crear diferentes diseños según el tipo de uso (por ejemplo: una vista simplificada para comerciales, una completa para administradores).
Personalizar diseños aumenta el mantenimiento a largo plazo. Si en una actualización futura Dinaup cambia la distribución de pestañas o campos, tu diseño personalizado **no se actualiza solo**.
* Si se **elimina un campo**, quedará un hueco vacío.
* Si se **añade un campo obligatorio**, el usuario no podrá rellenarlo y no podrá guardar.
Por eso, siempre que sea posible, recomendamos usar el diseño por defecto del sistema. Te aseguras de que todo esté actualizado y funcional sin tener que revisar cada cambio.
## Crear un diseño personalizado [#crear-un-diseño-personalizado-]
### Busca la sección "Personalización de Secciones" y pulsa "Agregar Nuevo" [#busca-la-sección-personalización-de-secciones-y-pulsa-agregar-nuevo]
### Escribe un nombre claro para identificar la configuración [#escribe-un-nombre-claro-para-identificar-la-configuración]
Ejemplo:
* Productos Información básica
* Vehículos sin información
Un mismo diseño puede utilizarse en varios roles.
### Pulsa **Configurar** [#pulsa-configurar]
La ventana de confirmación pregunta si quieres configurar desde cero o cargar una base sobre la que trabajar. Pulsa `Si` para cargar la base.
### Activa las opciones de `Desarrollo` [#activa-las-opciones-de-desarrollo]
Haz clic en el botón del engranaje para poder editar los campos.
### Configuración de campos [#configuración-de-campos]
A la derecha de cada campo hay 4 botones para configurar:
* Obligatorio
* Bloqueado
* Visible en Información Adicional
* Visible
### Arrastra campos [#arrastra-campos]
Haz clic sobre un campo para arrastrarlo o redimensionarlo.
### Guardar diseño [#guardar-diseño]
### Guardar personalización de Sección [#guardar-personalización-de-sección]
# Diferencias Solución Pymes y TPV (/docs/cuenta/precios/diferencias-solucion-pymes-y-tpv)
[Ready to Go TPV](/docs/rtg/tpv) y [Ready to Go Pymes](/docs/rtg/pymes) forman parte del ecosistema Dinaup y se complementan. Puedes activar o desactivar el acceso a cada aplicación según el empleado.
**¿Cuándo conviene cada solución?**
* **Ready to Go TPV** · Punto de venta para call center, mostrador, barra o caja. Si solo necesitas vender y cumplir con Verifactu, sin compras ni contabilidad.
* **Ready to Go Pymes** · Añade compras, inventario multi‑almacén, contabilidad y tesorería.
### Ventas [#ventas]
| | TPV | Pymes |
| ------------ | --- | ----- |
| Clientes | ✅ | ✅ |
| Presupuestos | ✅ | ✅ |
| Pedidos | ✅ | ✅ |
| Ventas | ✅ | ✅ |
### Compras y Gastos [#compras-y-gastos]
| | TPV | Pymes |
| ------------------- | --- | ----- |
| Proveedores | ❌ | ✅ |
| Compras | ❌ | ✅ |
| Gastos | ❌ | ✅ |
| Nóminas | ❌ | ✅ |
| Catálogos de Compra | ❌ | ✅ |
### Tesorería [#tesorería]
| | TPV | Pymes |
| --------------------- | --- | ----- |
| Cajas | ✅ | ✅ |
| Cuentas bancarias | ✅ | ✅ |
| Cobros de Venta | ✅ | ✅ |
| Cierres de Caja | ✅ | ✅ |
| Conciliación bancaria | ❌ | ✅ |
| Pagos de Compra | ❌ | ✅ |
### Inventario [#inventario]
| | TPV | Pymes |
| ------------------ | --- | ----- |
| Productos | ✅ | ✅ |
| Catálogos de Venta | ✅ | ✅ |
| Almacenes | ❌ | ✅ |
| Stock | ❌ | ✅ |
### Exportación y Análisis [#exportación-y-análisis]
| | TPV | Pymes |
| ------------------- | --- | ----- |
| Exportación Excel | ✅ | ✅ |
| Gráficas y reportes | ✅ | ✅ |
| Cajas | ✅ | ✅ |
### Contabilidad [#contabilidad]
| | TPV | Pymes |
| ----------------------- | --- | ----- |
| Cuadro de cuentas | ❌ | ✅ |
| Asientos Contables | ❌ | ✅ |
| Inmovilizados | ❌ | ✅ |
| Contabilidad Automática | ❌ | ✅ |
### Cumplimiento [#cumplimiento]
| | TPV | Pymes |
| --------- | --- | ----- |
| Verifactu | ✅ | ✅ |
| SII | ❌ | ❌ |
| TicketBAI | ❌ | ❌ |
# Precios (/docs/cuenta/precios)
Tarifas por módulo, usuarios incluidos y costes adicionales.
*Precios orientativos sin IVA.*
## 1. Ready to Go (soluciones listas para usar) [#1-ready-to-go-soluciones-listas-para-usar]
Selecciona un módulo y trabaja con él tal cual, o personalízalo más adelante. Cada licencia incluye **5 usuarios acumulables**.
* Pymes: 90 €
* 5 Usuarios: Incluidos.
* Total Mes: **90 €**\
\
*\* Usuario adicional: 9,96 €*
* \+ Pymes: 90 €
* \+ Recursos Humanos: 90 €
* 10 Usuarios: Incluidos.
* Total Mes: **180 €**\
\
*\* Usuario adicional: 11,93 €*
## 2. Soluciones a medida (Custom Solution) [#2-soluciones-a-medida-custom-solution]
Con Dinaup Flex diseñas tu propio sistema. Empieza con la licencia base y añade solo lo que necesites.
Servicio
Coste Mensual
Claves API Incluidas
Dinaup Flex
90 € mes + 1,97 € (por usuario)
1
Licencia desarrollador Flex. (Permite utilizar las herramientas de desarrollo)
Desde 3.000 €
—
#### Costes puntuales (solo se pagan una vez) [#costes-puntuales-solo-se-pagan-una-vez]
Servicio
Pago único
Alta de Licencia Personalizada
6.000 - 10.000 €
Sección
350 € - 890 €
Campo
150 € - 290 €
Informe
150 € - 290 €
Documento Dinámico
150 € - 300 €
**Mensual**
* 90 € (RTG Pymes) = 90 €
* 90 € (Dinaup Flex + API) = 90 €
* Total Mes: 180 €
**Pago único**
* Alta de licencia 7.000 €
* 3 secciones: 1.500 €
* 4 informes: 800 €
* Pago único: 9.300 €
## 3. Recursos adicionales [#3-recursos-adicionales]
Pagas solo por lo que consumas. Cada plan incluye una capa gratuita, así que en la mayoría de los casos no hay cargos extra.
Servicio
Coste Mensual
Capa gratuita
Base de datos (Datos estructurados)
4 € / GB
8 GB
Archivos (Imágenes, PDF, XLS...) archivos adjuntos al sistema.
## Partners [#partners]
Para implementación o personalización, los [**partners certificados**](/docs/cuenta/partners/partners) ofrecen soporte local.
# Cuenta y Facturación (/docs/cuenta/cuenta-y-facturacion)
Desde esta sección del panel de administración ([dinaup.com](https://dinaup.com)) gestionas tu suscripción a Dinaup: plan contratado, módulos activos, métodos de pago y facturas.
Solo los usuarios con el permiso **Gestionar Suscripción Dinaup** pueden acceder a esta sección.
***
## Suscripción [#suscripción]
### Plan actual [#plan-actual]
La tarjeta de suscripción muestra:
| Dato | Descripción |
| ----------------------- | -------------------------------------------------------- |
| **Plan** | El plan contratado (Starter, Business, Enterprise, etc.) |
| **Coste mensual** | Precio base del plan + módulos activos |
| **Próxima facturación** | Fecha del próximo cargo |
| **Estado** | Activa, En periodo de gracia, Suspendida |
### Cambiar de plan [#cambiar-de-plan]
Haz clic en **Cambiar plan** para ver los planes disponibles y sus diferencias. El cambio se aplica inmediatamente y el importe se prorratea en la siguiente factura.
### Módulos activos [#módulos-activos]
Desde la sección de suscripción puedes activar o desactivar los módulos Ready To Go:
| Módulo | Qué incluye |
| -------------- | ------------------------------------------------ |
| **Pymes** | Facturación, contabilidad, tesorería, inventario |
| **CRM** | Gestión comercial, oportunidades, seguimiento |
| **RRHH** | Control horario, fichajes, vacaciones |
| **TPV** | Punto de venta táctil |
| **Desktop** | Aplicación de escritorio |
| **Desarrollo** | Herramientas de desarrollo, Flex, API |
| **Soporte** | Acceso al sistema de soporte |
La activación/desactivación de módulos se refleja inmediatamente en Play Dinaup para todos los usuarios de tu empresa.
### Métricas de uso [#métricas-de-uso]
| Métrica | Descripción |
| ------------------------ | ------------------------------------------------ |
| **Usuarios facturables** | Usuarios activos que cuentan para la facturación |
| **Base de datos** | GB utilizados en la base de datos |
| **Archivos** | GB utilizados en almacenamiento de archivos |
| **Almacenes** | Número de almacenes configurados |
***
## Periodo de prueba [#periodo-de-prueba]
Las nuevas cuentas incluyen un **periodo de prueba gratuito de 14 días** con acceso completo a todos los módulos. Al finalizar el periodo:
* Si has configurado un método de pago, la suscripción se activa sola
* Si no, se te pedirá que selecciones un plan y añadas un método de pago
***
## Facturas y pagos [#facturas-y-pagos]
### Facturas [#facturas]
Consulta el historial de facturas emitidas por Dinaup a tu empresa. Cada factura incluye:
* Número de factura y fecha
* Desglose de servicios y módulos
* Descarga en PDF
### Recibos de Stripe [#recibos-de-stripe]
Si pagas con tarjeta, los recibos de cada cargo se gestionan a través de Stripe. Accede al portal de Stripe desde esta sección para ver todos los detalles.
### Métodos de pago [#métodos-de-pago]
Gestiona tus métodos de pago (tarjeta de crédito/débito) a través del portal seguro de Stripe. Puedes:
* Añadir una nueva tarjeta
* Cambiar la tarjeta predeterminada
* Eliminar tarjetas antiguas
→ Ver [Opciones de pago](/docs/cuenta/cuenta-y-facturacion/opciones-de-pago-facturacion-y-pagos-automatizados)
***
## Política de impagos [#política-de-impagos]
Si un pago no se procesa correctamente, Dinaup aplica restricciones progresivas:
| Periodo | Acción |
| --------------- | ------------------------------------- |
| **0-7 días** | Sin restricciones (periodo de gracia) |
| **7-30 días** | Aviso visible en la plataforma |
| **30-180 días** | Acceso de solo lectura |
| **+180 días** | Bloqueo total de la cuenta |
→ Ver [Política de Impagos](/docs/cuenta/legal/politica-de-impagos-de-dinaup)
***
## Datos de la empresa [#datos-de-la-empresa]
Desde **Mi Empresa** (accesible solo para administradores) puedes gestionar:
### Datos fiscales [#datos-fiscales]
Nombre o razón social, NIF/CIF, dirección completa. Se usan en las facturas que Dinaup te emite.
### Representante legal [#representante-legal]
Datos del representante legal de la empresa (nombre, apellidos, NIF, dirección).
### Datos de facturación [#datos-de-facturación]
Si la dirección de facturación es distinta a la de la empresa, configúrala aquí.
### Dominios [#dominios]
Verifica dominios de tu propiedad para proteger la identidad de tu empresa. La verificación se realiza mediante:
* **DNS TXT**: añade un registro `_dinaup_verify` con el token proporcionado
* **HTTP**: sube un archivo a `/.well-known/dinaup-domain-verify.txt`
Con un dominio verificado, los usuarios que se registren con emails de ese dominio se detectan como parte de tu empresa.
# Opciones de pago: facturación y pagos automatizados (/docs/cuenta/cuenta-y-facturacion/opciones-de-pago-facturacion-y-pagos-automatizados)
Para mantener tu suscripción activa, añade un **método de pago válido** en Dinaup.
La gestión de pagos se realiza a través de **Stripe**. Dinaup **no almacena datos bancarios**.
Se aceptan:
* **Tarjetas bancarias**
* **Domiciliación bancaria SEPA**
### Acceder a la suscripción [#acceder-a-la-suscripción]
1. Inicia sesión en [dinaup.com](https://www.dinaup.com/)
2. Selecciona **Añadir método de pago**.
3. Dinaup te redirigirá al portal de pagos.
### Añadir el método de pago [#añadir-el-método-de-pago]
* En la sección **Método de pago**, selecciona **Añadir método de pago**.
* Elige una de las siguientes opciones:
* **Tarjeta bancaria**
* **Cuenta bancaria (domiciliación SEPA)**
* Introduce la información solicitada y confirma.
# DinaZen (/docs/desarrollo/dotnet/dinazen)
**DinaZen** es la librería de componentes Blazor de Dinaup, construida sobre [Radzen](https://blazor.radzen.com/). Te da las piezas para montar aplicaciones .NET con el aspecto y el comportamiento de **Play Dinaup**: tarjetas, cabeceras, badges, formularios, tablas y vistas avanzadas.
Está pensada para desarrolladores que construyen apps Blazor sobre el [SDK .NET](/docs/desarrollo/dotnet/sdk). El SDK te da los datos (conexión, informes, escritura); DinaZen te da la capa visual para mostrarlos y editarlos sin reinventar la UI.
DinaZen es la **capa de presentación**. Para conectarte a Dinaup, consultar informes y guardar datos, usa el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
***
## Qué incluye [#qué-incluye]
DinaZen agrupa componentes por la función que cumplen en pantalla. A alto nivel:
| Categoría | Para qué sirve |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| **Presentación** | Tarjetas, cabeceras de sección, badges y estados que dan a tu app el aspecto de Play. |
| **Layout** | Estructura de páginas y vistas: organiza el contenido con la misma jerarquía visual que Dinaup. |
| **Formularios e inputs** | Campos de entrada coherentes para capturar y editar datos. |
| **Tablas** | Listados con paginación, filtros y selección, alineados con los [informes](/docs/desarrollo/flex/informes) del SDK. |
| **Vistas** | Vista **Gantt** para planificación, y vistas de informe (tarjetas, gráfico, Top-N) para presentar datos con el aspecto de Play. |
| **Utilidades** | Indicadores de carga, diálogos y helpers que resuelven los patrones de UI repetitivos. |
DinaZen no sustituye a Radzen: lo extiende. Puedes seguir usando los componentes de Radzen directamente cuando lo necesites; DinaZen aporta los que dan el look & feel de Dinaup.
***
## Referencia y patrones [#referencia-y-patrones]
Esta sección tiene dos puertas de entrada:
* **[Patrones de uso](/docs/desarrollo/dotnet/dinazen/patrones)**: el recetario. Cinco recetas de extremo a extremo (informe → tabla, datos tipados, elegir selector, esqueleto de diálogo y estados de carga). Empieza aquí si lo que quieres es *hacer algo*.
* **[Componentes](/docs/desarrollo/dotnet/dinazen/componentes)**: la referencia, agrupada por familias. Entra por la que necesites:
| Familia | Para qué |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| [Datos tipados (Spans)](/docs/desarrollo/dotnet/dinazen/componentes/datos-tipados) | Pintar un importe, fecha, duración o peso con el formato de Dinaup. |
| [Tarjetas y layout](/docs/desarrollo/dotnet/dinazen/componentes/tarjetas-y-layout) | Cabeceras, tarjetas y contenedores con la jerarquía visual de Play. |
| [Badges y estados](/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados) | Etiquetas de estado con color automático según el texto. |
| [KPIs y métricas](/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas) | Tarjetas y filas de indicadores para dashboards. |
| [Selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores) | Desplegables y selección de fichas (la regla de los 3 segundos). |
| [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes) | Pintar un informe del SDK como tabla, tarjetas o gráfica. |
| [Inputs y formularios](/docs/desarrollo/dotnet/dinazen/componentes/inputs-y-formularios) | Capturar y editar datos: búsqueda, ficheros, texto rico, etiquetas. |
| [Carga y rendimiento](/docs/desarrollo/dotnet/dinazen/componentes/carga-y-rendimiento) | Loader, skeleton y contenido diferido. |
| [Vistas avanzadas](/docs/desarrollo/dotnet/dinazen/componentes/vistas-avanzadas) | Gantt, código resaltado y selectores de rango de fechas. |
| [Diálogos](/docs/desarrollo/dotnet/dinazen/componentes/dialogos) | El esqueleto de diálogo y los diálogos listos (confirmar, elegir ficha). |
***
## Instalación y configuración [#instalación-y-configuración]
DinaZen se distribuye como paquete NuGet. Una vez referenciado, configura el proyecto y los imports.
### Añade el paquete [#añade-el-paquete]
```bash
dotnet add package DinaZen
```
### Configura el `.csproj` [#configura-el-csproj]
Trata los avisos de componentes como errores, para no romper la UI por descuido. Importa de forma estática las extensiones de Dinaup: así tienes `.STR()`, `.INT()`, `.IsEmpty()` y demás en todos los `.razor`.
```xml
RZ10012True
```
### Importa los componentes [#importa-los-componentes]
En tu `_Imports.razor`:
```csharp
@using DinaZen.Components
```
A partir de aquí, los componentes de DinaZen están disponibles en cualquier página o componente del proyecto.
***
## Convenciones de uso [#convenciones-de-uso]
DinaZen sigue los mismos criterios que el resto del ecosistema Blazor de Dinaup. Respétalos para que tu app se comporte como Play.
### Referencia campos con `nameof`, no con strings [#referencia-campos-con-nameof-no-con-strings]
Cuando un componente necesita el nombre de una propiedad, **nunca lo escribas como string literal**. Usa `nameof` para que el compilador valide el nombre y los renombrados no rompan en silencio.
```razor
Property=@nameof(Modelo.Number)
```
```razor
Property="Number"
```
### Estados de carga [#estados-de-carga]
Distingue entre "estoy procesando una acción" y "estoy cargando la interfaz por primera vez". Cada caso tiene su componente.
Una operación en curso (guardar, calcular, llamar a la API):
```razor
```
La interfaz aún no está lista y quieres mostrar un esqueleto en su lugar:
```razor
```
El estado de carga es parte de la experiencia. Una operación larga sin indicador hace pensar al usuario que algo se ha roto.
### Diálogos [#diálogos]
Los diálogos de DinaZen comparten una estructura fija de pie de página: el botón de cancelar a la izquierda en estilo discreto, el de confirmar a la derecha y destacado.
```razor
```
| Botón | Estilo | Variante |
| ------------ | --------- | ---------------------------------- |
| **Cancelar** | `Danger` | `Text` (discreto) |
| **Aceptar** | `Success` | sólido + `IsBusy` mientras procesa |
Marca el botón de confirmar con `IsBusy` durante la operación: el propio botón muestra el indicador de carga y bloquea doble clic.
***
## Cómo encaja con el SDK [#cómo-encaja-con-el-sdk]
DinaZen y el SDK .NET se reparten el trabajo: tú conectas y traes los datos con el cliente, y los presentas y editas con DinaZen.
### Conecta y lee con el SDK [#conecta-y-lee-con-el-sdk]
Usa el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente) para conectarte y ejecutar [informes](/docs/desarrollo/flex/informes), que te devuelven filas tipadas listas para mostrar.
### Presenta con DinaZen [#presenta-con-dinazen]
Pinta esas filas en tablas, tarjetas o vistas Kanban/Gantt, con el aspecto de Play y sin escribir CSS a mano.
### Edita y guarda [#edita-y-guarda]
Captura cambios con los formularios e inputs de DinaZen y persístelos con las **WriteOperations** del cliente.
→ [SDK .NET](/docs/desarrollo/dotnet/sdk) · [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente) · [Guías de estilo C# y Blazor](/docs/desarrollo/dotnet/c-code-style-guidelines) · [Dinaup Flex](/docs/desarrollo/flex)
# Dotnet (/docs/desarrollo/dotnet)
Herramientas y convenciones para desarrollar en .NET sobre Dinaup.
La librería tipada generada a partir del esquema de tu organización.
# MyDinaup (/docs/desarrollo/dotnet/mydinaup)
MyDinaup es una librería .NET que Dinaup genera a partir del esquema de tu organización: cada sección, informe y documento de tu tenant se convierte en una clase tipada con los nombres reales de tus campos.
Un **tenant** es tu instalación de Dinaup, con su propio modelo de datos. Ese modelo lo diseñas tú desde Dinaup Flex, así que dos organizaciones nunca tienen el mismo esquema. MyDinaup es el reflejo de *tu* esquema en código .NET.
El paquete se llama `{Empresa}.MyDinaup`. En este documento los ejemplos salen de [`DemoUp.MyDinaup`](https://www.nuget.org/packages/DemoUp.MyDinaup), el modelo de pre-producción que usa el equipo de Dinaup, y las clases citadas son reales.
## Qué problema resuelve [#qué-problema-resuelve]
El SDK `Dinaup` habla con la API, pero no conoce tu esquema. Sin MyDinaup, identificas cada campo por su clave interna en crudo:
```csharp
// Sin MyDinaup: claves de columna a pelo
var data = new Dictionary
{
{ "pr_30655031", "SC-4471" }, // ¿qué campo es este?
{ "nombre", "Almacén central" }
};
```
Esas claves (`pr_30655031`, `pr_506847515`) no se adivinan, no se autocompletan y un error tipográfico no salta hasta que la petición falla en ejecución. MyDinaup pone un nombre legible a cada una y las expone como constantes:
```csharp
// Con MyDinaup: nombres reales de tu esquema
using DemoUp.MyDinaup;
var data = new Dictionary
{
{ SectionsD.AlmacenesD.AlmacenesES.SendcloudID, "SC-4471" },
{ SectionsD.AlmacenesD.AlmacenesES.TextoPrincipal, "Almacén central" }
};
```
Lo que ganas:
* **Tu esquema, tipado.** Las clases llevan los nombres de tus secciones y campos, no los del modelo genérico.
* **Autocompletado.** El editor sugiere secciones, campos e informes. No hace falta abrir Flex para recordar una clave.
* **Errores en compilación.** Un campo mal escrito no compila. Sin MyDinaup, el mismo fallo es una excepción en tiempo de ejecución.
* **Filas fuertemente tipadas.** Un informe devuelve `row.Total As Decimal`, no un diccionario de strings que conviertes a mano.
## Qué contiene [#qué-contiene]
MyDinaup depende del paquete `Dinaup` y añade tres grupos de clases, uno por cada tipo de objeto de tu esquema. Todas heredan de clases base que viven en el SDK.
### Secciones [#secciones]
Una **sección** es una tabla de tu tenant: Almacenes, Entidades, Ventas. Por cada una, MyDinaup genera dos clases dentro de `SectionsD`:
* **`{Seccion}ES`**: las claves de campo como constantes. `AlmacenesES.SendcloudID` devuelve la clave interna (`"pr_30655031"`). Úsala para construir filtros y `WriteOperation`.
* **`{Seccion}C`**: la fila tipada, hereda de `DinaupRowBase`. Cada campo es una propiedad con su tipo real.
```csharp
Public Class AlmacenesES
Public Shared ReadOnly SendcloudID$ = "pr_30655031"
Public Shared ReadOnly TextoPrincipal$ = "nombre"
Public Shared ReadOnly FechaAlta_UTC$ = "pr_400105496714"
End Class
Public Class AlmacenesC
Inherits DinaupRowBase
Public Property SendcloudID As String
Public Property FechaAlta_UTC As DateTime?
Public Property ReferenciaResponsable As Dinaup.DinaupBasicInformation
End Class
```
Un campo que apunta a otra sección (una relación) se tipa como `DinaupBasicInformation`: trae el ID, el texto principal y la imagen del registro relacionado sin una segunda consulta.
La clase `{Seccion}D` también expone `_SectionIDGUID` (el identificador de la sección) y métodos de lectura directa: `GetRowByIdAsync` y `GetRowsAsync`.
Leer con `SectionsD` recupera la sección entera más los textos de sus relaciones, así que es más costoso. Para volumen o rendimiento, usa **Informes**. `SectionsD` encaja en código que corre poco o en prototipos.
### Informes [#informes]
Un **informe** es una consulta tipada. MyDinaup genera una clase `API{Nombre}C` por informe, bajo `Reports.{Categoria}D`, que hereda de `DinaupReportBase(Of RowC)` del SDK. La clase de fila anidada lleva una propiedad por columna, ya con su tipo:
```csharp
Public Class APIAlmacenesC
Inherits dinaup.DinaupReportBase(Of APIAlmacenes_RowC)
Public Class APIAlmacenes_RowC
Public Property ID As Guid
Public Property TextoPrincipal As String
Public Property DisponibleEnTPV As Boolean
Public Property Color As EnumTextoEstiloE
End Class
End Class
```
Al generar la fila, MyDinaup convierte cada columna con una llamada a método del SDK según su tipo: `.STR()` para texto, `.ToGuid()` para identificadores, `.BOOL()` para booleanos, `.ToDateTime_UTC()` para fechas, `.INT(0)` para enteros y enums. Son extensiones del paquete `Dinaup`.
El informe generado tolera que falte una columna en la respuesta del servidor. Cada columna se lee tras comprobar que existe, y la propiedad `TolerateMissingColumns` (heredada de `DinaupReportBase`) decide qué pasa si falta alguna:
* **`false`** (valor por defecto): una columna ausente lanza excepción y delata el desajuste entre modelo y servidor de inmediato.
* **`true`**: las columnas que faltan se registran como aviso y sus propiedades quedan en su valor por defecto, para poder cargar el resto.
### Documentos dinámicos [#documentos-dinámicos]
Un **documento dinámico** es un procedimiento con guion que corre en el servidor y devuelve HTML, JSON, PDF u otro formato: una factura, un email, un volcado JSON. MyDinaup genera una clase por documento bajo `DynamicDocuments.{Categoria}D`, heredera de `DinaupDynamicDocumentBase`, que solo guarda su identificador y su título:
```csharp
Public Class SesionC
Inherits DinaupDynamicDocumentBase
Sub New()
Me.ID = New Guid("73fd6203-3109-4572-8ad0-8c58702dd1a5")
Me.Title = "Sesión"
End Sub
End Class
```
### Enumeraciones y constantes [#enumeraciones-y-constantes]
Además de los tres grupos, MyDinaup genera dos archivos de apoyo:
* **`Enumeraciones.vb`**: los tipos de lista de tu esquema como `Enum` de .NET (`EnumTextoEstiloE`, con `Estilo1 = 1`, `Estilo2 = 2`…). Los usan las filas que tienen campos de ese tipo.
* **`Constants.vb`**: los catálogos de estados y tipos como valores predefinidos: cada estado de una venta, cada tipo de documento oficial, con su GUID y su etiqueta. Útil para filtrar o escribir sin copiar identificadores a mano.
## El esquema documentado en el propio código [#el-esquema-documentado-en-el-propio-código]
Las clases generadas no traen solo nombres: cada constante de campo lleva su **comportamiento en el servidor** como documentación XML, y cada sección incluye sus **scripts** como comentarios. Es la letra pequeña que antes obligaba a abrir Flex o a descubrirla a base de errores de la API.
### Qué cuenta cada campo [#qué-cuenta-cada-campo]
El comentario XML de la constante aparece en el editor al pasar el cursor o autocompletar. Un campo real de la sección Proyectos:
```csharp
'''
''' This field is related to the 'bd46bc13-...' section (Tipos de proyecto).
''' Auto-filled with Referencia dato: To Do (Siempre).
''' Auto-managed: filled and locked by the server, do not provide it.
''' Text field: up to 36 characters.
'''
Public Shared ReadOnly ReferenciaTipo$ = "pr_30010431914"
```
Lo que puede anunciar cada campo:
| Anotación | Qué significa para tu código |
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `This field is related to the '…' section` | Es una relación: escribe el GUID de un registro de esa sección. |
| `Auto-filled with …` | El servidor lo rellena solo (con un campo de la sesión, un valor fijo o un dato de referencia). Si dice `Siempre`, no intentes pisarlo. |
| `Auto-managed: filled and locked by the server` | No lo mandes en la escritura: lo pone y bloquea el servidor. |
| `READ-ONLY: auto-calculated by the server from the section …` | Contador o suma calculada desde otra sección. Escribirlo no tiene efecto. |
| `REST write policy: can be set when creating … read-only on update` | Solo acepta valor en el alta; en actualizaciones se ignora o falla. |
| `Read-only via REST: auto-set by the server, never writable` | Campos de sistema (`id`, `fecha`, `eliminado`…): nunca se escriben. |
| `Required` / `Unique` | Obligatorio al crear, o sin duplicados en la sección. |
| `Text field: up to N characters` / `Numeric size: …` | Tamaño máximo del texto o dígitos enteros y decimales admitidos. |
Antes de construir una [`WriteOperation`](/docs/desarrollo/dotnet/sdk/cliente), un vistazo a estas anotaciones evita los dos fallos típicos: mandar campos que el servidor gestiona y omitir los obligatorios.
### Los scripts de la sección, legibles [#los-scripts-de-la-sección-legibles]
Debajo de las constantes, cada sección incluye un bloque `COMPORTAMIENTO / SCRIPTS` con la lógica que el servidor ejecuta sobre sus registros: validaciones antes de aceptar, campos que se derivan al cambiar un estado, botones que crean registros relacionados.
```csharp
' Script: Estado cambiado
' Cuando: Campo cambiado
' Codigo:
' if C.ReferenciaEstado.Estado = S.Enums.estadotramite.pendiente
' C.EnProceso = 1
' else
' C.EnProceso = 0
' end
```
No es código que tu aplicación ejecute: es documentación de lo que pasará en el servidor cuando escribas en esa sección. Si una escritura por API devuelve un error de validación o un campo cambia de valor "solo", la explicación suele estar en este bloque. También es contexto directo para asistentes de IA que trabajen sobre tu repositorio: leen el comportamiento de la sección sin salir del código. La sintaxis de esos scripts es [DinaScript](/docs/desarrollo/flex/dinascript), con el prefijo [`C.`](/docs/desarrollo/flex/dinascript/c.-registro-del-formulario) apuntando al registro en edición.
## Cómo se genera y se actualiza [#cómo-se-genera-y-se-actualiza]
MyDinaup no se escribe: lo genera Dinaup Desktop leyendo tu esquema. Cuando cambias el modelo en Flex (añades un campo, creas una sección, modificas un informe) regeneras la librería para que el código vuelva a reflejar el esquema.
### Entra con el usuario Sistema [#entra-con-el-usuario-sistema]
Abre **Dinaup Desktop** con el usuario Sistema. La generación no está disponible para otros usuarios.
### Genera [#genera]
Ve a `Configuración` > `Generar MyDinaup` y pulsa `Commit`. Dinaup vuelca las clases actualizadas al repositorio de tu paquete `MyDinaup`.
### Publica y actualiza la referencia [#publica-y-actualiza-la-referencia]
Publica el paquete y sube la versión en tu proyecto. MyDinaup fija la versión del SDK que le toca (por ejemplo `Dinaup 10.15.0.*`), así que actualiza los dos a la vez.
Si el esquema cambia y no regeneras, el modelo y el servidor se desincronizan: un informe puede pedir una columna que ya no existe. Ahí es donde entra `TolerateMissingColumns`. Regenerar es la solución de fondo.
## Cómo se usa [#cómo-se-usa]
Instala el SDK base y tu paquete MyDinaup:
```bash
dotnet add package Dinaup
dotnet add package Demoup.MyDinaup
```
Conecta el cliente y ejecuta un informe tipado. Las filas ya vienen convertidas:
```csharp
using Dinaup;
using DemoUp.MyDinaup.Reports.FuncionalidadD;
var client = await DinaupClientC.ConnectAsync(
endPoint: "https://api.dinaup.com/v2/tu-codigo",
publicKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
secretKey: "tu-secret-key-aqui"
);
var report = new APIAlmacenesC();
await report.ExecuteQueryAsync(client, page: 1, resultsPerPage: 50);
foreach (var row in report.Rows)
{
Console.WriteLine($"{row.TextoPrincipal}: {row.DisponibleEnTPV}");
}
```
## Qué modelo elegir [#qué-modelo-elegir]
No todos los proyectos usan el MyDinaup de su propia organización:
| Paquete | Cuándo | Nota |
| ------------------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------- |
| `{Empresa}.MyDinaup` | Aplicación atada a un tenant concreto | Lo generas tú desde Dinaup Desktop |
| [`ReadyToGo.MyDinaup`](https://www.nuget.org/packages/ReadyToGo.MyDinaup) | Desarrollo compatible con varias organizaciones | Solo modela la estructura Ready-To-Go |
| [`DemoUp.MyDinaup`](https://www.nuget.org/packages/DemoUp.MyDinaup) | Pruebas del equipo de Dinaup | Pre-producción, desaconsejado en producción: puede traer errores |
## Límites [#límites]
* **Nombres en español.** Las clases y campos salen con los nombres de tu esquema, que suelen estar en español (`APIVentasC`, `ProductosES`). No es configurable: es un reflejo de tu modelo.
* **VB.NET generado.** El código de la librería es VB.NET. Lo consumes igual desde C#; el idioma del paquete no condiciona el de tu aplicación.
* **Hay que regenerar a mano.** No se sincroniza solo. Un cambio de esquema exige volver a `Generar MyDinaup`.
* **Solo `{Empresa}.MyDinaup` refleja tu tenant.** `ReadyToGo` y `DemoUp` son modelos ajenos a tu esquema.
Para el recetario de conexión, lectura, escritura y ejemplos, ver [SDK .NET y API](/docs/guias/sdk-api) y el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
# Web Service Guidelines (/docs/desarrollo/dotnet/web-service-guidelines)
```
app.MapHealthChecks("/HealthCheck");
app.MapGet("/version", () =>
{
return Results.Ok(new
{
version = Assembly.GetExecutingAssembly().GetName().Version.ToString()
});
});
```
# Algoritmos (/docs/desarrollo/flex/algoritmos)
Un **algoritmo** es una operación que defines en Flex y que el sistema convierte en una consulta SQL optimizada. Lo usas para calcular un valor automáticamente: el total de una línea, la suma de una factura, el precio de un producto en catálogo o un dato del usuario que tiene la sesión abierta.
La sintaxis con la que escribes la lógica es [DinaScript](/docs/desarrollo/flex/dinascript). Esta página explica los **tipos de algoritmo**, las **partes** que lo componen y cuándo usar cada cosa; la referencia del lenguaje (operadores, funciones, control de flujo) está en su propia sección.
***
## Tipos de algoritmo [#tipos-de-algoritmo]
Cada tipo se diferencia por **sobre qué datos opera**: una sola fila, registros relacionados, otra sección o ningún contexto de fila. Elige el tipo según el alcance del cálculo.
| Tipo | Sobre qué opera | Devuelve | Ejemplo |
| ----------------- | ---------------------------------- | ---------------------------- | -------------------------------------------------- |
| **Lineal** | Una fila y sus relaciones directas | Un valor de esa fila | `cantidad × precio` de una línea |
| **Cruzado** | Registros relacionados, agregados | Un valor agregado | Sumar todas las líneas de una factura |
| **Búsqueda** | Otra sección, filtrada | El `id` de un registro | El producto de catálogo que coincide con un código |
| **Datos** | Todos los registros de una sección | Un valor agregado global | Total facturado del mes para un dashboard |
| **Independiente** | Sin contexto de fila | Un valor de sesión o cálculo | El usuario o la empresa de la sesión actual |
***
## Matices de cada tipo [#matices-de-cada-tipo]
### Lineal [#lineal]
Trabaja sobre **una única fila** y puede acceder a sus **relaciones directas** para traer datos de registros enlazados. No agrega: el resultado sale de los campos de ese mismo registro y de los que cuelgan de él por una relación.
Por ejemplo, en una línea de venta puedes calcular la comisión combinando un campo propio con un campo del empleado relacionado:
```
venta.total * venta.empleado.comision / 100
```
Es el tipo que alimenta la mayoría de **campos auto-calculados** (⚙️), porque el cálculo vive y muere en la misma fila que se guarda.
→ Más sobre relaciones y campos auto-calculados en [Campos](/docs/desarrollo/flex/campos).
### Cruzado [#cruzado]
**Agrega registros relacionados** con la fila actual y devuelve un único valor. Es el tipo que usas cuando un registro "padre" necesita un total que vive en sus "hijos": una factura que suma sus líneas, un proyecto que suma sus tareas.
Para agregar usa las **funciones de agregación del espacio `F`** de DinaScript (sumar, contar, máximo, etc.). El patrón conceptual es siempre el mismo: indicas qué registros relacionados recorrer y qué campo agregar.
La diferencia clave con el tipo **Lineal** es la dirección: Lineal *baja* a una relación para leer un dato concreto; Cruzado *recoge* muchos registros relacionados y los resume en un número.
### Búsqueda [#búsqueda]
Recorre **otra sección** aplicando un filtro y **devuelve el `id`** del registro que coincide. No trae el dato final directamente: te da la referencia al registro encontrado, que luego usas para enlazar o para leer sus campos.
El caso típico es resolver una relación por una clave de negocio: dado un código de producto, encontrar el registro de catálogo correspondiente.
### Datos [#datos]
**Agrega sobre todos los registros de una sección**, sin limitarse a los relacionados con una fila. Es el motor de los **dashboards** y los widgets: total facturado del periodo, número de oportunidades abiertas, importe medio de pedido.
Usa también las **funciones de agregación del espacio `F`**, pero el conjunto de datos es toda la sección (con los filtros que definas), no el subconjunto relacionado con un registro concreto.
→ Estos cálculos suelen consumirse desde [Informes](/docs/desarrollo/flex/informes) y [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos).
### Independiente [#independiente]
**No tiene contexto de fila.** No opera sobre un registro ni sobre una sección concreta: resuelve un valor del entorno de ejecución, como el usuario o la empresa de la **sesión** actual, o se apoya en **otros algoritmos** para componer su resultado.
Lo usas cuando el cálculo no depende de "dónde estás" sino de "quién eres" o de un dato global del sistema.
***
## Las partes de un algoritmo [#las-partes-de-un-algoritmo]
Un algoritmo no siempre es una sola fórmula. Los tipos que recorren varios registros (**Cruzado**, **Búsqueda** y **Datos**) se construyen por **partes**, cada una con un papel distinto en la consulta que Flex genera. Defines solo las que necesitas: en un cálculo simple basta con la fórmula principal; en un cruzado fino completas las demás para acotar exactamente qué registros entran.
| Parte | Qué hace | Cuándo la usas |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Fórmula principal** | El cálculo en sí: el valor que el algoritmo devuelve (la suma, el `id` encontrado, el importe). | Siempre. Es el corazón del algoritmo. |
| **Prefiltrado** | Un filtro general que descarta registros antes de cualquier otro paso. | Para recortar el universo de datos cuanto antes y que el resto trabaje sobre menos filas. |
| **Filtrado izquierda** (datos principales) | Filtra sobre los **datos principales**: el registro o sección desde el que parte el cálculo. | Cuando quieres limitar la fila o filas de origen (solo las activas, solo las del periodo). |
| **Filtrado derecha** (datos relacionados) | Filtra sobre los **datos relacionados** que el cruce trae al otro lado. | Cuando solo te interesan ciertos registros enlazados (solo las líneas confirmadas, solo cobros de un tipo). |
| **Filtrado Having** (post-agrupación) | Filtra **después de agregar**, sobre el resultado ya agrupado. | Cuando la condición depende del agregado, no de filas sueltas (grupos cuyo total supera un umbral). |
El orden conceptual sigue al de una consulta SQL: primero el **prefiltrado** poda lo evidente, luego los **filtrados izquierda y derecha** acotan cada lado del cruce, la **fórmula principal** agrega, y por último el **Having** descarta grupos enteros según el resultado.
Piénsalo como un embudo. Cada parte estrecha el conjunto de datos en un momento distinto: las de filtrado **antes** de sumar (sobre filas), el **Having** **después** de sumar (sobre el total). Filtrar pronto y por el lado correcto es lo que mantiene el algoritmo rápido aunque la sección sea enorme.
### Cómo encaja en un cruzado [#cómo-encaja-en-un-cruzado]
En un algoritmo **Cruzado** o de **Búsqueda** estás relacionando dos lados (el registro de origen y los registros enlazados) y cada filtrado actúa sobre un lado concreto:
* **Izquierda** = el origen del cruce (la factura, el proyecto, la sección de partida).
* **Derecha** = lo que cruzas contra él (sus líneas, sus tareas, los cobros relacionados).
* **Having** = la condición sobre el agregado final (solo facturas cuya suma de líneas pase de cierto importe).
Así puedes, por ejemplo, sumar **solo** las líneas confirmadas (filtrado derecha) de **solo** las facturas de este año (filtrado izquierda), descartando de entrada los registros anulados (prefiltrado), y quedarte únicamente con los grupos relevantes (Having).
***
## Variables: convertir un algoritmo en parametrizable [#variables-convertir-un-algoritmo-en-parametrizable]
Un algoritmo puede declarar **variables** (preguntas que se resuelven en tiempo de ejecución) y tratarlas como **parámetros** de entrada. Así el mismo algoritmo sirve para varios casos sin duplicarlo: en lugar de fijar un umbral en el código, lo recibes desde fuera.
Las variables locales se referencian con el prefijo `v.` (igual que en [DinaScript](/docs/desarrollo/flex/dinascript)). Por ejemplo, un algoritmo que cuenta registros por encima de una duración mínima recibe esa duración como variable:
```
v.DuracionMinima
```
Quien consume el algoritmo (un informe, un campo, un documento) aporta el valor de `v.DuracionMinima`, y el cálculo se ajusta sin tocar la lógica.
Las **preguntas dinámicas** de un informe encajan de forma natural aquí: el filtro que el usuario rellena al lanzar el informe se traduce en el parámetro que el algoritmo espera.
***
## Dónde se usan [#dónde-se-usan]
Un mismo algoritmo se puede reutilizar en varios sitios:
* **Campos auto-calculados** (⚙️): el valor del campo se recalcula al guardar el registro. Suelen ser algoritmos **Lineales** o **Cruzados**.
* **Columnas de informes**: columnas calculadas que no existen como campo de la sección. Aquí encajan los algoritmos **Cruzados**, de **Búsqueda** y de **Datos**.
* **Documentos dinámicos**: datos calculados que se insertan en una plantilla (factura, presupuesto, email).
***
## Cómo se ejecutan [#cómo-se-ejecutan]
Los algoritmos se **compilan a SQL nativo** y se ejecutan directamente en **PostgreSQL**. No hay procesamiento en memoria intermedia, lo que aporta:
* **Rendimiento**: el cálculo ocurre en la base de datos, junto a los datos.
* **Consistencia**: siempre usan la versión más reciente de los datos.
* **Escalabilidad**: rinden bien aunque la sección tenga millones de registros.
Como el resultado es SQL, un algoritmo es tan rápido como permita el conjunto de datos que toca. Un tipo **Datos** que agrega una sección enorme sin filtros pesará más que un **Lineal** sobre una sola fila. Acota con las partes de **filtrado** cuando el volumen lo pida.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Lineal si el cálculo sale de una sola fila y, como mucho, de un dato que lees siguiendo una relación directa (el precio del producto enlazado). Cruzado si necesitas resumir varios registros relacionados en un número (sumar todas las líneas de la factura).
El identificador (`id`) del registro que coincide con el filtro, no sus campos. Con ese `id` enlazas el registro o lees después los datos que necesites.
Izquierda filtra los datos principales (el origen del cruce); derecha filtra los datos relacionados (lo que cruzas contra él); Having filtra después de agregar, sobre el total ya agrupado. Los dos primeros actúan sobre filas antes de sumar; el Having, sobre el resultado.
No. La fórmula principal es la única imprescindible. El prefiltrado y los filtrados (izquierda, derecha, Having) son opcionales: los añades solo cuando necesitas acotar qué registros entran en el cálculo.
Declarando variables (`v.NombreVariable`). Quien consume el algoritmo (un informe, un campo o un documento) aporta el valor, y el cálculo se adapta sin duplicar la lógica.
En DinaScript. Esta página describe los tipos y las partes; la sintaxis (operadores, funciones del espacio F, control de flujo) vive en su sección.
***
→ [DinaScript](/docs/desarrollo/flex/dinascript)
→ [Campos](/docs/desarrollo/flex/campos)
→ [Informes](/docs/desarrollo/flex/informes)
→ [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos)
# Campos (/docs/desarrollo/flex/campos)
Un **campo** es una columna de una [sección](/docs/desarrollo/flex/secciones). Define qué dato guarda cada registro y cómo se comporta: su tipo, sus validaciones, su valor por defecto, sus cálculos automáticos y sus relaciones con otras secciones.
Para configurar un campo eliges dos cosas: un **tipo base** (qué clase de dato es) y, encima, un **rol** opcional que lo afina (cómo se valida, se formatea y se muestra). Es la diferencia entre decir "esto es texto" y decir "esto es texto, y además es un email".
***
## Tipos base [#tipos-base]
El tipo base es la decisión de fondo: qué naturaleza tiene el dato. Hay **8 tipos base** y cada campo es exactamente uno de ellos.
| Tipo base | Para qué sirve | Ejemplos |
| -------------------- | ---------------------------- | ----------------------------------- |
| **Texto** | Una línea de texto libre | Nombre, referencia, email, NIF |
| **Texto Multilínea** | Texto largo en varias líneas | Descripción, observaciones, notas |
| **Número decimal** | Número con decimales | Importe, precio, peso, porcentaje |
| **Número entero** | Número sin decimales | Cantidad, unidades, contador |
| **Sí/No** | Un valor de dos estados | Activo, pagado, enviado |
| **Fecha** | Un día concreto, sin hora | Fecha de vencimiento, de nacimiento |
| **Fecha y Hora** | Un instante con día y hora | Momento de un evento, de una firma |
| **Hora** | Una hora del día, sin fecha | Hora de apertura, de un fichaje |
Los campos **Fecha y Hora** se guardan siempre en **UTC**. Al mostrarlos en pantalla, Dinaup los convierte a la zona horaria de cada usuario.
Además de estos 8, existe un tipo especial de **Relación**, que enlaza un registro con otro de otra sección (lo tienes más abajo, en [Relaciones entre secciones](#relaciones-entre-secciones)).
***
## Tipo base frente a rol [#tipo-base-frente-a-rol]
El tipo base dice **qué** es el dato. El **rol** dice **cómo** se comporta dentro de ese tipo: qué formato muestra, qué valida y con qué control lo editas. Un mismo tipo base admite muchos roles.
Piénsalo en dos capas:
### Eliges el tipo base [#eliges-el-tipo-base]
Decides la naturaleza del dato. Por ejemplo, **Texto**.
### Le pones un rol encima [#le-pones-un-rol-encima]
Afinas ese texto. Con el rol **Email** validas que tenga forma de correo; con **Teléfono** lo formateas y lo haces pulsable; con **Web** validas y enlazas la URL.
Algunos roles típicos para que veas el patrón:
| Tipo base | Roles de ejemplo | Qué aportan |
| ------------------ | ------------------------------------------- | --------------------------------------------------- |
| **Texto** | Email, Teléfono, Web, NIF/CIF, Color, IBAN | Validan el formato y lo presentan de forma adecuada |
| **Número entero** | Porcentaje, Moneda, Año, unidades de tiempo | Cambian cómo se muestra y se interpreta el número |
| **Número decimal** | Porcentaje, Moneda, Latitud/Longitud | Formato monetario, porcentual o de coordenadas |
El **catálogo completo de roles** de cada tipo base (con su validación y su forma de presentación) vive en la referencia técnica de Flex. Consúltala en [doc-flex.dinaup.com](https://doc-flex.dinaup.com/referencia/roles-de-campo/).
***
## Atributos de un campo [#atributos-de-un-campo]
Más allá del tipo y el rol, cada campo tiene atributos que controlan si es obligatorio, editable o visible:
| Atributo | Qué hace |
| ------------------ | --------------------------------------------------------------------------------------------- |
| **Obligatorio** | El registro no se puede guardar si el campo está vacío |
| **Bloqueado** | Solo lectura. Su valor lo pone el sistema o un cálculo, no el usuario |
| **Oculto** | No aparece en la interfaz por defecto |
| **Auto-calculado** | Su valor se obtiene de un [algoritmo](/docs/desarrollo/flex/algoritmos), no se escribe a mano |
***
## Valores por defecto [#valores-por-defecto]
Un campo puede arrancar con un valor predefinido cuando se crea un registro nuevo:
* **Valor fijo**: un texto, número o fecha concreto siempre igual.
* **Valor dinámico**: se calcula en el momento del alta a partir del usuario actual, la fecha de hoy u otros campos del propio registro.
***
## Autorrellenado [#autorrellenado]
Los campos de **Relación** pueden completar otros campos al elegir un registro relacionado. Por ejemplo, al seleccionar un cliente en una factura, su NIF, su dirección fiscal y sus condiciones de pago se rellenan solos.
Así reduces tecleo y evitas que el mismo dato se introduzca de dos formas distintas.
***
## Relaciones entre secciones [#relaciones-entre-secciones]
Un campo de **Relación** enlaza un registro con otro de otra sección. Es lo que conecta tu modelo de datos. Con relaciones puedes:
* Navegar de una factura al cliente asociado.
* Sumar las líneas de una factura con un [algoritmo](/docs/desarrollo/flex/algoritmos) cruzado.
* Cruzar datos de varias secciones en un mismo [informe](/docs/desarrollo/flex/informes).
Cuando una **Relación** no apunta a nada, se guarda como cadena vacía, no como ausencia de valor. Tenlo en cuenta al filtrar "relaciones vacías" en informes o algoritmos.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El tipo base define la naturaleza del dato (Texto, Número decimal, Fecha…) y hay 8. El rol va encima del tipo base y afina su validación y su presentación (por ejemplo, un Texto con rol Email valida el formato de correo). Un mismo tipo base admite varios roles.
Ocho: Texto, Texto Multilínea, Número decimal, Número entero, Sí/No, Fecha, Fecha y Hora y Hora. Aparte existe el tipo Relación, que enlaza con registros de otra sección.
En la referencia técnica de Flex: doc-flex.dinaup.com. Ahí tienes cada rol con su tipo base, su validación y cómo se muestra.
Sí. Marca el campo como auto-calculado y asígnale un algoritmo. Su valor se obtiene del cálculo y normalmente el campo queda bloqueado para que no se edite a mano.
***
→ [Secciones](/docs/desarrollo/flex/secciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
→ [Informes](/docs/desarrollo/flex/informes)
→ [Referencia técnica de campos (doc-flex.dinaup.com)](https://doc-flex.dinaup.com/referencia/tipos-de-campo/)
# Dinaup Flex (/docs/desarrollo/flex)
**Dinaup Flex** es la plataforma no-code/low-code para personalizar y extender el sistema sin programar: crear secciones de datos, definir campos e informes, generar documentos y automatizar procesos.
Para acceder a Dinaup Flex, el usuario necesita el permiso **Dinaup Flex** activado. Este permiso debe asignarse únicamente a personal técnico cualificado.
***
## Componentes de Flex [#componentes-de-flex]
### Secciones y Campos [#secciones-y-campos]
Las secciones son las tablas de datos de tu sistema. Cada sección contiene campos que definen la estructura de la información.
| Concepto | Descripción |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Sección** | Equivalente a una tabla de base de datos. Almacena registros de un tipo específico (clientes, facturas, productos, etc.) |
| **Sección base** | Estructura compartida por varias secciones derivadas. Evita duplicación de campos comunes. |
| **Campo** | Cada columna de la sección: texto, número, fecha, relación, sí/no, decimal, etc. |
| **Relación** | Campo que enlaza un registro con otro de otra sección (ej: Factura → Cliente) |
Los campos pueden configurarse con:
* **Validaciones**: obligatorio, rango de valores, formato
* **Valores por defecto**: fijos o calculados en el momento del alta
* **Autorrellenado**: se completan solos a partir de otros campos o de la sesión del usuario
* **Bloqueo**: campos de solo lectura que se calculan por el sistema
→ Ver [Secciones](/docs/desarrollo/flex/secciones) · [Campos](/docs/desarrollo/flex/campos)
### Informes [#informes]
Los informes permiten crear listados y consultas sobre cualquier sección, sin escribir SQL.
* Selecciona las **columnas** que necesitas
* Aplica **filtros** y **ordenación**
* Agrupa datos y crea **columnas calculadas** con algoritmos
* Define **preguntas dinámicas** para que el informe acepte parámetros
* Consume informes desde la **API** para integraciones externas
→ Ver [Informes](/docs/desarrollo/flex/informes)
### Algoritmos [#algoritmos]
Los algoritmos son operaciones programadas que se ejecutan como consultas SQL optimizadas. Se usan para cálculos automáticos en campos, columnas de informes y documentos dinámicos.
| Tipo | Descripción | Ejemplo |
| ----------------- | -------------------------------------- | -------------------------------------------------- |
| **Lineal** | Opera sobre los datos de la misma fila | Calcular el total de una línea de factura |
| **Cruzado** | Agrega datos de registros relacionados | Sumar todas las líneas de una factura |
| **Búsqueda** | Encuentra datos en otras secciones | Obtener el precio de un producto desde el catálogo |
| **Datos** | Accede a datos del contexto actual | Obtener el usuario actual o la fecha |
| **Independiente** | No depende de una fila específica | Calcular totales globales |
→ Ver [Algoritmos](/docs/desarrollo/flex/algoritmos)
### Documentos dinámicos [#documentos-dinámicos]
Genera documentos personalizados en múltiples formatos combinando datos con plantillas programables.
| Formato | Uso típico |
| --------- | ------------------------------------------- |
| **HTML** | Facturas para impresión, informes visuales |
| **JSON** | Integración con APIs externas |
| **PDF** | Documentos oficiales, presupuestos |
| **Email** | Plantillas de correo con datos del registro |
Los documentos dinámicos pueden:
* Incluir **JavaScript** para visualizaciones interactivas
* Usarse como **widgets** en dashboards
* Consultarse desde la **API** para integraciones
→ Ver [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos)
### DinaScript [#dinascript]
Lenguaje de scripting para lógica avanzada dentro de Flex. Se organiza en espacios de nombres:
* **F (Functions)**: funciones para manipulación de datos, operaciones matemáticas, texto, fechas
* **S (Schema)**: acceso a la estructura del esquema, secciones y campos
→ Ver [DinaScript](/docs/desarrollo/flex/dinascript)
***
## Estructura Flex detallada [#estructura-flex-detallada]
La documentación técnica completa de todas las secciones del sistema (incluyendo campos, relaciones, tablas PostgreSQL y descripciones detalladas) está disponible en:
→ [doc-flex.dinaup.com](https://doc-flex.dinaup.com/)
Esta referencia incluye más de 180 secciones organizadas por módulo, con detalle de cada campo, su tipo, rol, columna PostgreSQL y atributos.
***
## Secciones principales por módulo [#secciones-principales-por-módulo]
### Compra - Venta [#compra---venta]
Ventas/Ingresos, Compras/Gastos, Presupuestos, Cobros, Pagos, Libros Registro, Movimientos de inventario
### Contabilidad [#contabilidad]
Asientos contables, Cuadro de cuentas, Ejercicios, Inmovilizados, Documentos oficiales
### Inventario [#inventario]
Productos, Almacenes, Zonas, Huecos, Catálogos de compra/venta, Lotes
### CRM [#crm]
Oportunidades, Eventos/Seguimientos, Procesos de venta, Citas
### Recursos Humanos [#recursos-humanos]
Empleados, Contratos laborales, Fichajes, Ausencias, Horarios, Turnos, Correspondencias
### Entidades [#entidades]
Datos fiscales, Tipos de cliente, Direcciones de envío, Dominios de internet
### Proyectos [#proyectos]
Proyectos, Tareas, Actividades, Servicios, Carriles de vistas
# Roles de campo (/docs/desarrollo/flex/roles-de-campo)
Un **rol** especializa cómo se comporta y se muestra un [campo](/docs/desarrollo/flex/campos) según lo que guarda dentro. No crea un tipo nuevo: parte del tipo base del campo (texto, número, fecha…) y le añade un comportamiento, un formato de presentación y, a veces, validaciones acordes a lo que representa.
Piensa en un campo de texto: con rol **Email** lo muestra como un enlace `mailto:`, con rol **Teléfono** lo prepara para llamar, con rol **IBAN** lo trata como una cuenta bancaria. El dato sigue siendo texto; el rol decide cómo se presenta y qué se espera de él.
**Tipo vs rol.** El **tipo** define qué clase de dato guarda el campo (texto, número, fecha). El **rol** afina cómo se interpreta y se enseña ese dato. Eliges primero el tipo y luego, si encaja, el rol.
***
## Por qué usar un rol [#por-qué-usar-un-rol]
Un mismo tipo de dato puede significar cosas muy distintas. Un número puede ser dinero, un porcentaje, un peso o una cantidad de bytes. Un texto puede ser un correo, una matrícula o un NIF. El rol cierra esa ambigüedad y te da tres ventajas:
* **Presentación correcta**: el valor se muestra con el símbolo, el formato o el icono que le corresponde (€, %, MB, un enlace clicable).
* **Interacción adecuada**: un email abre el cliente de correo, un teléfono inicia la llamada, una web abre el navegador.
* **Validación coherente**: roles como NIF/CIF o IBAN dan por hecho que el contenido sigue un formato concreto.
Elegir bien el rol es lo que hace que un registro se entienda sin que nadie tenga que interpretar el dato en bruto.
***
## Presentación [#presentación]
Roles que cambian **cómo se muestra** el valor o cómo se interactúa con él. La mayoría parten de un campo de texto o número.
| Rol | Para qué sirve |
| --------------- | --------------------------------------------------------------------------- |
| **Ordinario** | Comportamiento estándar, sin especialización. El valor se muestra tal cual. |
| **Web** | Una dirección de internet. Se presenta como enlace que abre el navegador. |
| **Teléfono** | Un número de teléfono, preparado para llamar. |
| **Skype** | Un identificador de Skype. |
| **Email** | Un correo electrónico. Se muestra como enlace `mailto:`. |
| **Moneda** | Un importe monetario, con su símbolo de moneda. |
| **Porcentaje** | Un valor expresado en tanto por ciento (%). |
| **Icono** | El campo representa un icono. |
| **Icono Color** | Un icono con color asociado. |
| **Imagen** | Una imagen, que se previsualiza. |
| **Archivo** | Un fichero adjunto. |
| **Contraseña** | Un valor sensible, que se oculta al mostrarlo. |
***
## Medida y precisión [#medida-y-precisión]
Roles para **números** que representan magnitudes, tiempos o tamaños. Definen la unidad y la precisión con la que se trabaja el valor.
| Rol | Para qué sirve |
| ---------------- | ---------------------------------------------------------------- |
| **Preciso** | Número con precisión avanzada (más decimales de los habituales). |
| **Horas** | Una duración expresada en horas. |
| **Minutos** | Una duración en minutos. |
| **Segundos** | Una duración en segundos. |
| **Milisegundos** | Una duración en milisegundos. |
| **Bytes** | Un tamaño de datos en bytes. |
| **Megabytes** | Un tamaño en megabytes. |
| **Gigabytes** | Un tamaño en gigabytes. |
| **Gramos** | Un peso en gramos. |
| **Cronómetro** | Un tiempo medido a modo de cronómetro. |
| **Ratio** | Una proporción o relación entre dos magnitudes. |
| **Texto 60** | Un texto acotado a una longitud corta (60 caracteres). |
***
## Fiscales y de legislación [#fiscales-y-de-legislación]
Roles pensados para datos con un formato legal o contable definido. Asumen que el contenido sigue las reglas del dato que representan.
| Rol | Para qué sirve |
| ------------------------------------ | ------------------------------------------------------- |
| **NIF/CIF** | Un identificador fiscal (NIF o CIF). |
| **Tipo NIF/CIF** | El tipo de identificador fiscal asociado. |
| **CCC** | Un código de cuenta de cliente bancaria (formato CCC). |
| **IBAN** | Una cuenta bancaria en formato IBAN. |
| **Territorialidad - País** | Un país a efectos de territorialidad fiscal. |
| **Territorialidad - Provincia** | Una provincia a efectos de territorialidad fiscal. |
| **Clave operación intracomunitaria** | La clave que identifica una operación intracomunitaria. |
| **Código subcuenta** | El código de una subcuenta contable. |
| **Código cuenta contable** | El código de una cuenta contable. |
Los roles fiscales no sustituyen a la validación oficial de un organismo: definen el **formato esperado** del dato. La comprobación contra registros externos depende del proceso de negocio, no del rol del campo.
***
## Texto [#texto]
Roles para campos de **texto** que necesitan más espacio o formato enriquecido que una línea simple.
| Rol | Para qué sirve |
| ----------------- | --------------------------------------------------------- |
| **Multilínea** | Texto en varias líneas (área de texto). |
| **Texto largo** | Un bloque de texto extenso. |
| **HTML** | Contenido en formato HTML. |
| **HTML (Editor)** | Contenido HTML con un editor enriquecido para redactarlo. |
***
## Especiales [#especiales]
Roles para casos concretos que no encajan en las familias anteriores.
| Rol | Para qué sirve |
| -------------------------------- | ---------------------------------------------------------------------------- |
| **Referencia Pistola** | Un código pensado para leerse con pistola de códigos de barras. |
| **Año** | Un año (valor temporal acotado). |
| **Color Hex** | Un color en formato hexadecimal. |
| **Fecha Principal** | La fecha que actúa como fecha de referencia del registro. |
| **Datos serializados** | Un valor que guarda datos estructurados serializados. |
| **Condiciones de cadena mágica** | Define condiciones mediante una cadena de texto interpretada por el sistema. |
| **Asistente URL** | Un campo de texto que almacena una URL con ayuda para construirla. |
***
## Cómo encaja un rol con el resto de Flex [#cómo-encaja-un-rol-con-el-resto-de-flex]
El rol es una propiedad del campo, así que vive dentro de la definición de la [sección](/docs/desarrollo/flex/secciones):
* Se elige al configurar un [campo](/docs/desarrollo/flex/campos), después de fijar su tipo base.
* Afecta a cómo se presenta el valor en formularios, fichas e [informes](/docs/desarrollo/flex/informes), no a cómo se almacena.
* Cuando un [algoritmo](/docs/desarrollo/flex/algoritmos) calcula el valor de un campo, el rol determina cómo se muestra ese resultado (un importe en €, un porcentaje, un tamaño en MB).
Cambiar el rol de un campo que ya tiene datos altera cómo se interpretan esos valores. Si el contenido no encaja con el nuevo rol (por ejemplo, pasar a IBAN un texto que no es una cuenta), la presentación dejará de tener sentido. Cambia el rol con criterio y revisa los registros existentes.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. El rol especializa un tipo que ya existe. Un campo de texto con rol Email sigue siendo texto: el rol solo decide cómo se muestra y qué se espera de su contenido.
Sí, pero con cuidado. El rol cambia cómo se interpretan los valores guardados. Si el contenido no encaja con el nuevo rol, la presentación dejará de ser correcta. Revisa los datos existentes antes de cambiarlo.
Ambos parten de un número, pero lo presentan distinto: Moneda lo muestra como un importe con su símbolo de moneda; Porcentaje lo muestra como un tanto por ciento (%). El número guardado es el mismo tipo de dato; cambia su lectura.
Algunos roles (NIF/CIF, IBAN, Email) asumen un formato concreto y orientan la presentación a él. Definen el formato esperado del dato, no una comprobación oficial contra organismos externos.
***
→ [Campos](/docs/desarrollo/flex/campos)
→ [Secciones](/docs/desarrollo/flex/secciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
# Scripts y eventos (/docs/desarrollo/flex/scripts)
Un **script** es lógica que se ejecuta cuando ocurre un **evento**. El evento es el disparador (el usuario abre un formulario, cambia un campo, pulsa un botón); el script es lo que pasa a continuación (recalcular un total, validar antes de guardar, lanzar un informe).
Esta es la pieza de [Flex](/docs/desarrollo/flex) que da comportamiento a tus [secciones](/docs/desarrollo/flex/secciones): mientras las secciones y los [campos](/docs/desarrollo/flex/campos) definen *qué* datos hay, los scripts definen *qué ocurre* cuando se trabaja con ellos.
Un script siempre responde a la pregunta "**cuándo**" antes que a la de "**qué**". Primero eliges el evento que lo dispara; después decides la lógica que ejecuta. Sin evento no hay script.
***
## Tipos de script [#tipos-de-script]
Según la lógica que quieras ejecutar, eliges un tipo. Todos se asocian a un evento de la misma forma; lo que cambia es lo que hacen al dispararse.
| Tipo | Para qué sirve |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Terminal** | Ejecuta instrucciones en el terminal del dispositivo: abrir una ventana, navegar a otra sección, refrescar datos, mostrar un mensaje. Es la forma de orquestar la interfaz. |
| **Algoritmo** | Calcula valores y aplica reglas con [DinaScript](/docs/desarrollo/flex/dinascript). Se usa para totales, validaciones y derivar campos a partir de otros. → Ver [Algoritmos](/docs/desarrollo/flex/algoritmos). |
| **Plantilla de impresión** | Genera un documento (factura, albarán, listado) a partir de los datos. → Ver [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos). |
| **Función API** | Invoca una operación expuesta por la API para integrar con servicios externos o disparar procesos. |
***
## Scripts de formulario y scripts de campo [#scripts-de-formulario-y-scripts-de-campo]
Hay dos ámbitos según *dónde* viva el script. Es la primera decisión que tomas: ¿reacciona a algo que pasa en **todo el formulario**, o a algo que pasa en **un campo concreto**?
| Ámbito | Reacciona a… | Ejemplo |
| ------------------------ | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| **Script de formulario** | El ciclo de vida del registro completo: abrirlo, cargarlo, aceptarlo, cancelarlo, recalcularlo. | Recalcular el total de una factura justo antes de aceptarla. |
| **Script de campo** | Lo que ocurre en un campo individual: cambiar su valor, ganar o perder el foco, pulsarlo. | Al cambiar la cantidad, recalcular el subtotal de esa línea. |
La diferencia práctica: un **script de formulario** se dispara una vez por operación sobre el registro; un **script de campo** se dispara cada vez que el usuario interactúa con ese campo. Elige el ámbito según la granularidad que necesites.
***
## Eventos de formulario [#eventos-de-formulario]
Se disparan en distintos momentos del ciclo de vida del registro que el usuario tiene abierto.
| Evento | Cuándo se dispara |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Iniciado al agregar nuevo** | Al empezar a crear un registro nuevo, antes de que el usuario escriba nada. Ideal para fijar valores por defecto. |
| **Pre-aceptar** | Justo antes de guardar. El momento para validar y bloquear el guardado si algo no cuadra, o para recalcular totales finales. |
| **Pre-cancelar** | Justo antes de descartar los cambios. Útil para confirmar o limpiar estado. |
| **Tick de recálculo** | En cada ciclo de recálculo del formulario, para mantener valores derivados al día mientras se edita. |
| **Recalcular listado** | Al refrescar el listado de líneas o registros asociados. |
| **Cargado** | Cuando el formulario termina de cargar sus datos. Para ajustes que dependen del registro ya disponible. |
| **Valores de catálogos establecidos** | Cuando los catálogos (listas de opciones) ya están cargados y disponibles para usarse. |
| **Atajo de teclado / Macro** | Al pulsar una combinación de teclas asociada, para lanzar una acción rápida. |
***
## Eventos de campo [#eventos-de-campo]
Se disparan por la interacción del usuario con un campo concreto del formulario.
| Evento | Cuándo se dispara |
| ------------------------ | ---------------------------------------------------------------------------------------------------- |
| **Cambiado** | El valor del campo cambia. El evento más habitual para recalcular dependencias. |
| **Pierde foco** | El usuario sale del campo. Buen momento para validar lo que acaba de introducir. |
| **Gana foco** | El usuario entra en el campo. |
| **Cierra relación** | Se cierra una relación asociada al campo. |
| **Pre-agregar relación** | Justo antes de añadir un registro relacionado, para validar o preparar la nueva relación. |
| **Combo aplicar filtro** | Al aplicar un filtro sobre un campo de tipo lista o combo, para acotar las opciones que se muestran. |
| **Click** | El usuario pulsa el campo (típico en campos que actúan como botón o acción). |
***
## Otros disparadores [#otros-disparadores]
Más allá del formulario y los campos, un script puede ejecutarse de forma independiente o desde los informes.
| Disparador | Qué hace |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Independiente** | El script no cuelga de un formulario ni de un campo: se ejecuta por sí mismo cuando se invoca. |
| **Informe** | Se lanza sobre el resultado de un [informe](/docs/desarrollo/flex/informes) completo. |
| **Informe (filas seleccionadas)** | Se lanza solo sobre las filas que el usuario ha seleccionado en un informe, para actuar sobre un subconjunto. |
***
## Contextos [#contextos]
El **contexto** indica dónde aparece y se puede activar un script. Determina en qué parte de la interfaz queda disponible para el usuario.
| Contexto | Dónde aparece |
| ---------------------- | ------------------------------------------------------ |
| **Todos** | Disponible en todos los contextos aplicables. |
| **Campos personales** | Asociado a campos personalizados de la sección. |
| **Botones de informe** | Como acción accesible desde los botones de un informe. |
| **Botones de widget** | Como acción accesible desde los botones de un widget. |
***
## Cómo encajan los scripts en Flex [#cómo-encajan-los-scripts-en-flex]
Los scripts son el pegamento entre las piezas de Flex: las secciones aportan los datos, los algoritmos calculan, los documentos imprimen, y los scripts deciden **cuándo** se dispara cada cosa.
* Operan sobre [secciones](/docs/desarrollo/flex/secciones) y sus [campos](/docs/desarrollo/flex/campos), reaccionando a lo que el usuario hace con ellos.
* Un script de tipo Algoritmo ejecuta lógica de [DinaScript](/docs/desarrollo/flex/dinascript) para calcular o validar valores. → Ver [Algoritmos](/docs/desarrollo/flex/algoritmos).
* Un script de tipo Plantilla de impresión genera salida con [documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos).
* Los disparadores de informe conectan los scripts con los [informes](/docs/desarrollo/flex/informes), para actuar sobre sus resultados.
Un script es lógica que se ejecuta sola sobre tus datos. Defínelo con criterio y prueba el resultado antes de dejarlo en producción, igual que cualquier automatización. Un **Pre-aceptar** mal planteado puede bloquear guardados; un **Cambiado** que recalcula de más puede ralentizar la edición.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Un script de formulario reacciona al ciclo de vida del registro completo (abrirlo, cargarlo, aceptarlo, cancelarlo) y se dispara una vez por operación. Un script de campo reacciona a la interacción con un campo concreto (cambiarlo, ganar o perder el foco) y se dispara cada vez que el usuario toca ese campo. Elige según la granularidad que necesites.
Con un script de formulario en el evento Pre-aceptar. Se dispara justo antes de guardar, así que es el sitio para comprobar que todo cuadra y, si no, impedir el guardado. Para validar un campo concreto en cuanto el usuario lo abandona, usa el evento Pierde foco en ese campo.
Sí: usa un script de tipo Algoritmo, que ejecuta lógica de DinaScript para calcular totales, derivar campos o aplicar reglas. → Ver Algoritmos.
El tipo Plantilla de impresión, que genera la salida (factura, albarán, listado) a partir de los datos del registro. → Ver Documentos dinámicos.
***
→ [Recetas de scripts (ejemplos reales)](/docs/desarrollo/flex/dinascript/recetas-de-scripts)
→ [Secciones](/docs/desarrollo/flex/secciones)
→ [Campos](/docs/desarrollo/flex/campos)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
→ [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos)
→ [Informes](/docs/desarrollo/flex/informes)
# Secciones (/docs/desarrollo/flex/secciones)
Una **sección** es el equivalente a una tabla de base de datos en Dinaup. Cada sección almacena registros de un tipo específico: clientes, facturas, productos, empleados, o cualquier entidad que necesites modelar.
***
## Estructura de una sección [#estructura-de-una-sección]
Cada sección tiene:
| Propiedad | Descripción |
| ------------------------- | ----------------------------------------------------------------------- |
| **ID** | Identificador UUID único de la sección |
| **Nombre** | Nombre visible para los usuarios (ej: "Productos", "Facturas Emitidas") |
| **Tabla PostgreSQL** | Nombre de la tabla donde se almacenan los datos (formato `tpr_*`) |
| **Sección base** | Sección de la que hereda campos comunes (opcional) |
| **Campos del sistema** | Campos que gestiona Dinaup (ID, fecha de alta, autor, etc.) |
| **Campos personalizados** | Campos definidos por el usuario o por los módulos Ready To Go |
***
## Campos del sistema [#campos-del-sistema]
Todas las secciones incluyen campos del sistema que Dinaup gestiona por ti:
| Campo | Tipo | Descripción |
| ----------------------------- | ------------ | ---------------------------------------------- |
| `id` | UUID | Identificador único del registro |
| `fechaalta_utc` | Fecha y hora | Fecha de creación (UTC) |
| `fechaultimamodificacion_utc` | Fecha y hora | Última modificación (UTC) |
| `fechaindiceactividad_utc` | Fecha y hora | Última actividad relevante (UTC) |
| `autoridalta` | Relación | Usuario que creó el registro |
| `empresa` | Relación | Empresa (licencia) a la que pertenece |
| `textoprincipal` | Texto | Campo de texto principal (nombre, título) |
| `eliminado` | Sí/No | Eliminación lógica (0 = activo, 1 = eliminado) |
| `bloqueado` | Sí/No | Registro bloqueado para edición |
***
## Secciones base [#secciones-base]
Una sección base permite compartir campos entre varias secciones derivadas. Por ejemplo, la sección base "Entidades" contiene campos comunes (NIF, dirección, teléfono) que comparten las secciones "Clientes", "Proveedores" y "Bancos".
Esto evita duplicar campos y garantiza coherencia.
***
## Secciones Ready To Go [#secciones-ready-to-go]
Los módulos Ready To Go incluyen más de 180 secciones predefinidas organizadas por área:
| Área | Secciones principales |
| ---------------- | ----------------------------------------------------------------------------- |
| **Compra-Venta** | Ventas/Ingresos, Compras/Gastos, Presupuestos, Cobros, Pagos, Libros Registro |
| **Contabilidad** | Asientos, Cuadro de cuentas, Ejercicios, Inmovilizados |
| **Inventario** | Productos, Almacenes, Zonas, Catálogos de compra/venta, Lotes |
| **CRM** | Oportunidades, Eventos, Procesos de venta |
| **RRHH** | Empleados, Contratos, Fichajes, Ausencias, Horarios, Turnos |
| **Entidades** | Datos fiscales, Direcciones de envío, Dominios |
| **Proyectos** | Proyectos, Tareas, Actividades, Servicios |
Puedes modificar las secciones Ready To Go (añadir campos, cambiar validaciones) o crear secciones nuevas.
***
## Crear una sección personalizada [#crear-una-sección-personalizada]
Desde **Dinaup Desktop** o desde **Play Dinaup > Desarrollo > Esquema**:
1. Define el **nombre** de la sección
2. Opcionalmente, selecciona una **sección base** de la que heredar campos
3. Añade los **campos** que necesites (ver [Campos](/docs/desarrollo/flex/campos))
4. Configura **permisos** de acceso por rol
5. Crea **informes** para consultar los datos (ver [Informes](/docs/desarrollo/flex/informes))
Una vez creada, la sección está disponible para:
* Introducir datos desde la interfaz de Play Dinaup
* Consultarla desde la API REST o el SDK .NET
* Incluirla en informes y documentos dinámicos
* Conectarla con otras secciones mediante relaciones
***
## Referencia completa [#referencia-completa]
La documentación técnica de todas las secciones del sistema (campos, tipos, columnas PostgreSQL, scripts y relaciones) está disponible en:
→ [doc-flex.dinaup.com](https://doc-flex.dinaup.com/)
# Referencia de la API REST (/docs/desarrollo/integraciones/api-rest-referencia)
La **API REST pública de Dinaup** te deja leer y escribir tus datos desde cualquier lenguaje, mediante peticiones HTTP. Se sirve desde `https://webhook.dinaup.com` y está pensada para integradores: conectar una tienda online, alimentar un dashboard, importar datos en lote o sincronizar con otro sistema.
Esta página es el **mapa de capacidades**: qué endpoint usar para cada tarea. Para el detalle de parámetros, cuerpos y respuestas de cada llamada, ve a la [referencia completa de endpoints](/docs/desarrollo/integraciones/webhook/entrantes).
¿Programas en .NET? Tienes un [SDK oficial](/docs/desarrollo/dotnet/sdk) con tipado fuerte y nombres de campo legibles. La API REST es la vía universal para cualquier otro lenguaje.
***
## Autenticación [#autenticación]
Toda petición (salvo el *ping*) viaja con un **Token Bearer** en la cabecera HTTP. El token hereda los permisos del usuario al que pertenece: solo accede a lo que ese usuario puede ver y escribir.
```
Authorization: Bearer
```
El token no es tu clave API en crudo: Dinaup lo deriva de la clave y su secreto, firmados. Genera la clave en el panel de administración, márcala como compatible con webhooks y copia el token desde el Playground. El detalle está en la [referencia de endpoints](/docs/desarrollo/integraciones/webhook/entrantes#autenticación).
Usa la clave API solo en tu **backend**. Nunca la incrustes en código público ni en el frontend de una web.
→ [Claves API](/docs/cuenta/claves-api)
***
## Formato de las respuestas [#formato-de-las-respuestas]
Todas las respuestas son **JSON**. Cada endpoint devuelve su propia forma: `whoami` trae el usuario, `reports` trae las filas paginadas, `writeoperations` trae el resultado de la operación. El detalle de cada cuerpo está en la [referencia de endpoints](/docs/desarrollo/integraciones/webhook/entrantes).
Si algo falla, la respuesta llega con un código HTTP de error (`401` sin token, `403` sin permiso, `400` con datos inválidos) y un mensaje que describe el motivo. Ramificas tu integración leyendo el código de estado.
***
## Endpoints de consulta [#endpoints-de-consulta]
Lectura de datos: comprobar que todo está vivo, saber con qué usuario operas y ejecutar lo que ya tienes configurado en [Flex](/docs/desarrollo/flex).
| Endpoint | Para qué sirve |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Ping** | Comprueba que el servidor está operativo. No requiere autenticación; ideal para *healthchecks*. |
| **Whoami** | Devuelve el usuario asociado al token. Úsalo para verificar que la autenticación funciona. |
| **Ejecutar informe** | Lanza un [informe de Flex](/docs/desarrollo/flex/informes) ya configurado y te devuelve sus filas en JSON, paginadas. |
| **Documento dinámico** | Renderiza una [plantilla de documento dinámico](/docs/desarrollo/flex/documentos-dinamicos) con los datos que le pases (HTML, JSON, texto). |
Primero configuras el informe o el documento dentro de Dinaup (columnas, filtros, plantilla) y luego lo ejecutas por API. La API **dispara** lo que tú ya dejaste preparado en Flex.
***
## Endpoint de escritura [#endpoint-de-escritura]
| Endpoint | Para qué sirve |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **WriteOperations** | Crea o actualiza registros en cualquier sección. La misma operación sirve para alta y edición, admite lote e importación padre + hijos, y el borrado es lógico (editar marcando el registro como eliminado). |
Las escrituras respetan los permisos del usuario del token. Si ese usuario no puede escribir en una sección, la operación se rechaza con un error.
→ El detalle de parámetros, formatos de cuerpo (objeto simple, padre + hijos, lote) y ejemplos `curl` está en la [referencia de endpoints](/docs/desarrollo/integraciones/webhook/entrantes).
***
## Límites [#límites]
La API protege el servicio con dos topes:
* **Paginación**: un informe devuelve resultados **paginados**; pide las páginas que necesites con `page` y `resultsPerPage` en lugar de un volcado único.
* **Límite de tasa por endpoint**: cada endpoint acota las peticiones por periodo. Si lo superas, recibes `429 Too Many Requests` con la cabecera `Retry-After` indicando cuándo reintentar.
Las cifras exactas de cada endpoint están en la [referencia de endpoints](/docs/desarrollo/integraciones/webhook/entrantes#límites-de-tasa).
***
## Recibir eventos (webhooks salientes) [#recibir-eventos-webhooks-salientes]
La API REST es la dirección **tú → Dinaup** (tú preguntas, Dinaup responde). Para la dirección contraria (que **Dinaup te avise** cuando se crea o modifica un registro) usa los **webhooks salientes**: configuras una URL y Dinaup le envía una petición en tiempo real.
→ [Configurar webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes)
***
## Preguntas frecuentes [#preguntas-frecuentes]
Configura un informe en Flex con las columnas y filtros que quieras y ejecútalo por API. Es la vía estándar para extraer datos en JSON, ya paginados.
Con WriteOperations. La misma operación sirve para crear y para editar, y admite lotes: pasas un array de registros en una sola petición para importar en bloque. El detalle está en la referencia de endpoints.
No. El ping es un healthcheck público que solo confirma que el servidor responde. El resto de endpoints sí requieren tu Token Bearer.
Si tu aplicación es .NET, el SDK te da tipado fuerte y nombres de campo legibles. Para cualquier otro lenguaje, la API REST es la opción universal.
***
→ [Referencia completa de endpoints](/docs/desarrollo/integraciones/webhook/entrantes)
→ [API y Webhooks](/docs/desarrollo/integraciones/webhook)
→ [SDK .NET](/docs/desarrollo/dotnet/sdk)
→ [Integraciones](/docs/desarrollo/integraciones)
# Cloudflare Worker (/docs/desarrollo/integraciones/cloudflare-worker)
Puedes intercalar un Worker de Cloudflare entre el [Webhook de Dinaup](/docs/desarrollo/integraciones/webhook) y tus sistemas. Esto te aporta:
* **Reescritura de URLs:** transforma las direcciones para adaptar las peticiones al formato que esperan plataformas como Make, Zapier u otras.
* **Protección del endpoint:** filtra y verifica las solicitudes antes de que lleguen a Dinaup, para evitar accesos no autorizados.
* **Encolado con Cloudflare Queue:** organiza las solicitudes en una cola para gestionar picos de tráfico sin sobrecargar el sistema.
* **Gestión segura de secretos:** almacena tokens y credenciales en el sistema de secretos de Cloudflare, fuera del código.
* **Observabilidad:** captura métricas y logs en tiempo real con la infraestructura de Cloudflare.
* **Caching:** configura un `cacheTtl` y reescribe cabeceras para servir respuestas repetidas sin volver a llamar al backend.
## Ejemplo Caching [#ejemplo-caching]
Este worker actúa como un proxy que realiza una solicitud POST. La respuesta se cachea durante 10 segundos tanto en Cloudflare como en el navegador.
```javascript
const apiUrl = "https://webhook.dinaup.com/api/reports?id=&page=1&resultsPerPage=100&withFiles=false&safeColumnsName=false";
export default {
async fetch(request, env, ctx) {
const init = {
method: "POST",
headers: {
"Authorization": "Bearer " + env.SECRET_TOKEN,
},
body: "",
};
// Ejecutar la llamada a la URL con opciones de caché: 10 segundos
const newRequest = new Request(apiUrl, init);
const response = await fetch(newRequest, {
cf: {
cacheTtl: 10,
cacheEverything: true,
}
});
// Ajustar las cabeceras para que el navegador también cachee la respuesta
const newHeaders = new Headers(response.headers);
newHeaders.set("Cache-Control", "public, max-age=10");
newHeaders.delete("set-cookie");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders,
});
}
};
```
# Dinaup PG Sync (/docs/desarrollo/integraciones/dinaup-pg-sync)
Dinaup PG Sync habilita un acceso PostgreSQL de solo lectura a tus datos. Sirve para alimentar herramientas externas o ejecutar análisis sobre tu información sin tocar el sistema en producción. La sincronización es unidireccional (Dinaup → PostgreSQL) y se configura desde el panel de administración.
Conecta Power BI a tus datos vía PG Sync.
Librería .NET para conectar a Postgre.
# Eventos Redis en tiempo real (/docs/desarrollo/integraciones/eventos-redis)
Dinaup puede publicar cada alta y edición de tus datos en un servidor Redis tuyo, en el momento en que ocurre. El evento llega con los valores nuevos y los anteriores del registro: tu aplicación reacciona sin preguntar, sin polling y sin esperar a un webhook HTTP.
Es el mismo aviso que un [webhook saliente](/docs/desarrollo/integraciones/webhook/salientes), por un canal más rápido y con más caudal: pensado para refrescar pantallas en tiempo real, invalidar cachés o sincronizar otro sistema con miles de cambios al día.
## Antes de empezar [#antes-de-empezar]
* Un servidor Redis tuyo, accesible desde Internet, donde Dinaup pueda publicar.
* Tu app en .NET con el paquete `StackExchange.Redis` (y el paquete `Dinaup` para descomprimir).
## Conectar tu Redis y suscribirte [#conectar-tu-redis-y-suscribirte]
### Configura la conexión en tu empresa administrada [#configura-la-conexión-en-tu-empresa-administrada]
En la ficha de tu empresa administrada principal, rellena el campo **Conexión Redis Eventos** con la cadena de tu servidor, en formato StackExchange.Redis:
```
tu-redis.tuempresa.com:6379,password=xxxx,abortConnect=false
```
`abortConnect=false` es obligatorio. Si falta, Dinaup no inicia la conexión: sin ese flag, el conector fallaría al primer intento si tu Redis tarda en responder.
El cambio se aplica en caliente: el servidor detecta la cadena nueva en unos segundos, descarta la conexión anterior y conecta contra la nueva. Vaciar el campo desconecta.
### Suscríbete al canal [#suscríbete-al-canal]
Los eventos llegan por el canal `dinaup.srvs.events.{serie}.moni`, donde `{serie}` es la serie de tu licencia. El mensaje viene comprimido con gzip; el paquete `Dinaup` trae el descompresor.
```csharp
using StackExchange.Redis;
using System.Text.Json;
var redis = await ConnectionMultiplexer.ConnectAsync(
"tu-redis.tuempresa.com:6379,password=xxxx,abortConnect=false");
var canal = new RedisChannel($"dinaup.srvs.events.{serie}.moni",
RedisChannel.PatternMode.Literal);
await redis.GetSubscriber().SubscribeAsync(canal, (channel, mensaje) =>
{
byte[] bytes = mensaje;
bytes = Dinaup.extensions.Gzip_Decompress(bytes);
var texto = System.Text.Encoding.UTF8.GetString(bytes);
var evento = JsonSerializer.Deserialize>>(texto);
if (evento == null || evento.Type != 1) return;
foreach (var cambio in evento.Payload)
{
// cambio.SectionId, cambio.NewValues, cambio.PreviousValues…
}
});
```
Si no conoces tu serie, suscríbete por patrón (`dinaup.srvs.events.*.moni` con `PatternMode.Pattern`): el nombre del canal que recibas la contiene.
### Deserializa el evento [#deserializa-el-evento]
El mensaje es un sobre con la lista de cambios dentro. Estas dos clases bastan para leerlo:
```csharp
public class RedisEvent
{
public int Type { get; set; } // 1 = monitorización de cambios
public string LicSerie { get; set; }
public TPayload Payload { get; set; }
public DateTime Timestamp { get; set; } // UTC
}
public class RedisMonitoringDTO
{
public Guid ID { get; set; } // registro afectado
public string SectionId { get; set; } // sección (Guid en texto)
[JsonPropertyName("Tabla")]
public string Table { get; set; }
public Guid UserId { get; set; } // quién hizo el cambio
[JsonPropertyName("EsUpdate")]
public bool IsUpdate { get; set; } // false = alta
[JsonPropertyName("Nuevos")]
public Dictionary NewValues { get; set; }
[JsonPropertyName("Anteriores")]
public Dictionary PreviousValues { get; set; }
}
```
Cada evento agrega los datos del registro: `Nuevos` trae los valores tras el cambio y `Anteriores` los que había. Comparándolos sabes qué campo cambió sin consultar nada.
## Qué se publica y qué no [#qué-se-publica-y-qué-no]
Se publica cada alta y edición de las secciones normales de tu licencia. Quedan fuera:
* Secciones base y plantillas de tipo lista.
* Secciones internas de alta actividad: registros de actividad, anotaciones internas, registros de eliminación, numeraciones y series, registros Verifactu y transacciones monetarias internas, entre otras. Inundarían el canal sin aportar señal.
Es un canal de avisos, no una cola con reintentos. Si tu Redis está caído, los eventos de ese intervalo no se reenvían. Para reconstruir estado usa [informes](/docs/desarrollo/dotnet/sdk/cliente) o [PGSync](/docs/desarrollo/integraciones/dinaup-pg-sync); los eventos sirven para reaccionar, no como fuente de verdad.
## Para qué usarlo [#para-qué-usarlo]
* **Pantallas en tiempo real.** Un kanban o un TPV que se refresca cuando otro usuario mueve una tarjeta o cobra un ticket. Así funcionan las pantallas de play.dinaup.com.
* **Cachés que se invalidan solas.** Borra la entrada cuando llega el evento de su sección, en vez de expirar a ciegas.
* **Sincronización con otro sistema.** Empuja el cambio a tu buscador, tu data warehouse o tu web al momento, con los valores nuevos y viejos incluidos.
Si prefieres avisos gestionados por Dinaup y sin infraestructura propia, usa [webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes). Si necesitas la base de datos completa replicada, [PGSync](/docs/desarrollo/integraciones/dinaup-pg-sync).
# Integraciones (/docs/desarrollo/integraciones)
Dinaup se conecta con tu ecosistema de herramientas a través de múltiples canales. Elige la integración que mejor se adapte a tu caso de uso.
***
## API REST [#api-rest]
Interactúa directamente con tus datos mediante peticiones HTTP. Lee informes, genera documentos y escribe registros desde cualquier lenguaje de programación.
**Base URL:** `https://webhook.dinaup.com`
| Endpoint | Método | Descripción |
| -------------------------- | ------ | --------------------------------------------------------------------------------- |
| `/api/whoami` | GET | Verifica la autenticación y obtiene datos del usuario |
| `/api/reports` | POST | Consulta informes configurados en Flex |
| `/api/dynamicdocuments` | POST | Genera documentos dinámicos (HTML, JSON, PDF) |
| `/api/writeoperations` | POST | Crea o edita registros (`id=""` = crear, UUID = editar, `eliminado=1` = eliminar) |
| `/api/tools/aeat/NIFCheck` | GET | Valida NIF/CIF contra la AEAT |
| `/api/tools/vies/VATCheck` | GET | Valida NIF intracomunitario (VIES) |
→ [Documentación completa de la API](/docs/desarrollo/integraciones/webhook)
***
## Webhooks salientes [#webhooks-salientes]
Dinaup envía un POST a tu servidor cuando se crea o modifica un registro, con el estado antes y después del cambio. Configúralos desde el módulo Desarrollo de Play Dinaup: eliges la sección, los campos disparadores y la URL de destino.
→ [Configurar webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes)
***
## Automatización sin código [#automatización-sin-código]
Conecta Dinaup con miles de aplicaciones sin escribir código usando plataformas de automatización:
| Plataforma | Estado | Descripción |
| --------------------- | ---------- | ------------------------------------------------------------------------------------ |
| **n8n** | Disponible | Flujos de automatización self-hosted o cloud. Conexión directa con la API de Dinaup. |
| **Make** (Integromat) | Disponible | Escenarios visuales de automatización con cientos de integraciones. |
| **Zapier** | Disponible | Conecta Dinaup con más de 5.000 aplicaciones. |
→ [Guía de integración con n8n](/docs/desarrollo/integraciones/zapier-make-y-n8n/dinaup-and-n8n)
***
## PostgreSQL Sync [#postgresql-sync]
Dinaup puede sincronizar tus datos en una base de datos PostgreSQL propia. Esto permite:
* **Consultas SQL directas** sobre tus datos para análisis avanzado
* **Conexión con Power BI**, Metabase, Grafana u otras herramientas de BI
* **Backups propios** con la frecuencia que necesites
* **Desarrollo de aplicaciones** que lean datos de Dinaup
La sincronización es unidireccional (Dinaup → PostgreSQL) y se configura desde el panel de administración.
→ [Configurar PG Sync](/docs/desarrollo/integraciones/dinaup-pg-sync)
***
## Power BI [#power-bi]
Conecta tus datos de Dinaup directamente con Power BI para crear dashboards e informes. La conexión se realiza a través de PostgreSQL Sync.
→ [Guía de Power BI](/docs/desarrollo/integraciones/power-bi)
***
## SDK .NET [#sdk-net]
Cliente oficial para desarrollo en .NET. Permite operaciones de lectura, escritura y consulta de informes con tipado fuerte. El SDK se conecta a `api.dinaup.com` (distinto de `webhook.dinaup.com`).
```csharp
// Ejemplo: leer informes
var data = await client.GetReportAsync(reportId, page: 1, resultsPerPage: 100);
// Ejemplo: escribir datos
await client.RunWriteOperationAsync(sectionId, writeOperation);
```
→ [Documentación del SDK .NET](/docs/desarrollo/dotnet/sdk)
**¿API REST o SDK .NET?** Si tu aplicación es .NET, usa el SDK: tiene tipado fuerte, gestión de sesiones y todas las secciones de [MyDinaup](/docs/desarrollo/dotnet/mydinaup) (la librería tipada de tu esquema) con nombres de campo legibles. La API REST (`webhook.dinaup.com`) es para integraciones desde cualquier lenguaje.
***
## Cloudflare Workers [#cloudflare-workers]
Ejecuta lógica personalizada en el edge usando Cloudflare Workers conectados a la API de Dinaup. Útil para:
* Transformación de datos en cada petición
* Proxies de autenticación
* Lógica de negocio distribuida
→ [Guía de Cloudflare Workers](/docs/desarrollo/integraciones/cloudflare-worker)
***
## Resumen de opciones [#resumen-de-opciones]
| Necesidad | Solución recomendada |
| ---------------------------------------- | ------------------------------- |
| Leer/escribir datos (cualquier lenguaje) | API REST (`webhook.dinaup.com`) |
| Desarrollo de aplicaciones .NET | SDK .NET (`api.dinaup.com`) |
| Reaccionar a eventos en tiempo real | Webhooks salientes |
| Automatizar sin código | n8n, Make o Zapier |
| Análisis avanzado con SQL | PostgreSQL Sync |
| Dashboards de BI | PostgreSQL Sync + Power BI |
| Lógica en el edge | Cloudflare Workers |
# Power BI (/docs/desarrollo/integraciones/power-bi)
Puedes conectar **Dinaup** con **Power BI** utilizando [Dinaup PG Sync](/docs/desarrollo/integraciones/dinaup-pg-sync).
# Stripe (/docs/desarrollo/integraciones/stripe)
Stripe es la pasarela de pagos donde cobras a tus clientes online. Esta integración trae esas facturas y cobros a Dinaup para que no tengas que copiarlos a mano: revisas lo que ha pasado en Stripe y lo conviertes en una factura de tu [facturación](/docs/rtg/pymes/facturacion).
Es una conexión de **solo lectura desde Stripe hacia Dinaup**: Dinaup consulta tu cuenta de Stripe y muestra lo que hay, pero no modifica nada en Stripe. Tú decides qué importar.
Necesitas una cuenta de Stripe propia. La integración usa tus credenciales de Stripe para leer tu actividad; esas credenciales se configuran una vez y no se muestran en pantalla.
***
## Qué trae de Stripe [#qué-trae-de-stripe]
Una vez conectada, la integración te muestra tu actividad de Stripe organizada por pestañas. Cada una lista los registros tal y como están en Stripe, con su importe, su fecha y su estado.
| Pestaña | Qué contiene |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Facturas** | Las facturas emitidas en Stripe, con su número, cliente, vencimiento, total y estado de pago. Es la pestaña principal para importar a tu facturación. |
| **Pagos** | Los cobros individuales recibidos a través de Stripe. |
| **Suscripciones** | Las suscripciones recurrentes de tus clientes (mensuales, anuales) y su estado. |
| **Productos** | El catálogo de productos y precios que tienes dado de alta en Stripe. |
| **Liquidaciones** | Las transferencias que Stripe hace a tu banco, y las transacciones que componen cada una. |
| **Clientes** | Los clientes registrados en Stripe, con su nombre y correo. |
Cada **liquidación** es una sola transferencia de Stripe a tu banco que agrupa muchos cobros. Para que tu conciliación bancaria reconozca ese ingreso en bloque como la suma de varias operaciones, define un [tipo de movimiento bancario](/docs/rtg/pymes/tesoreria/tipos-de-movimiento) con la casilla **Liquidación de varias operaciones**. Si quieres que se asigne solo por el concepto del banco, añade además una [regla de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios).
***
## Estado de pago de las facturas [#estado-de-pago-de-las-facturas]
Cada factura llega con el estado que tiene en Stripe, para que sepas qué está cobrado y qué no. Dinaup lo traduce y lo muestra con un color según el caso:
| Estado | Qué significa |
| -------------- | ------------------------------------------------------ |
| **Borrador** | La factura existe en Stripe pero aún no se ha emitido. |
| **Abierta** | Emitida y pendiente de cobro. |
| **Pagada** | El cliente ya ha pagado. |
| **Incobrable** | Marcada en Stripe como que no se va a cobrar. |
| **Anulada** | La factura se ha anulado. |
Lo mismo aplica a las suscripciones (activa, en prueba, vencida, cancelada, impagada), para que distingas las que están al corriente de las que tienen un pago pendiente.
***
## Importar una factura a Dinaup [#importar-una-factura-a-dinaup]
El flujo está pensado para que no dupliques trabajo: ves lo que hay en Stripe, marcas lo que falta por traer y lo importas.
### Abre la pestaña Facturas [#abre-la-pestaña-facturas]
Verás el listado de facturas de tu cuenta de Stripe. Por defecto se muestran solo las **pendientes de importar**: las que todavía no existen en tu facturación de Dinaup. Quita ese filtro si quieres ver también las que ya importaste.
### Filtra lo que buscas [#filtra-lo-que-buscas]
Puedes acotar por estado (solo las pagadas, solo las abiertas...) para centrarte en lo que te interesa. Usa **Recargar** para volver a consultar Stripe y traer lo más reciente.
### Identifica las nuevas [#identifica-las-nuevas]
Las facturas que aún no están en Dinaup aparecen marcadas como **Nueva**. Junto a cada una tienes accesos directos para descargar su PDF o abrirla en Stripe, por si quieres revisarla antes de importarla.
### Agrégala al ERP [#agrégala-al-erp]
Pulsa el botón de **agregar** en la factura que quieras traer. Dinaup la da de alta en tu facturación con sus datos: número, cliente, importe y fecha. A partir de ahí deja de aparecer como "Nueva".
Dinaup reconoce por el **número de factura** las que ya tienes importadas, así que no se duplican aunque recargues o vuelvas a entrar. Si una factura ya existe en tu facturación, la integración lo detecta y no te ofrece volver a agregarla.
***
## Emparejar clientes de Stripe con los de Dinaup [#emparejar-clientes-de-stripe-con-los-de-dinaup]
Una factura de Stripe trae el nombre y el correo del cliente, pero ese cliente puede que ya exista en tu Dinaup con su ficha completa. Para que la factura importada se asocie a la ficha correcta, puedes **vincular un cliente de Stripe con un cliente de Dinaup**.
Así evitas fichas duplicadas y mantienes el historial de cada cliente en un solo sitio: lo que cobras por Stripe queda unido al resto de su actividad comercial. Las facturas importadas conviven con el resto en [facturación](/docs/rtg/pymes/facturacion) y su estado de cobro alimenta tu [pendiente de cobro](/docs/rtg/pymes/por-cobrar).
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Es de solo lectura: Dinaup consulta tu actividad de Stripe y la muestra, pero no crea ni cambia nada allí. Las altas se hacen en Dinaup cuando tú importas una factura.
No de forma silenciosa. Tú decides qué traer: revisas el listado, ves cuáles están pendientes de importar y agregas las que quieras. Así mantienes el control de lo que entra en tu facturación.
No se duplica. Dinaup la reconoce por su número de factura, la marca como ya existente y no te ofrece volver a agregarla.
Sí. Cada factura tiene accesos directos para descargar su PDF o abrirla en Stripe, de modo que la revises antes de traerla a Dinaup.
***
→ [Integraciones](/docs/desarrollo/integraciones)
→ [Facturación](/docs/rtg/pymes/facturacion)
→ [Pendiente de cobro](/docs/rtg/pymes/por-cobrar)
# CDN Público (/docs/desarrollo/recursos/cdn-publico)
El CDN público de Dinaup sirve imágenes a través de `storage.dinaup.com`. Son accesibles sin autenticación: útiles para catálogos de productos, webs, marketplaces o cualquier contenido visible desde fuera.
Los archivos en el CDN público son **accesibles por cualquier persona** que tenga el enlace. No subas documentos confidenciales a la galería pública.
## Origen de las imágenes [#origen-de-las-imágenes]
Las imágenes del CDN público provienen de tres fuentes principales:
| Origen | Descripción |
| --------------------- | ---------------------------------------------------------------------------------------- |
| **Galería Pública** | Imágenes subidas a la `PublicGallery` de cualquier registro (productos, servicios, etc.) |
| **Iconos de Sección** | Iconos configurados para las secciones del sistema |
| **Iconos de Campo** | Iconos asociados a campos específicos |
## Estructura de las URLs [#estructura-de-las-urls]
```
https://storage.dinaup.com/cdn/{GUID}_{tamaño}.{extensión}
```
Donde:
* `{GUID}`: Identificador único del archivo
* `{tamaño}`: Sufijo opcional que indica el tamaño de la imagen
* `{extensión}`: Formato del archivo (jpg, png, webp, etc.)
## Tamaños disponibles [#tamaños-disponibles]
Dinaup genera varias versiones de cada imagen para optimizar la carga según el contexto de uso:
| Sufijo | Tamaño | Uso recomendado |
| -------------- | ------------ | ----------------------------------------- |
| *(sin sufijo)* | **Original** | Máxima calidad, descarga, impresión |
| `_04` | 32px alto | Iconos, avatares en listas, tablas |
| `_02` | 100px alto | Miniaturas, previews, catálogos compactos |
| `_03` | 300px alto | Tarjetas de producto, galerías |
| `_06` | 720px alto | Visualización en detalle, webs responsive |
| `_05` | 1080px alto | Pantalla completa, alta calidad |
## Ejemplos de uso [#ejemplos-de-uso]
Dada una imagen con GUID `6c535438-f09f-45d1-be28-dd538ed47b59`:
```
# Original (máxima calidad)
https://storage.dinaup.com/cdn/6c535438-f09f-45d1-be28-dd538ed47b59.jpg
# Icono pequeño (32px)
https://storage.dinaup.com/cdn/6c535438-f09f-45d1-be28-dd538ed47b59_04.jpg
# Miniatura (100px)
https://storage.dinaup.com/cdn/6c535438-f09f-45d1-be28-dd538ed47b59_02.jpg
# Tarjeta (300px)
https://storage.dinaup.com/cdn/6c535438-f09f-45d1-be28-dd538ed47b59_03.jpg
# HD (720px)
https://storage.dinaup.com/cdn/6c535438-f09f-45d1-be28-dd538ed47b59_06.jpg
# Full HD (1080px)
https://storage.dinaup.com/cdn/6c535438-f09f-45d1-be28-dd538ed47b59_05.jpg
```
## Casos de uso típicos [#casos-de-uso-típicos]
### Catálogo de productos en web [#catálogo-de-productos-en-web]
```html
```
### Imágenes responsive [#imágenes-responsive]
```html
```
### Iconos en interfaces [#iconos-en-interfaces]
```html
```
## Buenas prácticas [#buenas-prácticas]
**Optimiza la carga**: Usa siempre el tamaño más pequeño que cumpla con tus necesidades. Reserva el original solo para descarga o impresión.
* **Listados con muchos elementos**: Usa `_04` (32px) o `_02` (100px)
* **Tarjetas y galerías**: Usa `_03` (300px)
* **Visualización en detalle**: Usa `_06` (720px)
* **Pantalla completa o alta calidad**: Usa `_05` (1080px) o el original
* **Descarga o impresión**: Usa el original (sin sufijo)
## Subir imágenes a la Galería Pública [#subir-imágenes-a-la-galería-pública]
Las imágenes se suben mediante el sistema de anotaciones de Dinaup usando el tipo `PublicGallery`:
```csharp
// Subir archivo
var upload = await dinaupClient.File_UploadBytesAsync(
dinaupClient.DefaultSession,
imageBytes,
"producto.jpg"
);
// Añadir a la galería pública de un registro
await dinaupClient.Annotation_PutAsync(
dinaupClient.DefaultSession,
sectionId,
rowId.ToString(),
upload.FileId,
"Foto principal del producto",
AnnotationTypeE.PublicGallery
);
```
Una vez subida la imagen, Dinaup genera todas las versiones de tamaño. Puedes acceder a cualquiera de ellas añadiendo el sufijo correspondiente a la URL.
## FAQ [#faq]
Sí, el CDN de Dinaup utiliza caché global para servir las imágenes con la menor latencia posible.
Sí, pero la galería pública está optimizada para imágenes. Para otros tipos de archivos, usa el sistema de archivos privados con URLs firmadas.
Se sirve la imagen en su tamaño original sin ampliar, para evitar pérdida de calidad.
El límite depende de tu plan de almacenamiento.
# Recursos (/docs/desarrollo/recursos)
Infraestructura que Dinaup pone a disposición de quien desarrolla: ejecución, archivos públicos y datos.
Aplicación de escritorio que ejecuta y publica tus módulos.
Sirve imágenes y archivos públicos con URLs estables.
Acceso a la base de datos y al modelo de información.
# Casos de uso (/docs/desarrollo/casos-de-uso)
Patrones de construcción que partners y desarrolladores implementan sobre Dinaup. Tú pones la lógica de negocio y la interfaz; Dinaup pone el backend: base de datos, autenticación, permisos, API, informes, backups e infraestructura en la nube. Ninguno de estos casos es un producto de Dinaup.
Las dos piezas que habilitan todo esto son **[Dinaup Flex](/docs/desarrollo/flex)** (modela datos, informes, documentos y automatizaciones sin programar) y el **[SDK .NET y la API REST](/docs/desarrollo/dotnet/sdk)** (conecta tu propio frontend o sistema externo). Cada caso de abajo combina ambas en distinta proporción.
***
## Qué construyes tú, qué pone Dinaup [#qué-construyes-tú-qué-pone-dinaup]
El reparto de responsabilidades es común a todos los casos:
| Lo construyes tú | Lo pone Dinaup |
| ------------------------------------------------------ | ---------------------------------------------------------------------------- |
| La **interfaz de usuario** y la experiencia | Base de datos dinámica (vía [Flex](/docs/desarrollo/flex)), sin escribir SQL |
| La **lógica de negocio** propia del caso | Autenticación, sesiones, recuperación de contraseña |
| El **modelo de datos** específico (secciones y campos) | Control de acceso, roles y permisos |
| Las **integraciones** con sistemas de terceros | API REST automática sobre todas las secciones |
| | Informes, paneles y documentos |
| | Backups replicados y la infraestructura en la nube |
Cualquier solución que construyas queda integrada en el entorno administrativo del cliente, accesible desde [play.dinaup.com](https://play.dinaup.com): un único sitio para gestionar usuarios, suscripción y datos.
→ Desarrollado en detalle con un ejemplo real en [UI/UX personalizada](/docs/desarrollo/casos-de-uso/ui-ux-personalizada).
***
## Los cuatro patrones [#los-cuatro-patrones]
Los cuatro casos más habituales. Cada tarjeta enlaza a la herramienta principal para construirlo.
Adapta el sistema a un sector concreto combinando secciones Flex propias con los módulos Ready To Go.
Un portal con tu marca donde tus clientes consultan sus datos, conectado por el SDK o la API.
Un e-commerce cuyo stock, pedidos y facturación viven directamente en Dinaup.
Una aplicación web o móvil para el equipo, apoyada en la API y en el sistema de usuarios de Dinaup.
***
## ERP a medida [#erp-a-medida]
Cuando un negocio tiene procesos que ningún ERP estándar cubre, lo habitual no es empezar de cero, sino **extender Dinaup**. Modelas lo que es específico de tu sector como secciones y campos en [Flex](/docs/desarrollo/flex), y lo apoyas en los módulos Ready To Go que ya resuelven lo común: facturación, contabilidad, tesorería, inventario.
* **Lo propio del negocio** se construye con secciones Flex, informes y algoritmos a medida.
* **Lo común a toda empresa** lo aportan los módulos Ready To Go, ya construidos sobre Flex.
* La gestión administrativa (formularios, listados, permisos) aparece sola en play.dinaup.com con cada cambio de estructura.
El resultado es un ERP que encaja con el sector sin renunciar a la base fiscal y contable ya resuelta.
→ Empieza por [Dinaup Flex](/docs/desarrollo/flex) para modelar tus secciones.
***
## Área de clientes [#área-de-clientes]
Un **frontend propio**, con la marca y el diseño que quieras, donde tus clientes entran a consultar sus presupuestos, pedidos, facturas o cualquier dato que decidas exponer. Tú construyes la pantalla; los datos vienen de Dinaup.
* Conectas tu aplicación al **[SDK .NET](/docs/desarrollo/dotnet/sdk)** (si trabajas en .NET) o a la **API REST** (desde cualquier lenguaje).
* Lees datos con informes y escribes con operaciones de escritura, sin tocar la base de datos directamente.
* La autenticación, los permisos y la seguridad los gestiona la plataforma, no tu código.
→ Cómo conectar tu frontend en el [SDK .NET y la API](/docs/desarrollo/dotnet/sdk).
***
## Tienda online integrada [#tienda-online-integrada]
Una **tienda online** cuyo catálogo, stock, pedidos y facturación no viven en un sistema aparte, sino **directamente en Dinaup**. Eliminas la sincronización entre la web y el ERP, que es la fuente habitual de descuadres.
* El catálogo y el inventario son secciones de Dinaup; la web los lee a través del SDK o la API.
* Cada pedido genera el documento de venta y su facturación dentro de la propia plataforma.
* El stock se descuenta sobre el mismo inventario que usa el resto de la empresa, sin duplicar datos.
Una sola fuente de verdad para la tienda y para la gestión interna.
→ Integra el escaparate con el [SDK .NET y la API](/docs/desarrollo/dotnet/sdk).
***
## App para empleados [#app-para-empleados]
Una aplicación **web o móvil** para el equipo (partes de trabajo, registros en campo, consultas rápidas) apoyada en la API de Dinaup y en su gestión de usuarios. Tus empleados usan las mismas credenciales que ya tienen en la plataforma.
* La app habla con Dinaup a través de la **API REST** o el **[SDK .NET](/docs/desarrollo/dotnet/sdk)**.
* Reutilizas el sistema de usuarios, roles y permisos de la plataforma: una sola alta de empleado sirve para todo.
* Los datos que captura el equipo entran directos en las secciones del sistema, listos para informes y facturación.
→ Conecta la app por el [SDK .NET y la API](/docs/desarrollo/dotnet/sdk).
***
## Por dónde empezar [#por-dónde-empezar]
El camino es el mismo en los cuatro casos: decide qué interfaz y lógica construyes tú ([UI/UX personalizada](/docs/desarrollo/casos-de-uso/ui-ux-personalizada)), modela los datos con [Dinaup Flex](/docs/desarrollo/flex) y conecta tu frontend o sistema externo con el [SDK .NET y la API](/docs/desarrollo/dotnet/sdk).
Para el detalle de la conexión, ver la guía [SDK y API](/docs/guias/sdk-api).
# UI/UX personalizada (/docs/desarrollo/casos-de-uso/ui-ux-personalizada)
Tú programas la pantalla que ve el usuario y las reglas de tu negocio. El resto (base de datos, autenticación, permisos, API, informes, backups e infraestructura en la nube) ya está resuelto. Un caso práctico lo ilustra.
## Ejemplo: app de puntuación para minigolf [#ejemplo-app-de-puntuación-para-minigolf]
Una empresa de minigolf que ya usa Dinaup para facturación y contabilidad quiere una aplicación donde los usuarios registren sus puntuaciones.
### Lo que construyes tú [#lo-que-construyes-tú]
* **La interfaz de usuario** donde los jugadores introducen sus puntos.
* La lógica de negocio propia del caso.
### Lo que pone Dinaup [#lo-que-pone-dinaup]
* **Base de datos**: la estructura dinámica *Dinaup Flex* permite crear y modificar entidades sin escribir SQL.
* **Seguridad**: control de acceso, autenticación y protección de datos de forma nativa.
* **Autenticación**: inicio de sesión integrado, con recuperación de contraseña, gestión de sesiones y permisos.
* **Interfaces administrativas**: los formularios dinámicos de gestión están en **play.dinaup.com** y se actualizan con cada cambio estructural.
* **Informes y paneles**: sistema propio de visualización de datos e informes, adaptado a cada módulo.
* **API**: se expone automáticamente una API dinámica para todas las entidades del sistema, con autenticación y permisos configurables.
* **Backups**: copias de seguridad automáticas replicadas en múltiples ubicaciones geográficas.
* **Usuarios, roles y permisos**: gestión completa y centralizada, editable desde el panel principal.
* **Infraestructura**: operación en la nube con alta disponibilidad y escalabilidad, sin mantenimiento por parte del desarrollador.
La aplicación queda integrada en el entorno administrativo del cliente, accesible desde [play.dinaup.com](https://play.dinaup.com).
## Qué implica este reparto [#qué-implica-este-reparto]
Para el cliente:
* Menos coste y tiempo de desarrollo al evitar las tareas técnicas de backend.
* Infraestructura mantenida y actualizada, sin mantenimiento adicional.
* Panel administrativo operativo desde el primer día.
* API integrada, preparada para futuras integraciones con otros servicios.
* Escalabilidad sin rediseños posteriores.
* Datos unificados en un único sistema, sin duplicidades.
* Gestión de empleados centralizada: un único inicio de sesión y administración de altas y bajas desde un solo lugar.
Para el desarrollador:
* Sin trabajo repetitivo de backend.
* Menos responsabilidades técnicas (seguridad, infraestructura).
* Plazos de entrega más cortos.
* Foco en la experiencia de usuario y la calidad de la interfaz.
***
Para construir la UI/UX existe un proyecto interno reutilizable de componentes Blazor.
# Soporte (/docs/guias/soporte)
¿No encuentras lo que buscas en las guías? Tienes varias vías:
* **Chat de ayuda**: el icono de la esquina superior derecha de [play.dinaup.com](https://play.dinaup.com).
* **Email**: [soporte@dinaup.com](mailto:soporte@dinaup.com).
* **Buscador**: la barra de búsqueda de arriba te lleva directo a la página que cubre tu duda.
## Preguntas frecuentes [#preguntas-frecuentes]
Las dudas más habituales, organizadas por área:
Producto: facturación, TPV, inventario y stock, RRHH, CRM, contabilidad e IA.
Registro, usuarios, permisos, suscripción y seguridad.
Integraciones, API, webhooks, Make/Zapier y Power BI.
# Cumpleaños de clientes (/docs/rtg/crm/cumpleanos)
**Cumpleaños** lista las fechas de nacimiento de tus clientes. La abres desde **Cumpleaños** en el grupo CRM del menú lateral.
***
## Qué ves [#qué-ves]
Una lista con los clientes que tienen fecha de nacimiento registrada en su ficha, con su nombre y su cumpleaños. Los clientes sin fecha de nacimiento no aparecen.
Te sirve para adelantarte a una fecha señalada y usarla como excusa de contacto o de fidelización.
Un cliente solo sale en esta lista si su ficha tiene la **fecha de nacimiento** rellena. Complétala en la ficha del cliente para que aparezca.
***
→ [Volver al CRM](/docs/rtg/crm)
# IA en el CRM (/docs/rtg/crm/ia-en-crm)
La IA del CRM hace dos cosas: crea eventos a partir de una frase en lenguaje natural y, sobre una oportunidad, propone cómo avanzarla con un carrusel de sugerencias. Propone y confirmas tú; no envía mensajes ni mueve oportunidades por su cuenta.
***
## Crear eventos desde lenguaje natural [#crear-eventos-desde-lenguaje-natural]
Escribes en una frase lo que vas a hacer, y la IA lo convierte en un evento estructurado, listo para que lo revises y guardes.
Por ejemplo, escribes:
> *"Reunión con Paco mañana a las 16:30 en la oficina para firmar el contrato"*
Y la IA monta el evento por ti, repartiendo cada parte de la frase en su campo:
| Campo del evento | Lo que entiende la IA |
| ------------------ | ----------------------------------------- |
| **Tipo de evento** | Reunión |
| **Fecha y hora** | Mañana, 16:30 |
| **Duración** | Una estimación según el tipo de evento |
| **Ubicación** | La oficina |
| **Notas** | Firmar el contrato |
| **Oportunidad** | La oportunidad en la que estás trabajando |
### Abre el campo de evento rápido [#abre-el-campo-de-evento-rápido]
Desde una oportunidad (o desde la casilla de texto rápida del CRM), escribe directamente lo que vas a hacer, con tus palabras. No hay un formato obligatorio: cuanta más información des (quién, cuándo, dónde, para qué), más campos rellenará la IA.
### Deja que la IA monte el evento [#deja-que-la-ia-monte-el-evento]
La IA interpreta la frase y propone el evento ya estructurado: tipo, fecha, hora, ubicación, notas y la entidad u oportunidad asociada. Lo ves todo relleno antes de aceptar nada.
### Revisa, ajusta y guarda [#revisa-ajusta-y-guarda]
Comprueba que cada campo es correcto. Si la IA interpretó mal la hora, el tipo o la ubicación, lo corriges en un momento. Cuando todo cuadre, guardas el evento.
Cada evento que creas alimenta la línea de tiempo de la oportunidad y la actividad de tu equipo, igual que cualquier otro [seguimiento](/docs/rtg/crm/seguimientos).
***
## Carrusel de sugerencias sobre una oportunidad [#carrusel-de-sugerencias-sobre-una-oportunidad]
Cuando entras en una oportunidad, la IA puede analizarla y devolverte un **carrusel de tarjetas**: un repaso de cómo va el trato y qué hacer a continuación.
Para componer el carrusel, la IA lee el contexto completo de la oportunidad: su fase actual, el histórico de eventos, las notas, cuánto tiempo lleva parada y cómo ha respondido el cliente.
### Qué te muestra el carrusel [#qué-te-muestra-el-carrusel]
| Tarjeta | Qué te da |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Puntos fuertes** | Qué juega a tu favor en esta operación (por ejemplo, que tu contacto sea quien decide, o que ya haya visto una demo). |
| **Puntos débiles** | Los riesgos o frenos que detecta (por ejemplo, días sin respuesta del cliente, o que aún no hayáis hablado de precio). |
| **Próxima acción** | El siguiente paso recomendado para hacer avanzar el trato. |
| **Mensaje listo para enviar** | Un texto redactado para el cliente, contextual a esta oportunidad, que puedes copiar, adaptar y enviar por donde quieras. |
El **mensaje** es siempre un borrador. La IA no lo envía: tú lo revisas, decides si lo mandas tal cual, lo editas o lo descartas, y eliges el canal (email, mensajería, donde toque).
***
## Análisis de oportunidad [#análisis-de-oportunidad]
El carrusel es, en el fondo, un análisis de la oportunidad puesto en formato accionable. La IA no se inventa el estado del trato: lo deduce de lo que tú y tu equipo habéis ido registrando. De ahí una consecuencia práctica:
**Cuanto mejor rellenes la oportunidad, mejores serán las sugerencias.** Escribe las notas como si fueran para un compañero que cubre tus vacaciones: registra eventos, anota cómo reacciona el cliente, deja claro qué falta. Ese contexto es lo que la IA lee para afinar el análisis.
***
## Qué hace y qué no hace la IA [#qué-hace-y-qué-no-hace-la-ia]
* **No programa eventos sin tu confirmación.** Te propone el evento montado; tú lo revisas y lo guardas.
* **No envía mensajes por ti.** Redacta un borrador; tú decides si lo mandas, lo cambias o lo tiras.
* **No mueve oportunidades de fase.** Te recomienda el siguiente paso; arrastras tú la tarjeta en el Kanban.
* **Hereda tus permisos.** La IA solo ve lo que tu usuario puede ver. Si no tienes acceso a una oportunidad, la IA tampoco la consulta.
La IA es además una capa **opcional**: si tu empresa no la quiere, el administrador la desactiva y estas funciones desaparecen sin afectar al resto del CRM.
→ [IA en Dinaup](/docs/rtg/ia)
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Redacta el mensaje y te lo deja listo. Tú decides si lo envías, dónde lo pegas (email, mensajería, etc.) y si lo ajustas antes.
No. La IA monta el evento como propuesta, con todos los campos rellenos, y te lo muestra para que lo revises. Solo se guarda cuando lo confirmas tú.
De lo que hay registrado en la propia oportunidad: fase actual, histórico de eventos, notas, tiempo en la fase y respuestas del cliente. No usa información externa: cuanto más completa esté la ficha, mejor es el análisis.
No. La IA hereda exactamente tus permisos. Si tu usuario no puede ver una oportunidad o un cliente, la IA tampoco los consulta.
Sí. La IA es una capa opcional. El administrador puede desactivarla para toda la empresa y el CRM sigue funcionando con normalidad.
***
→ [Seguimientos](/docs/rtg/crm/seguimientos)
→ [IA en Dinaup](/docs/rtg/ia)
→ [Casos de IA por módulo](/docs/rtg/ia/casos-por-modulo)
# CRM (/docs/rtg/crm)
En el CRM tu equipo comercial trabaja las oportunidades, registra cada interacción con los clientes y mide su actividad. Está conectado con el resto de módulos (Pymes, TPV, Proyectos).
***
## Funcionalidades principales [#funcionalidades-principales]
### Oportunidades [#oportunidades]
Las oportunidades representan potenciales operaciones comerciales. Cada oportunidad contiene:
* **Cliente** asociado (con acceso a sus datos fiscales, historial de compras y contactos)
* **Proceso y fase** en la que se encuentra (ej: Primer contacto → Propuesta → Negociación → Cierre)
* **Valor estimado** de la operación
* **Responsable** del seguimiento
* **Línea de tiempo** con todo el historial de interacciones
### Vista Kanban [#vista-kanban]
Visualiza todas las oportunidades organizadas por fases en un tablero Kanban. Arrastra y suelta para mover oportunidades entre fases. Filtra por responsable, proceso o estado.
### Seguimientos y eventos [#seguimientos-y-eventos]
Registra cada interacción con el cliente: llamadas, emails, reuniones, notas. Cada evento queda asociado a la oportunidad y al cliente, creando un historial completo accesible por todo el equipo.
* Añade eventos directamente desde la casilla de texto rápida
* Programa seguimientos futuros con recordatorios
* Visualiza el timeline completo de cada oportunidad
### Dashboard [#dashboard]
Panel con métricas clave del equipo comercial:
* Oportunidades por fase y su valor acumulado
* Tasa de conversión entre fases
* Actividad del equipo (seguimientos realizados, oportunidades gestionadas)
* Evolución temporal del pipeline
### Productividad [#productividad]
Análisis detallado del rendimiento del equipo:
* Seguimientos realizados por persona y período
* Tiempo medio entre interacciones
* Oportunidades ganadas/perdidas por responsable
### Resumen de cliente [#resumen-de-cliente]
Vista 360° de cada cliente desde el CRM:
* Datos fiscales y de contacto
* Historial de oportunidades (ganadas, perdidas, en curso)
* Historial de compras (integrado con Pymes)
* Venta rápida directa desde la ficha del cliente
### Cumpleaños [#cumpleaños]
Vista de cumpleaños de contactos para gestión de relaciones y oportunidades de fidelización.
***
## Conceptos clave [#conceptos-clave]
### Procesos [#procesos]
Un proceso define el tipo de ciclo comercial (ej: "Venta consultiva", "Renovación", "Captación"). Cada proceso tiene sus propias fases.
### Fases [#fases]
Las fases son los pasos dentro de un proceso (ej: "Cualificación → Demo → Propuesta → Negociación → Cierre"). Se visualizan como columnas en el Kanban.
→ Ver [Procesos y Fases](/docs/rtg/crm/procesos-y-fases)
### Eventos [#eventos]
Un evento es cualquier interacción con un cliente: llamada, email, reunión, nota interna. Los eventos alimentan la línea de tiempo y se usan para medir la actividad del equipo.
→ Ver [Seguimientos](/docs/rtg/crm/seguimientos)
***
## Configuración [#configuración]
Desde **CRM > Configuración** puedes personalizar:
* **Procesos y fases**: define los ciclos comerciales de tu empresa
* **Tipos de eventos**: categoriza las interacciones (llamada, email, visita, etc.)
* **Campos personalizados**: añade información específica a oportunidades y eventos a través de [Dinaup Flex](/docs/desarrollo/flex)
***
## Integración con otros módulos [#integración-con-otros-módulos]
| Módulo | Integración |
| ------------- | ----------------------------------------------------------------------------------------------------- |
| **Pymes** | El historial de ventas del cliente aparece en su ficha CRM. Puedes crear ventas rápidas desde el CRM. |
| **TPV** | Las ventas TPV asociadas a un cliente se reflejan en su historial. |
| **Proyectos** | Vincula oportunidades con proyectos para seguimiento post-venta. |
| **RRHH** | Las actividades del equipo comercial alimentan la productividad. |
# La ficha de oportunidad (/docs/rtg/crm/oportunidades)
Una **oportunidad** es un trato concreto con un cliente: su importe, su fase, quién la lleva y todo su historial. Esta es la ficha donde la das de alta y la editas, con todos sus campos y sus pestañas.
La abres desde el [tablero](/docs/rtg/crm/tablero-kanban), desde una lista de oportunidades o desde el [panel](/docs/rtg/crm/panel).
***
## Cabecera [#cabecera]
* **Título de la oportunidad**: el nombre del trato. Es obligatorio para guardar.
* **Cliente**: la entidad con la que negocias. El botón de añadir da de alta un cliente nuevo sin salir de la ficha.
* **Contacto**: la persona con la que tratas dentro del cliente.
* **Comercial**: quién lleva la oportunidad. El selector solo lista empleados marcados como comerciales.
***
## Proceso [#proceso]
Una línea de tiempo muestra las fases del proceso y marca en cuál está la oportunidad. Cambia la fase desde aquí. La fase es obligatoria para guardar.
***
## Valoración y estado [#valoración-y-estado]
| Campo | Qué es |
| ---------------------------- | ----------------------------------------------------------------------- |
| **Estado** | El estado de la oportunidad (pendiente, ganada, perdida…). Obligatorio. |
| **Importe estimado (€)** | El valor de la operación. |
| **Fecha estimada de cierre** | Cuándo esperas cerrar el trato. |
| **Probabilidad de cierre** | Un valor de 0 a 10 que ajustas con un deslizador. |
| **Interés del cliente** | Un valor de 0 a 10 que ajustas con un deslizador. |
Cuando hay importe y probabilidad, la ficha calcula el **valor ponderado** (importe por probabilidad) y lo muestra en una tarjeta.
### Registrar una pérdida [#registrar-una-pérdida]
El botón **Registrar pérdida** despliega dos campos:
* **Motivo de pérdida**: de la lista que configura tu empresa (precio, competencia, *timing*…).
* **Fecha de pérdida**.
→ [Motivos de pérdida](/docs/rtg/crm/procesos-y-fases)
***
## Notas y necesidades [#notas-y-necesidades]
* **Notas**: un editor de texto con formato para lo que quieras dejar por escrito sobre el trato.
* **Necesidades del cliente**: sus problemas o puntos de dolor.
***
## Más detalles [#más-detalles]
Un bloque plegable con campos adicionales:
* **Prioridad** y **Urgencia del cliente**.
* **Tipo** de oportunidad.
* **Nota rápida**.
* **Campaña de Captación** y **Método de Captación**: de dónde salió el trato.
***
## Pestañas de la oportunidad [#pestañas-de-la-oportunidad]
En una oportunidad ya guardada aparecen cinco pestañas:
| Pestaña | Qué muestra |
| -------------- | ------------------------------------------------------------------------------------------------ |
| **Eventos** | La casilla de evento rápido y la lista de eventos del trato. Registras interacciones desde aquí. |
| **Documentos** | Los archivos adjuntos a la oportunidad. |
| **Análisis** | El carrusel de sugerencias de la IA sobre cómo avanzar el trato. |
| **H. Estados** | El historial de cambios de estado. |
| **H. Fases** | El historial de cambios de fase, con sus fechas. |
La casilla de evento rápido de la pestaña **Eventos** entiende lenguaje natural: escribes lo que ha pasado y la IA monta el evento. El carrusel de la pestaña **Análisis** lee todo el historial del trato para proponerte el siguiente paso.
→ [Seguimientos y eventos](/docs/rtg/crm/seguimientos)
→ [La IA en el CRM](/docs/rtg/crm/ia-en-crm)
***
## Ventanas relacionadas [#ventanas-relacionadas]
* **Ver ficha completa**: el botón del pie abre la ficha completa de la oportunidad (con todos sus datos y relaciones), más allá de esta ventana de edición.
***
→ [Tablero Kanban](/docs/rtg/crm/tablero-kanban)
→ [Procesos y fases](/docs/rtg/crm/procesos-y-fases)
→ [Volver al CRM](/docs/rtg/crm)
# Panel del CRM (/docs/rtg/crm/panel)
El **Panel** es la pantalla de **Inicio** del CRM, la primera que ves al entrar. Reúne en una sola vista lo que tienes hoy entre manos, el estado del pipeline y las oportunidades que necesitan que hagas algo con ellas.
***
## Mi día [#mi-día]
La primera tarjeta lista tus **eventos de hoy** ordenados por hora, cada uno con su inicio y su duración. Si no tienes nada, muestra "Agenda libre por hoy".
En la cabecera de la tarjeta tienes dos botones:
* **Oportunidad**: abre el alta de una oportunidad nueva.
* **Evento**: abre el alta de un evento nuevo.
Haz clic en cualquier evento de la lista para abrir su ficha.
***
## KPIs del pipeline [#kpis-del-pipeline]
Una fila de tarjetas resume el estado de tus oportunidades abiertas:
| KPI | Qué mide |
| ------------------- | ------------------------------------------------------------------------------------------------------ |
| **Pipeline Total** | Suma del valor estimado de todas las oportunidades abiertas. |
| **Ponderado** | Suma de cada valor estimado multiplicado por su probabilidad de cierre. Los ingresos esperados reales. |
| **Abiertas** | Total de oportunidades abiertas en todos los procesos. |
| **Cierre Este Mes** | Oportunidades con fecha de cierre estimada dentro del mes actual. |
| **Estancadas** | Oportunidades sin cambio de estado o fase en más de 15 días. |
| **Sin evento** | Oportunidades abiertas sin ningún evento futuro programado. |
***
## Requiere atención [#requiere-atención]
Dos listas señalan los tratos que no puedes dejar aparcados:
* **Cierre Este Mes**: oportunidades con fecha de cierre estimada este mes, con su importe y su probabilidad. Haz clic en una para abrirla.
* **Oportunidades Estancadas**: las que llevan más de 15 días sin moverse, con los días transcurridos desde el último cambio.
***
## Equipo y herramientas [#equipo-y-herramientas]
* **Leaderboard, Pipeline por Comercial**: ranking del equipo por valor ponderado. Cada comercial aparece con su número de oportunidades, su valor total y su valor ponderado. Solo cuenta oportunidades abiertas.
* **Buscar cliente**: un buscador rápido para abrir la ficha de un cliente sin salir del panel. El botón **+** da de alta un cliente nuevo.
***
## Modo guía [#modo-guía]
El botón **Modo guía**, arriba a la derecha, abre una ventana con una introducción guiada al CRM. Úsala la primera vez para situarte antes de empezar a trabajar tus oportunidades.
***
→ [Tablero Kanban](/docs/rtg/crm/tablero-kanban)
→ [Oportunidades](/docs/rtg/crm/oportunidades)
→ [Volver al CRM](/docs/rtg/crm)
# Procesos y Fases (/docs/rtg/crm/procesos-y-fases)
Un **proceso** define un tipo de ciclo comercial: la forma en que tu empresa vende algo de principio a fin. Las **fases** son los pasos por los que pasa una oportunidad dentro de ese proceso, y se dibujan como las columnas del tablero Kanban.
Cada empresa diseña los suyos: una venta consultiva no sigue el mismo camino que una renovación de contrato.
***
## Proceso, fase y estado [#proceso-fase-y-estado]
Tres conceptos encajan para formar tu embudo. Conviene tenerlos claros antes de configurar nada.
| Concepto | Qué es | Ejemplo |
| ----------- | ----------------------------------------------- | --------------------------------------------------- |
| **Proceso** | El tipo de ciclo comercial completo | Venta consultiva, Renovación, Captación |
| **Fase** | Un paso dentro del proceso (columna del Kanban) | Cualificación, Demo, Propuesta, Negociación, Cierre |
| **Estado** | El resultado de la oportunidad | Pendiente, Ganada, Perdida |
La diferencia práctica: una **oportunidad** vive en una sola fase a la vez y avanza arrastrándola por el Kanban. El **estado** marca si sigue abierta (Pendiente) o ya terminó (Ganada o Perdida).
Una oportunidad es un trato concreto con una entidad (cliente o cliente potencial), con su importe y su fecha esperada. Aquí defines el **camino** que recorren tus oportunidades; darlas de alta y moverlas es otra tarea.
***
## Las fases son las columnas del Kanban [#las-fases-son-las-columnas-del-kanban]
El orden de las fases importa: define el embudo visual de izquierda a derecha. Cuando entras en la vista Kanban, cada fase del proceso es una columna y cada oportunidad es una tarjeta dentro de su columna actual.
Para mover una oportunidad de fase, **arrastra su tarjeta** a la columna siguiente. Dinaup guarda cada cambio de fase con su fecha y hora. Esa traza alimenta tus métricas: cuánto tiempo pasa una oportunidad en cada fase, dónde se atascan los tratos y tu tasa de conversión entre fases.
***
## Estados finales: ganada o perdida [#estados-finales-ganada-o-perdida]
Cuando una oportunidad llega a su desenlace, sale del flujo de fases con uno de dos estados finales:
* **Ganada**: el trato se cerró con éxito.
* **Perdida**: el trato no salió adelante.
Al marcar una oportunidad como **perdida**, eliges un **motivo de pérdida** de una lista que tú configuras (por ejemplo: precio, competencia, *timing*, no era la persona que decide). Registrar el motivo es lo que te permite, más adelante, analizar **por qué** pierdes y no solo cuánto.
***
## Configura tu embudo [#configura-tu-embudo]
Diseña tus procesos y fases desde **CRM → Configuración**.
### Crea un proceso [#crea-un-proceso]
Da de alta un proceso por cada tipo de ciclo comercial que manejes. Si vendes igual a todo el mundo, te basta con uno. Si una renovación y una captación siguen caminos distintos, crea un proceso para cada una y ponle un nombre que lo identifique.
### Define sus fases en orden [#define-sus-fases-en-orden]
Añade las fases por las que pasa una oportunidad dentro de ese proceso y **ordénalas** de la primera a la última. Ese orden es el que verás como columnas en el Kanban, así que colócalas tal como avanza realmente tu venta.
### Configura los motivos de pérdida [#configura-los-motivos-de-pérdida]
Crea la lista de motivos por los que sueles perder tratos (precio, competencia, *timing*, no decisor…). Serán las opciones disponibles cuando marques una oportunidad como perdida, y la base de tu análisis de pérdidas.
### Empieza a trabajar tu pipeline [#empieza-a-trabajar-tu-pipeline]
Con el proceso listo, ya puedes dar de alta oportunidades asignándolas a su proceso y a su fase inicial, y moverlas por el Kanban a medida que avanzan.
Empieza simple, con tres o cuatro fases. Sobre-diseñar el embudo al principio es el error más típico: acabas con columnas que nadie usa. Siempre puedes añadir fases cuando tu proceso real lo pida.
***
## Cuando tu proceso cambia [#cuando-tu-proceso-cambia]
Si tu forma de vender evoluciona, no toques el proceso antiguo: crea uno nuevo con las fases actualizadas. Las oportunidades que ya estaban en el proceso anterior siguen ahí hasta que se cierren, y las nuevas las das de alta en el proceso nuevo. Así no rompes el histórico ni las métricas de lo que ya estaba en marcha.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El proceso es el tipo de ciclo comercial completo (una venta consultiva, una renovación). Las fases son los pasos dentro de ese proceso (cualificación, demo, propuesta…) y se muestran como las columnas del Kanban.
Las que refleje tu venta real, pero empieza con tres o cuatro. Es preferible un embudo corto que se usa a uno largo lleno de columnas vacías. Puedes añadir fases más adelante.
Para entender por qué pierdes, no solo cuánto. Al marcar una oportunidad como perdida eliges un motivo de tu lista, y eso te permite analizar después si pierdes por precio, por competencia, por timing, etc.
No. Crea un proceso nuevo con las fases actualizadas. Las oportunidades que ya estaban en el proceso anterior se quedan ahí hasta cerrarse; las nuevas van al proceso nuevo.
***
→ [Volver al CRM](/docs/rtg/crm)
→ [Seguimientos](/docs/rtg/crm/seguimientos)
# Productividad y análisis (/docs/rtg/crm/productividad-y-analisis)
El CRM tiene dos pantallas para medir lo que pasa en el pipeline y en el equipo: **Productividad**, centrada en la actividad comercial de un periodo, y **Análisis**, un cuadro de mando del pipeline repartido en pestañas. Ambas están en el grupo **Productividad** del menú lateral.
***
## Productividad [#productividad]
Mide la actividad comercial dentro de un rango de fechas que tú eliges.
### Filtrar por fechas [#filtrar-por-fechas]
Arriba fijas el rango con **Desde** y **Hasta**, o usas un botón de atajo: **Hoy**, **Ayer**, **Últimos 7 días**, **Últimos 30 días**, **Mes Actual** o **Mes Pasado**.
### Qué mide [#qué-mide]
En la cabecera, una fila de KPIs del periodo:
| KPI | Qué cuenta |
| ------------------------ | ----------------------------------------- |
| **Nuevas oportunidades** | Oportunidades dadas de alta en el rango. |
| **Alta de Eventos** | Eventos nuevos programados. |
| **Eventos** | Eventos del periodo. |
| **Cambios de Fase** | Movimientos de oportunidades entre fases. |
| **Cambios de Estado** | Cambios de estado de oportunidades. |
| **Comerciales Activos** | Comerciales con actividad. |
| **Clientes Tocados** | Clientes con alguna interacción. |
Debajo, un **funnel** con las oportunidades por proceso y fase, gráficas de oportunidades por estado y por proceso, los cambios de estado y de fase, y la actividad por comercial.
***
## Análisis [#análisis]
Un cuadro de mando del pipeline, marcado como **Preview**. Fijas el rango de fechas con el selector superior y consultas los datos en ocho pestañas.
| Pestaña | Qué muestra |
| ------------- | --------------------------------------------------------------------------------------------------------- |
| **Resumen** | KPIs del periodo: oportunidades creadas, pipeline generado, ticket medio, actividad comercial y pérdidas. |
| **Pipeline** | Distribución de oportunidades por fase, proceso, tipo y estado. |
| **Equipo** | Ranking por comercial: pipeline generado, número de oportunidades y tiempo invertido. |
| **Clientes** | Top 10 de clientes por pipeline y por número de oportunidades. |
| **Captación** | Origen de las oportunidades por método de captación y por campaña. |
| **Pérdidas** | Motivos de pérdida y valor perdido, de las oportunidades con fecha de pérdida en el rango. |
| **Actividad** | Análisis de los eventos: por tipo, por estado y minutos invertidos. |
| **Bonos** | Conclusiones de tareas por bono, por cliente y por proyecto. |
Casi todas las gráficas permiten cambiar entre vista de tabla y vista de gráfico con el conmutador de cada tarjeta.
***
→ [Panel del CRM](/docs/rtg/crm/panel)
→ [Seguimientos y eventos](/docs/rtg/crm/seguimientos)
→ [Volver al CRM](/docs/rtg/crm)
# Acciones rápidas y Drive (/docs/rtg/crm/quick-actions-y-drive)
Dos funciones del CRM: las **acciones rápidas** localizan un cliente y crean una venta o un pedido para él sin salir del CRM, y **Drive** es el espacio de archivos donde el equipo comercial guarda y organiza sus documentos.
***
## Acciones rápidas desde la ficha del cliente [#acciones-rápidas-desde-la-ficha-del-cliente]
La **Ficha de Cliente** es la pantalla donde buscas un cliente, lo seleccionas y creas lo que necesites para él. La encuentras en el menú lateral del CRM, en **Ficha de Cliente**.
### Localizar al cliente [#localizar-al-cliente]
### Busca o selecciona el cliente [#busca-o-selecciona-el-cliente]
En el bloque **Acceso rápido**, usa el selector de cliente para buscar por nombre. También puedes abrir la búsqueda en cualquier momento pulsando **F2**.
### Crea el cliente si no existe [#crea-el-cliente-si-no-existe]
Si el cliente aún no está dado de alta, pulsa el botón **+** junto al buscador para crear una ficha rápida sin abandonar la pantalla.
### Trabaja sobre su ficha [#trabaja-sobre-su-ficha]
Al seleccionar un cliente se carga su resumen: datos principales, oportunidades, pedidos y ventas. Desde ahí lanzas las acciones rápidas.
### Acciones disponibles [#acciones-disponibles]
Con un cliente seleccionado aparecen estos botones, cada uno con su atajo de teclado:
| Acción | Atajo | Qué hace |
| ------------- | ----- | --------------------------------------------------------------------------- |
| **Ver ficha** | `F3` | Abre la ficha completa del cliente para consultar o editar todos sus datos. |
| **Pedido** | `F4` | Abre el alta rápida de un **pedido** ya asociado a ese cliente. |
| **Venta** | `F6` | Abre el alta rápida de una **venta** ya asociada a ese cliente. |
No tienes que volver a indicar el cliente: la venta o el pedido nacen vinculados a quien tienes seleccionado.
Los atajos de teclado permiten encadenar altas sin tocar el ratón, útil para mostrador o televenta.
### Todo el contexto del cliente, a la vista [#todo-el-contexto-del-cliente-a-la-vista]
Bajo las acciones, la ficha reúne en un mismo sitio el historial del cliente, organizado en pestañas:
* **Información del cliente**: nombre, tipo de cliente, ubicación y observaciones.
* **Oportunidades** y **eventos recientes** relacionados con él.
* **Pedidos**: sus pedidos y los conceptos pedidos.
* **Ventas**: sus ventas e ingresos y los conceptos vendidos.
Las sugerencias de venta generadas por IA sobre una oportunidad están en su propia herramienta.
→ [IA en el CRM](/docs/rtg/crm/ia-en-crm)
***
## Drive: los archivos de tu CRM [#drive-los-archivos-de-tu-crm]
**Drive** es el explorador de archivos del CRM. Funciona como una unidad de disco dentro de Dinaup: creas carpetas, subes documentos y los tienes ordenados y accesibles para el equipo comercial. Lo abres desde el menú lateral del CRM, en **Más opciones → Drive**.
Es el sitio natural para guardar propuestas, contratos, presentaciones, fichas técnicas o cualquier documento que tu equipo necesite tener a mano.
### Qué puedes hacer [#qué-puedes-hacer]
* **Crear carpetas** y subcarpetas para estructurar la información. Cada carpeta puede llevar su propio icono y color.
* **Subir archivos** arrastrándolos sobre la ventana o con el botón **Subir**. También puedes **subir una carpeta entera** con su contenido.
* **Navegar** con la ruta de migas superior y con el árbol de carpetas lateral.
* **Buscar** por nombre dentro de la ubicación actual (o pulsa la tecla `/` para saltar al buscador).
* **Ordenar** la lista por nombre, fecha de modificación o tamaño.
* **Previsualizar** un archivo haciendo clic sobre él, sin necesidad de descargarlo.
* **Descargar** archivos, uno a uno o varios a la vez tras seleccionarlos.
* **Mover** archivos y carpetas arrastrándolos a otra carpeta.
* **Eliminar** lo que ya no necesites; lo borrado va a la **papelera**, desde donde puedes revisarlo.
### Compartir un archivo [#compartir-un-archivo]
Cada archivo tiene una acción de **Compartir** que genera un enlace para enviárselo a quien quieras. También puedes **copiar la URL** del archivo desde su menú.
Los enlaces de descarga son **temporales**: caducan al cabo de unos minutos. Genera uno nuevo cuando vuelvas a necesitarlo en lugar de guardar el enlace antiguo.
### Selección múltiple [#selección-múltiple]
Puedes seleccionar varios elementos a la vez para descargarlos o eliminarlos en bloque:
* Marca las casillas de cada fila, o usa **Ctrl/Cmd + clic** y **Mayús + clic** para selección por rango.
* `Ctrl/Cmd + A` selecciona todo lo visible.
* `Supr` elimina la selección (con confirmación).
Al eliminar una carpeta se borra también todo su contenido. Dinaup te avisa de cuántos archivos y subcarpetas se verán afectados antes de confirmar.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Mientras tengas un cliente seleccionado en la Ficha de Cliente, las acciones Pedido (F4) y Venta (F6) crean el documento ya asociado a ese cliente.
Sí. El botón + junto al buscador abre el alta rápida de cliente sin salir de la pantalla.
Es el espacio de archivos de tu CRM: carpetas y documentos del equipo comercial, con subida, búsqueda, previsualización, descarga y compartición por enlace temporal.
Lo eliminado va a la papelera de Drive, accesible desde la barra de acciones, donde puedes revisar lo borrado.
***
→ [CRM (visión general)](/docs/rtg/crm)
→ [IA en el CRM](/docs/rtg/crm/ia-en-crm)
→ [Seguimientos](/docs/rtg/crm/seguimientos)
# Seguimientos y eventos (/docs/rtg/crm/seguimientos)
Un **evento** es cualquier interacción con un cliente: una llamada, un email, una reunión, una visita o una simple nota interna. Cada vez que registras un evento, Dinaup lo añade a la **línea de tiempo** de la oportunidad y del cliente, y suma a la actividad del comercial que lo ha hecho.
Con los seguimientos, lo que hablaste, cuándo, con quién y qué quedó pendiente queda escrito y accesible para todo el equipo.
***
## Qué es un evento [#qué-es-un-evento]
Un evento responde siempre a tres preguntas: **qué** pasó, **cuándo** y **con quién**. Sobre esa base, cada evento puede llevar una fecha programada, una duración, notas y la oportunidad a la que pertenece.
Los tipos de evento son **configurables** por tu empresa desde **CRM > Configuración**. Estos son los habituales:
| Tipo | Para qué sirve |
| ----------- | -------------------------------------------------------------------------------- |
| **Llamada** | Una conversación telefónica con el contacto |
| **Email** | Un correo enviado o recibido relacionado con el trato |
| **Reunión** | Un encuentro programado, presencial o por videollamada |
| **Visita** | Un desplazamiento al cliente o una visita del cliente |
| **Nota** | Una anotación interna sin interacción directa (un recordatorio, una observación) |
Empieza con pocos tipos de evento y añade más solo cuando los necesites. Demasiadas categorías al principio hacen que el equipo dude al registrar y dejen de hacerlo.
***
## Para qué sirven los seguimientos [#para-qué-sirven-los-seguimientos]
Cada evento trabaja en tres frentes a la vez:
* **Alimenta la línea de tiempo de la oportunidad.** Ves todo lo que ha pasado en el trato, en orden, sin reconstruirlo de memoria.
* **Alimenta la ficha del cliente.** En la vista 360° del cliente aparece su historial completo de interacciones, vengan de la oportunidad que vengan.
* **Mide la actividad del comercial.** Las llamadas, reuniones y emails registrados cuentan para las métricas de productividad del equipo.
Por eso conviene escribir las notas como si fueran para un compañero que te cubre las vacaciones: cuanto más claras, más útil es el historial para ti, para el equipo y para las sugerencias de la IA.
***
## Añadir un evento rápido [#añadir-un-evento-rápido]
La forma más ágil de registrar una interacción es la casilla de **evento rápido** que tienes dentro de cada oportunidad. Escribes en lenguaje natural lo que ha pasado o lo que vas a hacer, y Dinaup lo convierte en un evento estructurado.
### Abre la oportunidad [#abre-la-oportunidad]
Entra en la oportunidad sobre la que quieres dejar constancia. La casilla de evento rápido vive dentro de su ficha.
### Escribe qué ha pasado o qué harás [#escribe-qué-ha-pasado-o-qué-harás]
Redacta una frase normal, por ejemplo: *"Reunión con el contacto mañana a las 16:30 en la oficina para firmar el contrato."* No hace falta rellenar campos uno a uno.
### Revisa y guarda [#revisa-y-guarda]
Dinaup propone el evento ya montado (tipo, fecha, duración, notas y la oportunidad actual). Repasa que todo encaje, retoca lo que haga falta y guarda.
La interpretación del lenguaje natural la hace la IA del CRM. Tú sigues teniendo la última palabra: la IA propone el evento, tú lo confirmas.
→ [La IA en el CRM](/docs/rtg/crm/ia-en-crm)
***
## Tu agenda de eventos [#tu-agenda-de-eventos]
Los eventos con fecha futura forman tu **agenda**: las llamadas, reuniones y visitas que tienes por delante. Desde **CRM > Mis Eventos** ves la lista de tus seguimientos programados, para saber qué te toca hacer hoy y en los próximos días.
Un evento programado funciona como **recordatorio**: te avisa de que tienes una tarea pendiente con un cliente para que ningún seguimiento se quede en el aire. Cuando lo completas, lo registras y pasa a formar parte de la línea de tiempo como interacción realizada.
Programa el siguiente paso justo al cerrar el actual. Si al terminar una llamada dejas creado el evento de seguimiento, tu agenda se mantiene viva sola y nunca pierdes el hilo de un trato.
***
## La línea de tiempo [#la-línea-de-tiempo]
Todos los eventos de una oportunidad se ordenan en su **línea de tiempo**: el relato cronológico del trato, desde el primer contacto hasta el cierre. Junto a las interacciones aparecen también los hitos del propio trato, como los cambios de fase en el [tablero Kanban](/docs/rtg/crm/procesos-y-fases).
Esa misma información, vista desde el cliente, te da el historial completo de la relación con él. No tienes que saltar entre módulos ni preguntar a otro compañero: el seguimiento está donde lo necesitas.
***
## Eventos y la IA del CRM [#eventos-y-la-ia-del-crm]
La IA del CRM se apoya en tus eventos para entender cada trato. Puede **crear eventos a partir de lenguaje natural** (como en el evento rápido) y, cuando le pides sugerencias sobre una oportunidad, lee todo el historial de interacciones para proponerte los próximos pasos. Cuanto mejor registres tus eventos, mejores serán sus propuestas.
→ [La IA en el CRM](/docs/rtg/crm/ia-en-crm)
***
## Preguntas frecuentes [#preguntas-frecuentes]
La oportunidad es el trato concreto que persigues con un cliente. El evento es cada interacción que tienes dentro de ese trato (una llamada, un email, una reunión). Una oportunidad acumula muchos eventos a lo largo de su vida.
Sí. Los tipos de evento se configuran desde CRM > Configuración. Puedes ajustar las categorías (llamada, email, reunión, visita, nota…) a cómo trabaja tu equipo.
Sí. Una nota es un evento sin interacción directa: te sirve para dejar una observación o un recordatorio en la línea de tiempo del cliente o de la oportunidad.
Para usarlo como recordatorio. Aparece en tu agenda (CRM > Mis Eventos) y te avisa del seguimiento pendiente. Cuando lo realizas, queda registrado en la línea de tiempo.
***
→ [Volver al CRM](/docs/rtg/crm)
→ [Procesos y fases](/docs/rtg/crm/procesos-y-fases)
→ [La IA en el CRM](/docs/rtg/crm/ia-en-crm)
# Tablero Kanban (/docs/rtg/crm/tablero-kanban)
El **Tablero** es la pantalla operativa del pipeline. Eliges un proceso de venta y ves sus oportunidades repartidas en columnas, una por fase. Es donde mueves los tratos día a día.
Aquí trabajas el pipeline; el **diseño** de los procesos, las fases y los motivos de pérdida se hace en otra pantalla.
→ [Procesos y fases](/docs/rtg/crm/procesos-y-fases)
***
## Elegir el proceso [#elegir-el-proceso]
Arriba tienes el selector **Proceso**. Cambia entre los procesos de venta que tenga activos tu empresa. El tablero recuerda el último proceso que elegiste y lo carga la próxima vez que entras.
Si un proceso no tiene fases configuradas, el tablero te avisa y te remite a **Configuración → Flujos → Fases**.
***
## Las columnas son las fases [#las-columnas-son-las-fases]
Cada fase del proceso es una columna, en el orden en que las configuraste. Cada oportunidad es una tarjeta dentro de su columna actual. La cabecera de cada columna muestra su icono, su nombre, el número de oportunidades y la suma de sus importes.
Para **mover una oportunidad de fase**, arrastra su tarjeta a otra columna. El cambio se guarda al soltar. Si el guardado falla, la tarjeta vuelve a su columna anterior.
El botón **+** de cada columna crea una oportunidad nueva ya asignada a ese proceso y a esa fase.
***
## KPIs del proceso [#kpis-del-proceso]
Sobre las columnas, una fila de tarjetas resume el proceso seleccionado:
| KPI | Qué mide |
| ------------------------------- | -------------------------------------------------------------------------------------------- |
| **Pipeline Total** | Suma del valor estimado de las oportunidades visibles. |
| **Ponderado** | Valor estimado por la probabilidad de cierre de cada oportunidad. |
| **Oportunidades** | Número de oportunidades visibles. |
| **Hoy / Mañana / Prox 30 días** | Oportunidades con su próximo evento programado hoy, mañana o dentro de los próximos 30 días. |
***
## Filtrar el tablero [#filtrar-el-tablero]
Junto al selector de proceso tienes dos filtros:
* **Buscador**: filtra las oportunidades por texto.
* **Comerciales**: las burbujas de los comerciales con oportunidades en el proceso. Marca una para ver solo las suyas. Al entrar, el tablero filtra por tu propio usuario.
***
## Listas de oportunidades [#listas-de-oportunidades]
Además del tablero, el CRM tiene dos vistas en lista de las mismas oportunidades, en el menú lateral:
* **Mis Oportunidades**: solo las que tienes asignadas como comercial principal.
* **Oportunidades**: todas las oportunidades, sin filtrar por comercial.
***
→ [Oportunidades](/docs/rtg/crm/oportunidades)
→ [Procesos y fases](/docs/rtg/crm/procesos-y-fases)
→ [Volver al CRM](/docs/rtg/crm)
# Análisis de facturas (/docs/rtg/ia/analisis-de-facturas)
El **Análisis de facturas** es el historial de cada lectura de factura con IA. Cada fila es una llamada al modelo para extraer los datos de un PDF. Aquí no subes facturas: eso se hace en la [digitalización](/docs/rtg/ia/digitalizacion-ocr). Esta pantalla es el registro de lo que ya se ha procesado, con su coste y su tiempo.
Lo encuentras en **IA → Análisis Facturas**. Es la vista de control del OCR de facturas: sirve para revisar el gasto de la IA en digitalización y medir cuánto trabajo manual te está quitando.
***
## Elegir el periodo [#elegir-el-periodo]
Arriba tienes un selector de **rango de fechas**. Por defecto muestra los **últimos 30 días**; cambia el rango y toda la pantalla (indicadores y tabla) se recalcula para ese periodo.
***
## Los indicadores [#los-indicadores]
Sobre la tabla, dos filas de tarjetas resumen el periodo elegido.
La primera fila mide el consumo técnico de cada llamada:
| Indicador | Qué cuenta |
| ------------------ | --------------------------------------------------------- |
| **Total llamadas** | Cuántas facturas se han analizado en el periodo. |
| **Precio** | El coste total en euros de esas llamadas. |
| **Tokens entrada** | El volumen de texto que se ha enviado al modelo. |
| **Tokens salida** | El volumen de texto que el modelo ha devuelto. |
| **Cache reads** | Tokens reutilizados de la caché (más baratos). |
| **Cache creation** | Tokens que se han guardado en caché por primera vez. |
| **Duración media** | El tiempo medio que tarda cada análisis, en milisegundos. |
La segunda fila mide el resultado de negocio:
| Indicador | Qué cuenta |
| ------------------------- | --------------------------------------------------------------------- |
| **Proveedores distintos** | Cuántos proveedores diferentes aparecen en las facturas del periodo. |
| **Proveedores nuevos** | De esos, cuántos no existían en tu ficha y la IA marcó como alta. |
| **Tiempo con IA** | El tiempo estimado que has empleado digitalizando con IA. |
| **Tiempo sin IA** | El tiempo que habrías empleado tecleando esas mismas facturas a mano. |
Las dos últimas tarjetas son la comparación que justifica el OCR: **tiempo con IA** frente a **tiempo sin IA** te dice, en horas y minutos, lo que la lectura automática te ha ahorrado en el periodo.
***
## La tabla de llamadas [#la-tabla-de-llamadas]
Debajo, una tabla lista cada análisis, ordenada por fecha de la más reciente a la más antigua. Puedes ordenar por cualquier columna y pasar de página.
| Columna | Qué muestra |
| ------------- | ------------------------------------------------------- |
| **Fecha** | Cuándo se lanzó el análisis. |
| **Usuario** | Quién subió la factura. |
| **Modelo** | El modelo de IA que hizo la lectura. |
| **Input** | Tokens de entrada de esa llamada. |
| **Output** | Tokens de salida de esa llamada. |
| **Cache** | Tokens leídos de caché, si los hubo. |
| **Cache new** | Tokens que se guardaron en caché en esa llamada. |
| **Precio** | El precio y el coste de esa lectura. |
| **Duración** | Lo que tardó, en milisegundos. |
| (estado) | Un icono verde si la lectura salió bien, rojo si falló. |
Si no hay análisis en el periodo elegido, la pantalla muestra un aviso de **sin análisis** en lugar de la tabla.
***
## Relación con la digitalización [#relación-con-la-digitalización]
Esta pantalla y la [digitalización de facturas](/docs/rtg/ia/digitalizacion-ocr) son las dos caras del mismo proceso:
* En **Digitalización** subes la factura y la conviertes en un gasto.
* En **Análisis de facturas** ves el registro de esas lecturas, con su coste y su tiempo.
Para el desglose completo del gasto de IA de tu empresa (chat, herramientas y todo lo demás, no solo facturas), usa el [panel de uso](/docs/rtg/ia/panel-de-uso).
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Esta pantalla es solo el historial de las lecturas ya hechas. Para subir una factura nueva ve a la digitalización.
El panel de uso reparte todo el gasto de IA de la empresa (chat, herramientas, clasificadores…). Esta pantalla se centra solo en las lecturas de factura, con el detalle de cada llamada.
Parte del texto que se envía al modelo se reutiliza entre llamadas. Los cache reads son esos tokens reaprovechados, que cuestan menos; la cache creation es lo que se guarda por primera vez para reutilizarlo después.
De comparar el tiempo estimado de digitalizar con IA frente al de teclear esas mismas facturas a mano. Es una estimación para dimensionar el ahorro, no un cronómetro exacto.
***
→ [Digitalización de facturas (OCR)](/docs/rtg/ia/digitalizacion-ocr)
→ [Panel de uso](/docs/rtg/ia/panel-de-uso)
→ [IA en Dinaup](/docs/rtg/ia)
# Casos de IA por módulo (/docs/rtg/ia/casos-por-modulo)
La IA de Dinaup aparece dentro de los módulos que ya usas: lee una factura, clasifica un movimiento bancario, propone el siguiente paso con un cliente o resume una tarea sin que cambies de pantalla.
Esta página recorre módulo por módulo dónde está la IA y para qué sirve. Para la base (cómo chatear, crear agentes o controlar el gasto), empieza por la introducción a la [IA en Dinaup](/docs/rtg/ia).
**La IA sugiere, tú decides.** En todos los casos de abajo, la IA propone y tú confirmas antes de que algo se grabe, se envíe o se cierre. Nunca actúa a tus espaldas, y hereda tus permisos: si no ves un dato, la IA tampoco.
***
## Resumen: qué hace en cada módulo [#resumen-qué-hace-en-cada-módulo]
| Módulo | Casos de IA |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Pymes** | Lectura OCR de facturas en PDF · clasificación automática de movimientos bancarios y sugerencia de reglas · investigador de entidades (análisis 360° de cliente o proveedor) |
| **CRM** | Crear eventos desde lenguaje natural · carrusel de sugerencias (puntos fuertes, puntos débiles, próxima acción, mensaje listo para enviar) |
| **TPV** | Lectura OCR de la factura del proveedor para registrar la compra |
| **Tareas y Proyectos** | Agente mencionable en comentarios (resumir, qué queda, generar subtareas) · alertas de higiene |
| **Recursos Humanos** | Chat de consultas sobre la plantilla · redacción de comunicados |
***
## Pymes [#pymes]
En facturación y tesorería la IA cubre la transcripción de documentos y la clasificación de movimientos.
### Lectura OCR de facturas en PDF [#lectura-ocr-de-facturas-en-pdf]
Subes el PDF de una factura y la IA lee el documento y rellena la ficha por ti: **proveedor, fecha, base imponible, IVA y las líneas de detalle**. En lugar de teclear todos los campos a mano, revisas lo que la IA ha extraído, corriges lo que haga falta y grabas.
Si el proveedor no existe todavía, la IA te lo propone como alta nueva a partir de los datos del documento.
El OCR funciona como una **propuesta**: ves todos los campos rellenos antes de aceptar. Si la IA interpreta mal un importe o una línea, lo ajustas antes de grabar la compra.
### Clasificación automática de movimientos bancarios [#clasificación-automática-de-movimientos-bancarios]
Cuando importas un extracto, la IA analiza cada movimiento y propone a qué corresponde: el proveedor o cliente, el tipo de operación, la categoría. Así llegas a la conciliación con la mayor parte del extracto ya ordenado en vez de un listado en bruto.
Cuando un patrón se repite, la IA va más allá y te **sugiere crear una regla** para que ese concepto se clasifique solo la próxima vez. Tú decides si conviertes la sugerencia en regla general (todas las cuentas) o solo para esa cuenta.
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
→ [Reglas de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios)
### Investigador de entidades (análisis 360°) [#investigador-de-entidades-análisis-360]
Pides a la IA un análisis completo de un cliente o un proveedor y te devuelve una visión **360°**: qué le has vendido o comprado, su comportamiento de pago, su histórico, lo relevante para tu relación con esa entidad. Útil antes de una reunión, de ampliar crédito o de renegociar condiciones.
→ [Documentación de Pymes](/docs/rtg/pymes)
***
## CRM [#crm]
En el CRM la IA cubre dos tareas: registrar lo que ha pasado y proponer el siguiente paso.
### Crear eventos desde lenguaje natural [#crear-eventos-desde-lenguaje-natural]
Escribes en lenguaje natural lo que ocurrió o lo que vas a hacer (por ejemplo, *"llamar a ACME el jueves a las 10 para revisar el presupuesto"*) y la IA lo convierte en un **seguimiento estructurado**: tipo de evento, fecha, hora y entidad asociada. Te ahorra rellenar el formulario campo a campo.
### Carrusel de sugerencias [#carrusel-de-sugerencias]
Sobre una oportunidad o un cliente, la IA te muestra un **carrusel de tarjetas** con análisis y acciones listas para usar:
* **Puntos fuertes**: qué juega a tu favor en esta operación.
* **Puntos débiles**: qué riesgos o frenos detecta.
* **Próxima acción**: el siguiente paso recomendado.
* **Mensaje listo para enviar**: un texto redactado para el cliente que puedes revisar, ajustar y enviar.
Como siempre, el mensaje es un borrador: tú decides si lo envías tal cual, lo editas o lo descartas.
→ [Documentación del CRM](/docs/rtg/crm)
***
## TPV [#tpv]
En el punto de venta, la IA registra las compras a proveedores con el mismo OCR que en Pymes.
### Lectura OCR de la factura del proveedor [#lectura-ocr-de-la-factura-del-proveedor]
Cuando recibes mercancía con su factura, subes el documento y la IA lo lee y **rellena la compra**: proveedor, fecha, importes y líneas. Revisas, corriges si hace falta y confirmas, sin transcribir el papel a mano.
→ [Documentación del TPV](/docs/rtg/tpv)
***
## Tareas y Proyectos [#tareas-y-proyectos]
Aquí la IA actúa como un miembro más del equipo al que puedes preguntar, y como un vigilante que mantiene el tablero sano.
### Agente mencionable en comentarios [#agente-mencionable-en-comentarios]
Dentro de una tarea puedes **mencionar al agente** en un comentario y pedirle cosas sobre esa tarea:
* **Resumir** el hilo de comentarios cuando la conversación se ha hecho larga.
* **Qué queda** por hacer según lo hablado.
* **Generar subtareas** a partir de la descripción, para desglosar el trabajo.
El agente responde en el propio comentario, con el contexto de la tarea delante.
### Alertas de higiene [#alertas-de-higiene]
La IA revisa el estado del trabajo y te avisa de las tareas que están **mal cuidadas**: sin responsable asignado, sin fecha, paradas demasiado tiempo. Son avisos para que el tablero no se llene de tareas huérfanas que nadie mueve.
→ [Documentación de Proyectos](/docs/rtg/proyectos)
***
## Recursos Humanos [#recursos-humanos]
En RRHH la IA ayuda a responder dudas sobre la plantilla y a escribir las comunicaciones internas.
### Chat de consultas [#chat-de-consultas]
Preguntas en lenguaje natural sobre tu personal y la IA te responde consultando los datos a los que tienes acceso (por ejemplo, sobre ausencias, horarios o la composición de la plantilla). Respeta tus permisos: si tu usuario no ve las nóminas, la IA tampoco las consulta.
### Redacción de comunicados [#redacción-de-comunicados]
Le das los puntos clave y la IA te redacta el **comunicado** o la **carta** interna: un aviso a la plantilla, una notificación, un borrador de comunicación. Revisas el texto y lo ajustas antes de difundirlo.
→ [Documentación de RRHH](/docs/rtg/recursos-humanos)
***
## Algo común a todos los módulos [#algo-común-a-todos-los-módulos]
Más allá de estos casos concretos, hay dos capacidades de IA que aparecen de forma transversal en cualquier módulo:
* **Herramientas de texto**: en cualquier campo de texto largo puedes corregir, resumir, expandir, cambiar el tono o traducir lo que escribes.
* **Clasificadores automáticos**: etiquetas que se rellenan solas al escribir un texto (sentimiento, idioma, urgencia, tema…). Útiles, por ejemplo, para ordenar una bandeja de tickets por urgencia o filtrar las reseñas negativas sin leerlas una a una.
→ [Volver a la IA en Dinaup](/docs/rtg/ia)
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. En todos estos casos la IA propone (un campo relleno, una regla, un mensaje, un evento) y tú confirmas antes de que se grabe o se envíe. Solo realiza acciones sin confirmación si le has dado permiso explícito para algo poco reversible.
Es la misma capacidad de lectura de documentos: subes el PDF, la IA extrae proveedor, fecha, importes y líneas, y tú revisas antes de grabar. En Pymes rellena la compra desde facturación; en el TPV, desde el registro de compras del punto de venta.
No. La IA hereda exactamente tus permisos. Si no tienes acceso a una sección, la IA tampoco la consulta cuando le preguntas.
Sí. El administrador puede desactivar la IA para toda la empresa, y entonces desaparecen todas estas acciones. Es completamente opcional.
***
→ [IA en Dinaup](/docs/rtg/ia)
→ [Documentación de Pymes](/docs/rtg/pymes)
→ [Documentación del CRM](/docs/rtg/crm)
→ [Documentación del TPV](/docs/rtg/tpv)
→ [Documentación de Proyectos](/docs/rtg/proyectos)
→ [Documentación de RRHH](/docs/rtg/recursos-humanos)
# Chat y agentes de IA (/docs/rtg/ia/chat-y-agentes)
Un **agente** es un asistente de IA con el que conversas dentro de Dinaup. Le preguntas en lenguaje natural y te responde, consulta los datos a los que tú tienes acceso y te propone acciones concretas. El agente nunca cierra una factura, envía un email ni cambia un dato sin tu confirmación.
El chat se abre en una **ventana flotante**, así que puedes seguir trabajando con la pantalla de detrás mientras conversas.
***
## Elegir el nivel del modelo [#elegir-el-nivel-del-modelo]
Antes de escribir (o en cualquier momento de la conversación) eliges con qué **nivel** de modelo quieres que piense el agente. El nivel marca el equilibrio entre rapidez y profundidad de razonamiento.
| Nivel | Cómo trabaja | Para qué tareas |
| --------------- | ----------------------------- | --------------------------------------------------------------------- |
| **Rápido** | Responde casi al instante | Preguntas simples, clasificar, resumir algo corto, tareas repetitivas |
| **Equilibrado** | Rápido y capaz a la vez | El día a día. Cubre la mayoría de los casos |
| **Razonador** | Piensa más despacio y a fondo | Decisiones complejas, análisis profundo, redacciones críticas |
Empieza siempre por **Equilibrado**. Si ves que el agente se queda corto o se equivoca en algo importante, sube a **Razonador**. Para volúmenes grandes de preguntas sencillas, baja a **Rápido** y ganas velocidad.
Subir de nivel consume más cuota de IA por cada respuesta. Bajarlo, menos. Ajusta el nivel a lo que la tarea realmente pide en vez de usar siempre el más potente.
→ [Cuotas y permisos de IA](/docs/rtg/ia/cuotas-y-permisos)
***
## Adjuntar archivos al chat [#adjuntar-archivos-al-chat]
Puedes arrastrar o subir archivos a la conversación para que el agente los lea y responda sobre ellos. Sirve para imágenes, PDFs, hojas de cálculo y documentos de texto.
Algunos ejemplos:
* Adjuntar la factura de un proveedor y preguntar si encaja con un pedido concreto.
* Subir una hoja de cálculo y pedir un resumen de las cifras.
* Pasar un documento largo y pedir los puntos clave.
El agente usa el contenido del archivo como contexto de esa conversación para darte una respuesta basada en él.
***
## Prompts y respuestas sugeridas [#prompts-y-respuestas-sugeridas]
No hace falta saber qué preguntar para arrancar. Dinaup te guía con sugerencias en dos momentos del chat:
### Prompts sugeridos para empezar [#prompts-sugeridos-para-empezar]
Al abrir el agente verás unos **prompts sugeridos**: preguntas de arranque que aparecen como botones. Un clic y empiezas la conversación sin tener que escribir nada desde cero. Cada agente trae las suyas, pensadas para lo que sabe hacer.
### Respuestas sugeridas con el siguiente paso [#respuestas-sugeridas-con-el-siguiente-paso]
Después de cada respuesta del agente aparecen **chips con próximos pasos** habituales (por ejemplo, generar un documento, crear una tarea o redactar un email). Pulsas uno y enlazas con la siguiente acción sin reescribir el contexto.
***
## Historial de conversaciones [#historial-de-conversaciones]
Todas tus conversaciones con agentes se **guardan** sin que hagas nada y son **buscables por palabra clave**. Así recuperas lo que ya preguntaste sin tener que repetirlo y retomas un hilo días después.
Cuando quieras arrancar de cero, **limpia el chat**: empiezas una conversación nueva y el agente olvida el hilo actual, pero conserva su conocimiento de largo plazo. El historial anterior sigue ahí, disponible en la búsqueda.
***
## Qué puede hacer la IA con tus datos [#qué-puede-hacer-la-ia-con-tus-datos]
El valor de un agente de Dinaup es que no es un chat aislado: conoce tu negocio. Pero siempre dentro de unos límites claros.
### Consulta solo lo que tú puedes ver [#consulta-solo-lo-que-tú-puedes-ver]
El agente puede **consultar los datos a los que tu usuario tiene acceso**: ventas, productos, clientes, lo que esté dentro de tus permisos. La IA **hereda tus permisos exactos**: si tu usuario no ve las nóminas, el agente tampoco. No hay forma de que vea más de lo que verías tú.
### Propone acciones, tú las confirmas [#propone-acciones-tú-las-confirmas]
Cuando una respuesta implica **crear o modificar un dato**, el agente no lo graba por su cuenta: te abre el formulario con la propuesta rellena para que la revises y confirmes. Tú ves qué va a pasar antes de que pase, y tú firmas.
| Lo que hace la IA | Ejemplo | ¿Confirmas tú? |
| ----------------- | --------------------------------- | --------------------------- |
| **Leer** | Consultar tus ventas del mes | No, es solo lectura |
| **Sugerir** | Proponer cómo clasificar un gasto | Sí, antes de grabar |
| **Generar** | Redactar un email a un cliente | Sí, tú decides si lo envías |
Revisa siempre lo que vas a grabar o enviar antes de confirmar.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Empieza por Equilibrado, que cubre la mayoría de los casos. Sube a Razonador para decisiones complejas, análisis profundos o textos críticos. Baja a Rápido para preguntas sencillas o tareas repetitivas, donde ganas velocidad y consumes menos cuota.
No. Cuando una acción crea o modifica un registro, el agente te abre el formulario con la propuesta para que la revises y confirmes. Tú ves el cambio antes de grabarlo.
No. La IA hereda tus permisos exactos. Solo consulta lo que tu usuario ya tiene acceso a ver. No hay escalada de permisos.
Sí. Todas se guardan y puedes buscarlas por palabra clave en el historial. Si quieres empezar de cero, limpia el chat: el agente olvida el hilo actual pero el historial anterior sigue accesible.
Sí. Puedes subir imágenes, PDFs, hojas de cálculo y documentos de texto. El agente los lee y responde sobre su contenido dentro de esa conversación.
***
→ [Crear tu propio agente](/docs/rtg/ia/crear-agente)
→ [Cuotas y permisos de IA](/docs/rtg/ia/cuotas-y-permisos)
→ [Casos de uso de la IA por módulo](/docs/rtg/ia/casos-por-modulo)
# Clasificadores automáticos (/docs/rtg/ia/clasificadores)
Un **clasificador** es una etiqueta que la IA calcula sola a partir de un texto: lee el contenido de un campo y le pone una marca de color con su veredicto. Lo añades a cualquier campo de texto de tus registros y, a partir de ahí, cada nuevo texto se etiqueta sin que hagas nada.
La idea es que dejes de leer registro por registro para saber qué hay dentro. El clasificador te lo resume en una marca: si una reseña es positiva o negativa, si un ticket es urgente, en qué idioma llega un email. Con esa marca puedes **segmentar, priorizar y enrutar** tu trabajo de golpe.
***
## Catálogo de clasificadores [#catálogo-de-clasificadores]
Estos son los tipos disponibles. Cada uno analiza una dimensión distinta del texto:
| Clasificador | Qué detecta | Ejemplo de uso |
| ------------------ | ---------------------------------------------------------- | --------------------------------- |
| **Sentimiento** | Si el tono es positivo, negativo, neutro o mixto | Reseñas y opiniones de clientes |
| **Idioma** | El idioma en que está escrito el texto | Emails entrantes de varios países |
| **Urgencia** | El nivel de prioridad: baja, media, alta o crítica | Tickets de soporte |
| **Toxicidad** | Si hay lenguaje ofensivo o agresivo | Comentarios de una comunidad |
| **Tema** | La categoría del contenido (ventas, técnico, facturación…) | Clasificar el correo entrante |
| **Legibilidad** | Lo fácil o difícil que es de leer el texto | Revisar copy de marketing |
| **Emoji sugerido** | Un emoji que resume el contenido | Títulos y mensajes cortos |
Además de estos tipos predefinidos, puedes **definir tus propias categorías**: le indicas la lista de etiquetas con las que quieres clasificar y la IA encaja cada texto en una de ellas. Así adaptas el clasificador al vocabulario de tu negocio.
***
## Cómo funciona [#cómo-funciona]
El clasificador trabaja sobre un campo de texto que tú eliges. Cuando el texto cambia, la marca se recalcula con su nuevo veredicto.
### Elige el campo a clasificar [#elige-el-campo-a-clasificar]
Decide sobre qué texto quieres la etiqueta: una descripción, un comentario, el cuerpo de un email, una reseña. El clasificador lee ese campo, no toda la ficha.
### Elige el tipo de clasificador [#elige-el-tipo-de-clasificador]
Selecciona qué dimensión quieres marcar (sentimiento, urgencia, idioma…) o define tus propias categorías si ninguna de las predefinidas encaja con tu caso.
### Deja que se rellene solo [#deja-que-se-rellene-solo]
Con el clasificador activado, cada vez que llega o cambia un texto la IA calcula la etiqueta y la muestra como una marca de color junto al registro. No tienes que pulsar nada.
Como cualquier capacidad de IA en Dinaup, el clasificador **sugiere, no decide**. La marca es una ayuda para ordenar tu trabajo; tú sigues siendo quien actúa sobre cada registro.
***
## Para qué sirven [#para-qué-sirven]
El valor de un clasificador está en lo que haces con la marca. Tres usos principales:
* **Segmentar.** Filtras tu lista por el color de la etiqueta y te quedas solo con lo que te interesa. Por ejemplo, ver todas las reseñas negativas o todos los textos en un idioma concreto.
* **Priorizar.** Ordenas por la etiqueta para atender primero lo importante. Una bandeja de tickets con marca de urgencia te dice qué abrir antes sin leer ni uno.
* **Enrutar.** Decides a dónde va cada registro según su etiqueta. Un email entrante clasificado por idioma o por tema puede dirigirse al equipo que corresponde.
Como la marca aparece en la vista de lista, conviertes una columna de textos largos en una columna de colores que filtras y ordenas.
***
## Coste [#coste]
Una clasificación consume muy poco: es una operación corta y puntual de IA, mucho más ligera que una conversación con un agente. Por eso puedes ponerla sobre muchos registros sin preocuparte demasiado por el gasto.
Aun así, las clasificaciones cuentan dentro del consumo de IA de tu empresa, igual que el resto de capacidades. Si quieres ver cuánto gastas y cómo se reparte tu cuota, consulta:
→ [Cuotas y permisos de IA](/docs/rtg/ia/cuotas-y-permisos)
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Una vez activado el clasificador sobre un campo, la etiqueta se recalcula sola cuando el texto cambia. Por eso se llama automático.
Sí. Además de los tipos predefinidos (sentimiento, urgencia, idioma…), puedes pasarle tu propia lista de categorías y la IA clasificará cada texto en una de ellas.
No modifica el contenido. El clasificador solo añade una marca informativa que puedes usar para filtrar, ordenar y enrutar. La decisión sobre el registro sigue siendo tuya.
Muy poco: es una operación de IA corta y puntual, mucho más ligera que un chat. Cuenta dentro del consumo de IA de tu empresa, que puedes seguir desde tus cuotas.
***
→ [Casos de uso de la IA por módulo](/docs/rtg/ia/casos-por-modulo)
→ [Cuotas y permisos de IA](/docs/rtg/ia/cuotas-y-permisos)
# Crear un agente (/docs/rtg/ia/crear-agente)
Un **agente** es un asistente de IA con personalidad y conocimiento propios que tú defines en el **Builder**. Le das un rol, le enseñas tus documentos, le añades habilidades reutilizables y eliges con qué modelo piensa.
A diferencia de los agentes predefinidos del Explorer, el que creas aquí es tuyo: lo configuras de principio a fin y decides quién puede usarlo.
***
## Qué configuras en un agente [#qué-configuras-en-un-agente]
Un agente se monta sobre seis piezas. No todas son obligatorias: con un nombre y un buen rol ya funciona, y el resto lo añades cuando lo necesites.
| Pieza | Qué hace | ¿Obligatoria? |
| ---------------------------- | ----------------------------------------------------------- | -------------------------------- |
| **Identidad** | Nombre, avatar, descripción y disclaimer | Nombre sí, el resto recomendable |
| **System prompt** | Define quién es el agente y cómo se comporta | Sí (es el alma del agente) |
| **Modelo** | El motor que piensa: proveedor, nivel y ventana de contexto | No (hay uno por defecto) |
| **Archivos de conocimiento** | Documentos que el agente conoce y consulta | No |
| **Habilidades** | Mini-prompts reutilizables que el agente sabe ejecutar | No |
| **Visibilidad** | Quién puede usar el agente: tú, tu equipo o una app externa | Sí (por defecto, personal) |
***
## Montar el agente en el Builder [#montar-el-agente-en-el-builder]
### Abre el Builder [#abre-el-builder]
Ve a **IA → Builder** y pulsa **Nuevo agente**. El Builder es donde viven y se editan tus agentes propios.
### Ponle identidad [#ponle-identidad]
Dale los datos básicos con los que se presentará:
* **Nombre**: claro y descriptivo (por ejemplo, "Asistente Contable").
* **Avatar**: una imagen que lo represente. Puedes generarla con IA desde una descripción.
* **Descripción**: una frase que explique para qué sirve. Ayuda a tu equipo a saber cuándo usarlo.
* **Disclaimer**: aviso que aparece al iniciar la conversación (por ejemplo, "Este agente no sustituye a un asesor certificado").
### Escribe el system prompt [#escribe-el-system-prompt]
Aquí defines **quién es el agente y cómo se comporta**: su rol, su tono, sus reglas y lo que debe hacer o evitar. Es la pieza que más influye en la calidad de las respuestas.
Cuanto más específico seas, mejor se comportará. Un buen system prompt cubre el rol, el idioma, el estilo de respuesta y las cautelas que quieres que respete.
### Elige el modelo [#elige-el-modelo]
Selecciona el motor que pensará por el agente. Si no quieres complicarte, deja el modelo por defecto: cubre la gran mayoría de los casos. Más abajo tienes los criterios para cambiarlo.
### Añade conocimiento y habilidades [#añade-conocimiento-y-habilidades]
Sube los **archivos de conocimiento** que el agente debe dominar (manuales, catálogos, normativa interna) y define las **habilidades** que quieras que sepa ejecutar. Ambos son opcionales, pero son lo que convierte a un agente genérico en un experto de tu negocio.
### Pruébalo e itera [#pruébalo-e-itera]
Pulsa **Chatear** dentro del Builder para abrir una ventana de prueba. Hazle preguntas reales de tu día a día, detecta dónde falla, ajusta el system prompt o el conocimiento, y vuelve a probar. Iterar es normal: un agente se afina probándolo.
### Define la visibilidad y guarda [#define-la-visibilidad-y-guarda]
Elige quién puede usar el agente (personal, compartido o acceso externo) y guarda. Si lo compartes, aparece para el resto del equipo.
Antes de añadir archivos o habilidades, invierte el tiempo en describir bien el rol en el system prompt.
***
## El modelo: con qué piensa el agente [#el-modelo-con-qué-piensa-el-agente]
El modelo es el motor de razonamiento. El selector te deja elegir entre tres ejes:
* **Proveedor**: la empresa que ofrece el modelo de IA.
* **Nivel**: el escalón de capacidad y coste, de económico a premium. Más nivel significa respuestas más capaces, pero más lentas y caras.
* **Ventana de contexto**: cuánta información cabe de una vez en la conversación (el historial, los archivos adjuntos y el conocimiento recuperado). A más ventana, más documentación maneja el agente sin perder el hilo.
Por cada modelo verás su capacidad y su coste relativo para que compares antes de elegir.
| Si tu agente… | Elige un modelo… |
| ------------------------------------------ | --------------------------------------------- |
| Hace tareas repetitivas y de alto volumen | Económico y rápido (ahorras en cada consulta) |
| Resuelve la mayoría de casos del día a día | El nivel por defecto |
| Toma decisiones críticas o analiza a fondo | Premium, de razonamiento |
| Procesa documentos muy largos | El de mayor ventana de contexto |
→ [Chatear con agentes](/docs/rtg/ia/chat-y-agentes)
***
## Archivos de conocimiento [#archivos-de-conocimiento]
Los archivos de conocimiento son los documentos que el agente conoce y consulta para responder. Súbelos cuando quieras que tu agente domine información propia de tu empresa, como:
* Manuales de procedimientos internos.
* Catálogos de productos o servicios.
* Preguntas frecuentes históricas.
* Normativa o políticas internas.
**Cómo funciona por dentro:** cada documento se trocea en fragmentos pequeños y se indexa por significado. Cuando preguntas algo, el agente recupera solo los fragmentos relevantes y los usa como contexto para responder. No relee el documento entero cada vez, busca lo que encaja con tu pregunta.
Formatos admitidos: **PDF, DOCX, TXT, MD y CSV**.
***
## Habilidades [#habilidades]
Las **habilidades** son mini-prompts reutilizables: instrucciones concretas que el agente sabe ejecutar cuando se lo pides. En lugar de explicarle la tarea cada vez, la defines una vez y la invocas siempre que la necesites.
Ejemplos típicos:
* **Resumir un cliente**: el agente sabe qué información consultar y cómo presentarla.
* **Redactar un email de cobro**: usa el tono que definiste y la firma corporativa.
* **Analizar un KPI mensual**: sabe qué métricas mirar y cómo interpretarlas.
Una habilidad bien definida ahorra repetir instrucciones y hace que el agente responda de forma consistente.
***
## La memoria del agente [#la-memoria-del-agente]
Conforme trabajas con un agente, este acumula memoria. Se organiza en dos capas que puedes consultar y editar desde la pestaña **Memorias** dentro del chat.
### Memoria consciente [#memoria-consciente]
Lo que el agente "sabe" de forma explícita y estructurada:
* Las **habilidades** que le has definido.
* Los **archivos de conocimiento** que le has subido.
* Los **perfiles** de las personas con las que ha hablado: con el uso, el agente aprende tus preferencias, tu contexto y tu estilo (por ejemplo, que prefieres respuestas cortas).
### Memoria subconsciente [#memoria-subconsciente]
Los **fragmentos indexados semánticamente** que el agente recupera por significado cuando responde. Es la memoria de fondo: no la lees como una lista de hechos, sino que el agente la consulta sola al buscar lo relevante para tu pregunta.
### Panel de memoria [#panel-de-memoria]
Desde la pestaña **Memorias** tienes:
* **Estadísticas** de lo que recuerda (habilidades, archivos, perfiles y volumen indexado).
* Un **buscador** para encontrar cualquier cosa que el agente haya memorizado.
* La opción de **editar o borrar fragmentos concretos**, o de limpiar toda la memoria de golpe.
La memoria es editable. Si el agente ha aprendido algo erróneo o desactualizado, búscalo en el panel y bórralo. No tienes que empezar de cero.
***
## Visibilidad: quién puede usar el agente [#visibilidad-quién-puede-usar-el-agente]
Al guardar decides el alcance del agente:
| Visibilidad | Quién lo usa | Para qué |
| ------------------ | ----------------------------- | ----------------------------------------- |
| **Personal** | Solo tú | Un asistente a tu medida, privado |
| **Compartido** | Todo tu equipo | Un experto común para toda la empresa |
| **Acceso externo** | Aplicaciones externas vía API | Integrar el agente en tu web o app propia |
Empieza en **personal** mientras lo afinas y, cuando esté listo, súbelo a **compartido** para que lo use el equipo. El **acceso externo** te permite ofrecer la experiencia del agente fuera de Dinaup, conectándolo desde tus propios sistemas.
Un agente compartido respeta siempre los permisos de cada persona: si un usuario no puede ver cierta información en Dinaup, el agente tampoco se la mostrará. La IA hereda tus permisos, no los amplía.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El system prompt define quién es el agente y cómo se comporta (su rol, tono y reglas). Los archivos de conocimiento son la información que consulta para responder (manuales, catálogos, FAQs). Uno es la personalidad, el otro es la documentación.
No. Hay un modelo por defecto que cubre la mayoría de los casos. Solo cambias de modelo si necesitas más capacidad, más velocidad, menos coste o una ventana de contexto mayor.
PDF, DOCX, TXT, MD y CSV. Cada documento se trocea e indexa por significado para que el agente recupere solo los fragmentos relevantes al responder.
Sí. Desde la pestaña Memorias del chat puedes buscar y borrar fragmentos concretos, o limpiar toda la memoria. La memoria consciente y la subconsciente son editables.
Al guardar, cambia su visibilidad a Compartido. Aparecerá para todo el equipo. Si en su lugar eliges Acceso externo, podrás usarlo desde aplicaciones externas vía API.
***
→ [Chatear con agentes](/docs/rtg/ia/chat-y-agentes)
→ [Herramientas de IA](/docs/rtg/ia/herramientas)
→ [Clasificadores automáticos](/docs/rtg/ia/clasificadores)
# Cuotas y permisos (/docs/rtg/ia/cuotas-y-permisos)
La IA de Dinaup consume recursos cada vez que trabaja, y accede a tus datos para responderte. Dinaup te da el control total sobre las dos cosas: cuánto se gasta cada persona y qué puede ver la IA. Como administrador decides el presupuesto, supervisas el consumo y, si lo necesitas, la apagas entera o por secciones.
***
## Cuota semanal por usuario [#cuota-semanal-por-usuario]
Cada usuario tiene un límite de gasto en euros por semana para la IA. Ese límite lo defines tú como administrador: marcas un presupuesto sensato según el uso que esa persona hace de la IA. Al terminar la semana, el contador se reinicia.
La cuota es **por usuario**, no por empresa. Así un perfil que apenas usa la IA no consume el presupuesto de quien la exprime a diario, y puedes ajustar a cada uno según su rol.
La cuota acota el gasto de la IA, no el de Dinaup. Facturar, vender o consultar informes nunca depende de tu cuota de IA.
### Definir la cuota [#definir-la-cuota]
### Abre la configuración de IA [#abre-la-configuración-de-ia]
Ve a **Configuración → IA** desde el panel de administración. Ahí está el apartado de **Cuotas**.
### Asigna un presupuesto semanal [#asigna-un-presupuesto-semanal]
Define cuántos euros por semana puede consumir cada usuario en IA. Empieza con un presupuesto holgado y ajústalo cuando veas el consumo real en el panel de uso.
### Revisa y reajusta [#revisa-y-reajusta]
La cuota no es definitiva. Si una persona se queda corta o le sobra mucho, vuelve aquí y cámbiala. Los cambios aplican desde ese momento.
***
## Panel de uso [#panel-de-uso]
Para saber dónde se va el dinero, abre la pestaña **Uso** desde cualquier chat con la IA. Ahí ves el consumo de forma transparente, en euros reales:
* **Consumo de la semana**: cuánto llevas gastado sobre tu cuota.
* **Por modelo**: cuánto se va en cada modelo de IA. Los modelos más potentes cuestan más por consulta que los rápidos.
* **Por módulo**: cuánto gastas en cada parte de Dinaup: leer facturas, sugerencias del CRM, chat con agentes, clasificadores de texto…
* **Histórico**: la evolución del gasto a lo largo del tiempo.
Este desglose te dice exactamente dónde merece la pena la IA y dónde no. Si ves que un módulo se lleva mucho presupuesto, decides si compensa o si conviene moderar su uso.
Elegir bien el modelo es la palanca más directa para controlar el coste. Un modelo rápido para tareas simples ahorra mucho frente a uno potente. → [Casos de uso por módulo](/docs/rtg/ia/casos-por-modulo)
***
## Avisos y bloqueo al agotar la cuota [#avisos-y-bloqueo-al-agotar-la-cuota]
La IA no te deja tirado sin avisar. Conforme te acercas al límite, recibes una alerta para que no te pille por sorpresa. Si llegas al tope, las acciones de IA se bloquean hasta la siguiente semana o hasta que el administrador amplíe tu cuota.
Lo importante: **solo se bloquea la IA**. El resto de Dinaup sigue funcionando con total normalidad.
| Situación | Qué ocurre |
| -------------------- | ---------------------------------------------------------------- |
| Te acercas al límite | Aviso de que estás cerca de agotar la cuota |
| Agotas la cuota | Las acciones de IA quedan bloqueadas |
| Resto de Dinaup | Facturación, ventas, CRM, RRHH… siguen funcionando igual |
| Recuperar la IA | Esperar al reinicio semanal o pedir al admin que amplíe la cuota |
***
## La IA hereda tus permisos [#la-ia-hereda-tus-permisos]
Esta es la regla de oro de la seguridad: **la IA ve exactamente lo que ve tu usuario, ni más ni menos**. No hay puerta trasera ni escalada de privilegios.
Si tu usuario no tiene acceso a las nóminas, la IA tampoco puede consultarlas, ni cuando se lo pides directamente. La IA opera siempre dentro de tus permisos, igual que si tú mismo navegaras por Dinaup.
No tienes que configurar nada para esto. Los permisos que ya tiene cada usuario son los que respeta la IA.
Esto significa que el control de acceso que ya gestionas en Dinaup vale también para la IA. No hay un segundo sistema de permisos que mantener: hay uno solo, el de siempre.
***
## Desactivar la IA [#desactivar-la-ia]
Si tu empresa no quiere usar la IA, o quiere acotar dónde aparece, puedes apagarla. La IA es completamente opcional y desactivable.
* **Apagar toda la empresa**: desde **Configuración → IA**, desactivas la IA por completo. Desaparecen todas las acciones de IA para todos los usuarios. Reactivable en cualquier momento.
* **Apagar por secciones**: si solo te preocupan ciertas áreas (por ejemplo, datos especialmente sensibles), desactivas la IA únicamente en esas secciones y la mantienes en el resto.
Desactivar la IA no borra nada ni afecta a tus datos. Solo retira las funciones de IA. Cuando vuelvas a activarla, todo sigue donde estaba.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. La cuota solo limita el gasto de la IA. Aunque la agotes, sigues facturando, vendiendo y usando cualquier otro módulo con normalidad.
Recibe avisos al acercarse al límite y, al agotarla, las acciones de IA se bloquean hasta el reinicio de la semana siguiente o hasta que el administrador amplíe su cuota. El resto de Dinaup no se ve afectado.
No. La IA hereda exactamente tus permisos. Si no tienes acceso a una sección, la IA tampoco, aunque se lo pidas directamente.
Sí. Puedes apagar la IA para toda la empresa o solo en las secciones que elijas, y dejarla activa en el resto.
El administrador, desde Configuración → IA. La cuota es por usuario, así que puedes ajustarla al uso de cada perfil.
***
→ [IA en Dinaup](/docs/rtg/ia)
→ [Casos de uso por módulo](/docs/rtg/ia/casos-por-modulo)
# Digitalización de facturas (OCR) (/docs/rtg/ia/digitalizacion-ocr)
La **digitalización** convierte una factura de compra en datos estructurados sin teclear nada. Subes la factura como foto o PDF y la IA extrae el **proveedor**, la **fecha**, la **base imponible**, el **IVA** y las **líneas**. Con todo ello prepara un **gasto** listo para guardar en [Compras y gastos](/docs/rtg/pymes/facturacion/compras).
En lugar de transcribir cada importe a mano, la IA hace la lectura y tú revisas y confirmas.
***
## Qué extrae la IA [#qué-extrae-la-ia]
De cada factura, la IA intenta reconocer:
| Dato | Qué reconoce |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| **Proveedor** | Nombre y, si aparece, el NIF/CIF. Si ese proveedor ya existe en tu ficha, lo asocia; si es nuevo, te lo marca para darlo de alta. |
| **Fecha** | La fecha de la factura. |
| **Base imponible** | El importe sin impuestos. |
| **IVA** | El tipo y la cuota de impuesto aplicados. |
| **Líneas** | El desglose de conceptos cuando la factura los detalla. |
| **Total** | El importe final a pagar. |
La IA **lee** la factura; tú **confirmas**. Antes de guardar el gasto, revisa que los importes y el proveedor son correctos. Si algún dato no se ha reconocido bien (una foto borrosa, un formato raro), lo corriges en pantalla antes de aceptar.
***
## Subir una factura [#subir-una-factura]
### Abre la digitalización [#abre-la-digitalización]
Entra en la sección de **IA → Digitalización** y elige subir una factura nueva.
### Adjunta la foto o el PDF [#adjunta-la-foto-o-el-pdf]
Sube el archivo de la factura: una **foto** hecha con el móvil, una imagen escaneada o un **PDF**. Acepta los formatos habituales de imagen y documento.
### Deja que la IA la lea [#deja-que-la-ia-la-lea]
La IA analiza el documento y extrae proveedor, fecha, base, IVA y líneas. Es un proceso de unos segundos por factura; verás el indicador mientras trabaja.
### Revisa y pasa a Gastos [#revisa-y-pasa-a-gastos]
Comprueba los datos propuestos, ajusta lo que haga falta y confirma. La factura se convierte en un **gasto** en [Compras y gastos](/docs/rtg/pymes/facturacion/compras/gestion-de-compras-y-gastos), con su proveedor, importes e IVA ya rellenos.
***
## Carga individual o por lotes [#carga-individual-o-por-lotes]
Puedes digitalizar de dos maneras, según cuántas facturas tengas delante:
* **Individual**: subes una factura, la revisas y la conviertes en gasto. Ideal cuando llega una factura suelta.
* **Por lotes**: subes varias facturas a la vez y la IA las va procesando una tras otra. Pensado para vaciar de golpe la carpeta de facturas pendientes del mes.
En ambos casos el resultado es el mismo: cada factura procesada queda lista para revisar y pasar a gastos.
Sube las facturas con buena calidad. Una imagen nítida, recta y completa (que se vean los importes y el NIF) hace que la IA acierte más y tú corrijas menos.
***
## El proveedor: existente o nuevo [#el-proveedor-existente-o-nuevo]
Cuando la IA reconoce el proveedor de la factura, comprueba si ya lo tienes:
* Si el **proveedor ya existe** en tu ficha (por NIF o por nombre), la factura se asocia a él directamente.
* Si es un **proveedor nuevo**, la IA te lo señala para que decidas darlo de alta. Así no se te duplican proveedores ni se cuelan gastos sin asignar.
De esta forma, según vas digitalizando, tu lista de proveedores y tus gastos quedan conectados sin trabajo extra.
***
## Relación con Compras y gastos [#relación-con-compras-y-gastos]
La digitalización es la **puerta de entrada por IA** a los gastos de compra. El gasto que genera es un gasto normal y corriente. Una vez creado, vive en [Compras y gastos](/docs/rtg/pymes/facturacion/compras) como cualquier otro, con su proveedor, su base, su IVA y su total. Puedes editarlo, asignarle categoría y darle el mismo tratamiento que a un gasto introducido a mano.
La diferencia es el punto de partida: en vez de empezar con un formulario en blanco, empiezas con un formulario ya relleno a partir de la factura real.
→ [Compras y gastos](/docs/rtg/pymes/facturacion/compras/gestion-de-compras-y-gastos)
***
## Preguntas frecuentes [#preguntas-frecuentes]
Fotos (imagen) y PDF. Sirve una foto hecha con el móvil, un escaneo o el PDF que te manda el proveedor. Cuanto más nítida y completa sea la imagen, mejor lee la IA.
No. La IA extrae los datos y los propone; tú revisas y confirmas antes de guardar el gasto. Siempre tienes la última palabra sobre los importes y el proveedor.
Sí. Además de la carga individual, puedes subir un lote de facturas y la IA las procesa una por una. Es la forma rápida de pasar todas las facturas pendientes del mes.
La IA te lo marca como proveedor nuevo para que lo des de alta. Si ya existe (lo reconoce por NIF o nombre), asocia la factura al proveedor que ya tienes, sin duplicarlo.
Lo corriges en pantalla antes de confirmar. La digitalización te ahorra teclear, pero la revisión final es tuya: ajustas cualquier dato que no haya salido bien y luego guardas.
***
→ [Casos de uso de la IA por módulo](/docs/rtg/ia/casos-por-modulo)
→ [Compras y gastos](/docs/rtg/pymes/facturacion/compras)
→ [IA en Dinaup](/docs/rtg/ia)
# Explorador de agentes (/docs/rtg/ia/explorador-de-agentes)
El **Explorador de agentes** es tu catálogo de IA: el sitio donde ves todos los agentes que ya puedes usar y arrancas una conversación. Antes de crear un agente desde cero, pasa por aquí: el que necesitas puede existir ya, o puede haber una plantilla predefinida que te sirva de punto de partida.
Cada agente se abre en una **ventana flotante**, así que puedes seguir trabajando con la pantalla de detrás mientras conversas.
***
## Para qué sirve [#para-qué-sirve]
El Explorador resuelve una pregunta concreta: **"¿qué agentes tengo disponibles ahora mismo y cuál uso?"**. Es la puerta de entrada al chat de IA cuando no quieres configurar nada, solo ponerte a trabajar.
Te conviene pasar por aquí cuando:
* Quieres **chatear con un agente ya hecho** sin abrir el Builder ni definir nada.
* Buscas un **agente de tu empresa** pensado para una tarea concreta (contabilidad, ventas, soporte…).
* Alguien de tu equipo **te ha compartido** un agente y quieres usarlo.
* Quieres **partir de una plantilla** en lugar de empezar con una página en blanco.
Si lo que quieres es montar un agente a tu medida (con su rol, su conocimiento y sus habilidades), ese es trabajo del Builder. El Explorador es para **usar** agentes; el Builder, para **crearlos**.
→ [Crear un agente](/docs/rtg/ia/crear-agente)
***
## Cómo están organizados los agentes [#cómo-están-organizados-los-agentes]
El Explorador agrupa los agentes que tienes a tu alcance en bloques claros, para que encuentres rápido el que buscas. Cada agente se muestra como una **tarjeta** con su avatar, su nombre y un botón para chatear.
| Grupo | Qué contiene | De dónde salen |
| ----------------------- | ----------------------------------------------- | ------------------------------------------------------ |
| **Mis agentes** | Los agentes personales que tú has creado | Los hiciste tú en el Builder, con visibilidad personal |
| **Agentes de empresa** | Agentes compartidos para todo el equipo | Alguien los creó y los marcó como compartidos |
| **Compartidos conmigo** | Agentes a los que te han dado acceso individual | Otra persona (o una app externa) te concedió permiso |
Algunas tarjetas de la sección **Compartidos conmigo** llevan una marca extra que indica su naturaleza:
* **Externo**: el agente vive en una aplicación de fuera de Dinaup y se conecta vía API. Lo usas igual, pero su lógica no la controlas tú.
* **Admin**: tienes permisos de administración sobre ese agente, no solo de uso.
Si una sección no aparece, es que aún no tienes agentes de ese tipo. Por ejemplo, **Mis agentes** estará vacío hasta que crees el primero en el Builder.
***
## Encontrar el agente que necesitas [#encontrar-el-agente-que-necesitas]
Recorre los grupos y fíjate en el **avatar, el nombre y la descripción** de cada tarjeta: están pensados para que sepas de inmediato qué hace cada agente. Un buen nombre y una buena descripción son justo lo que evita que tengas que abrir el agente para averiguar si te sirve.
Si eres tú quien crea agentes para el equipo, ponles **nombres claros y descripciones útiles**. Es lo que hace que el resto los encuentre y los use en el Explorador sin preguntarte.
***
## Empezar a usar un agente [#empezar-a-usar-un-agente]
Una vez localizado el agente, arranca la conversación.
### Abre el Explorador [#abre-el-explorador]
Ve a **IA → Explorador de agentes**. Verás tus agentes organizados por grupos.
### Elige un agente [#elige-un-agente]
Localiza la tarjeta del agente que encaja con lo que necesitas. Apóyate en su nombre y su descripción para decidir.
### Pulsa **Chat** [#pulsa-chat]
El botón **Chat** de la tarjeta abre el agente en una **ventana flotante**. La pantalla de detrás se queda donde estaba, así que no pierdes el contexto de lo que estabas haciendo.
### Conversa y deja que proponga [#conversa-y-deja-que-proponga]
Escríbele en lenguaje natural. El agente consulta los datos a los que **tú** tienes acceso y te propone acciones que confirmas tú.
→ [Chatear con agentes](/docs/rtg/ia/chat-y-agentes)
***
## Partir de una plantilla [#partir-de-una-plantilla]
Además de los agentes ya configurados, el Explorador te ofrece **plantillas predefinidas**: agentes de arranque listos para usar tal cual o para copiar y adaptar a tu negocio. Te ahorran la página en blanco: en vez de pensar un agente desde cero, parte de uno que ya hace algo parecido a lo que buscas y ajústalo en el Builder.
Úsalas cuando no sepas por dónde empezar o cuando una plantilla cubra casi del todo tu caso y solo necesites afinarla.
***
## El Explorador y tus permisos [#el-explorador-y-tus-permisos]
Reutilizar un agente **no salta ninguna barrera de seguridad**. Da igual quién creó el agente: cuando chateas con él, **hereda tus permisos exactos**. Solo consulta y muestra la información que tu usuario ya puede ver en Dinaup. Un agente de empresa o uno compartido contigo no te da acceso a datos que no te corresponden.
Que un agente esté disponible en tu Explorador no significa que veas más de lo que verías tú normalmente. La IA opera siempre dentro de tus permisos, nunca por encima de ellos.
→ [Cuotas y permisos de IA](/docs/rtg/ia/cuotas-y-permisos)
***
## Preguntas frecuentes [#preguntas-frecuentes]
El Explorador es para usar agentes ya existentes: los encuentras y chateas con ellos. El Builder es para crearlos y configurarlos (rol, conocimiento, habilidades, visibilidad). Si solo quieres ponerte a trabajar, vas al Explorador; si quieres montar un agente a tu medida, al Builder.
Porque aún no has creado ningún agente personal. En cuanto crees el primero en el Builder con visibilidad personal, aparecerá en esa sección del Explorador.
Que ese agente vive en una aplicación de fuera de Dinaup y se conecta vía API. Lo usas igual desde el chat, pero su configuración y su lógica no las controlas tú.
No. Cualquier agente que abras hereda tus permisos exactos. Consulta únicamente la información a la que tu usuario ya tiene acceso, sin importar quién creó el agente.
Las dos cosas. Puedes chatear con una plantilla directamente o usarla como punto de partida y adaptarla a tu negocio en el Builder antes de ponerla a trabajar.
***
→ [Chatear con agentes](/docs/rtg/ia/chat-y-agentes)
→ [Crear un agente](/docs/rtg/ia/crear-agente)
→ [Volver a IA](/docs/rtg/ia)
# Herramientas de IA (/docs/rtg/ia/herramientas)
Las herramientas de IA son acciones rápidas y de un solo uso que aplicas directamente sobre el campo en el que estás trabajando. No necesitas crear un [agente](/docs/rtg/ia/crear-agente) ni abrir un chat: aparecen donde hacen falta (un campo de texto largo, un campo de imagen, un buscador) y resuelven una tarea concreta sobre la marcha.
Piensa en ellas como el menú contextual de la IA: seleccionas qué quieres (corregir, traducir, generar una imagen…), la IA lo hace y tú decides si te quedas con el resultado. Igual que con todo en Dinaup, **la IA propone y tú confirmas**.
Las herramientas sueltas consumen cuota de IA, pero mucho menos que una conversación con un agente: son acciones puntuales y cortas. Si tu empresa tiene la IA desactivada, estas herramientas no aparecen.
***
## Texto [#texto]
En cualquier campo de texto largo (descripciones, notas, comentarios, comunicaciones) aparece una barra flotante con asistencia de IA. Seleccionas la acción y la IA reescribe o analiza el contenido.
| Herramienta | Qué hace |
| -------------------------- | ---------------------------------------------------------------------------------------------- |
| **Corregir** | Arregla ortografía y gramática sin cambiar el sentido. |
| **Resumir** | Condensa el texto en una versión más corta. |
| **Expandir** | Desarrolla las ideas y añade más detalle. |
| **Cambiar tono** | Reescribe en el registro que elijas: formal, informal, profesional, cercano, directo o amable. |
| **Traducir** | Pasa el texto a otro idioma. |
| **Extraer palabras clave** | Saca las ideas principales como una lista de keywords. |
| **Redactar email** | Convierte unas notas o bullets sueltos en un email completo y listo para enviar. |
Antes de aplicar el cambio, ves una **comparación visual** del antes y el después, para que apruebes el resultado con conocimiento de causa en lugar de a ciegas.
**Redactar email** es ideal para responder rápido: escribe tres o cuatro ideas en bruto ("confirmar pedido, disculpa por retraso, nuevo plazo viernes") y deja que la IA arme el correo con cuerpo y cierre. Tú lo revisas y lo envías.
***
## Imagen [#imagen]
En los campos de imagen (avatares, fotos de producto, banners) la IA te ayuda a crear y arreglar imágenes sin salir de Dinaup ni abrir un editor externo.
| Herramienta | Qué hace |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| **Generar desde prompt** | Describes la imagen que quieres ("logo minimalista de una cafetería urbana") y la IA la crea. El tamaño es configurable. |
| **Quitar fondo** | Recorta el sujeto y devuelve una imagen con fondo transparente, lista para montar sobre cualquier color. |
| **Auto-mejorar** | Optimiza nitidez y color de una imagen existente. |
| **Sugerir icono** | A partir de una descripción, la IA propone el icono que mejor la representa. |
**Generar desde prompt** sirve también para crear el avatar de un agente: describe el personaje y usa la imagen resultante como su cara. Lo tienes a un paso al [crear un agente](/docs/rtg/ia/crear-agente).
***
## Voz [#voz]
Cuando rellenar un campo escribiendo es incómodo (notas largas, comentarios sobre la marcha), la voz es el atajo. Disponible en campos de texto largo.
* **Dictado (voz a texto)**: pulsas el micrófono, hablas y la IA transcribe lo que dices al campo. El idioma es configurable. Perfecto para anotar mientras te mueves.
* **Texto a voz**: la IA lee en alto el contenido del campo, útil para revisar un texto sin tener que mirarlo.
***
## Búsqueda inteligente [#búsqueda-inteligente]
En lugar de montar filtros a mano, describes en lenguaje natural lo que buscas y la IA lo traduce a los filtros correspondientes.
* **Búsqueda en lenguaje natural**: escribes algo como *"ventas de mayo por encima de 1000 del cliente ACME"* y la IA interpreta la frase y aplica los filtros de fecha, importe y cliente por ti.
* **Autocompletar**: mientras escribes, la IA sugiere opciones contextuales para terminar antes.
Es la forma más rápida de llegar a un dato concreto cuando sabes qué quieres pero no por dónde empezar a filtrar.
***
## Generación [#generación]
Atajos para producir contenido a partir de algo que ya tienes, sin redactarlo desde cero.
| Herramienta | Qué hace |
| --------------------- | ---------------------------------------------------------------------- |
| **Título** | Propone un título claro y pegadizo para un artículo, producto o email. |
| **Resumen ejecutivo** | Destila un documento largo en sus puntos esenciales. |
| **Icono sugerido** | Recomienda el icono que encaja con el contenido que estás creando. |
***
## Utilidades [#utilidades]
La pantalla de Herramientas incluye además dos utilidades que no consumen IA:
* **Generador de QR**: crea un código QR a partir del texto o la URL que escribas.
* **Generador de contraseñas**: produce una contraseña aleatoria lista para copiar.
***
## Cuándo usar una herramienta y cuándo un agente [#cuándo-usar-una-herramienta-y-cuándo-un-agente]
Las herramientas sueltas y los agentes resuelven cosas distintas. Esta es la regla rápida:
| Usa una herramienta suelta cuando… | Usa un [agente](/docs/rtg/ia/crear-agente) cuando… |
| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| Quieres una acción puntual sobre un campo (corregir, traducir, generar una imagen). | Necesitas una conversación, con contexto e ida y vuelta. |
| No hace falta memoria ni conocimiento previo. | El asistente debe recordar archivos, datos o conversaciones anteriores. |
| Es algo que resuelves en un clic y sigues. | La tarea encadena varios pasos o consulta tus datos. |
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Las herramientas sueltas están disponibles directamente en los campos donde hacen falta (texto, imagen, búsqueda) sin configurar nada. Los agentes son para conversaciones con contexto y memoria.
Sí, pero mucho menos que un chat con un agente, porque son acciones cortas y puntuales. Puedes consultar tu consumo en cualquier momento.
No. En las herramientas de texto ves una comparación del antes y el después y eres tú quien decide si aceptas el cambio.
Sí. El dictado tiene idioma configurable, así que transcribe en el idioma que selecciones.
Si tu empresa tiene la IA desactivada, las herramientas no aparecen. Pídele a tu administrador que la active.
***
→ [Crear un agente](/docs/rtg/ia/crear-agente)
→ [Casos de uso por módulo](/docs/rtg/ia/casos-por-modulo)
# IA en Dinaup (/docs/rtg/ia)
La IA de Dinaup es un **copiloto** integrado en tu día a día: clasifica, redacta textos, lee documentos y sugiere el siguiente paso. Te propone; tú revisas y confirmas. Es una capa opcional sobre el resto de Dinaup (Pymes, CRM, TPV, RRHH, Proyectos) que el administrador puede apagar por empresa.
***
## Principios [#principios]
| Principio | Qué significa |
| ----------------------------- | ------------------------------------------------------------------------------- |
| **La IA sugiere, tú decides** | Nunca cierra una factura, envía un email ni cambia un dato sin tu confirmación. |
| **Transparencia** | Antes de aceptar ves qué va a hacer, con qué datos y con qué modelo. |
| **Siempre desactivable** | Se apaga por empresa y se reactiva cuando quieras. |
***
## El Hub de IA [#el-hub-de-ia]
Toda la IA vive en un único sitio: **Apps → IA**. Es el centro desde donde chateas, creas asistentes y usas herramientas. Se organiza en cuatro zonas:
| Zona | Para qué sirve |
| ------------ | --------------------------------------------------------------------------------------------------------------------------- |
| **Explorer** | Agentes listos para usar y plantillas predefinidas. El punto de partida si solo quieres empezar a chatear. |
| **Builder** | El taller donde creas tus propios agentes: les das personalidad, conocimiento y habilidades. |
| **Tools** | Herramientas sueltas que no necesitan agente: corregir texto, generar imágenes, dictar por voz, buscar en lenguaje natural. |
| **History** | El historial de todas tus conversaciones, buscable por palabra clave para no repetir lo que ya preguntaste. |
***
## La IA hereda tus permisos [#la-ia-hereda-tus-permisos]
Este es el punto clave de seguridad: **la IA ve exactamente lo que tú ves, ni más ni menos.**
Si tu usuario no tiene acceso a las nóminas, la IA tampoco las consulta. No existe escalada de privilegios: la IA opera siempre con tu perfil, dentro de tus mismos límites de acceso. Cuando una acción modifica datos, lo normal es que te muestre el cambio en un formulario para que lo confirmes antes de grabar.
→ [Cuotas y permisos](/docs/rtg/ia/cuotas-y-permisos)
***
## Tres niveles de modelo [#tres-niveles-de-modelo]
No todas las tareas necesitan la misma potencia. Al chatear eliges entre tres niveles, equilibrando rapidez, capacidad y coste:
| Nivel | Cuándo usarlo |
| --------------- | ----------------------------------------------------------------------------------------------- |
| **Rápido** | Preguntas simples, clasificar o resumir algo corto. Es el más ágil y el más barato. |
| **Equilibrado** | El punto de partida para casi todo. Cubre la gran mayoría de los casos del día a día. |
| **Razonador** | Decisiones complejas, análisis profundo o redacciones críticas. Más pausado, pero el más capaz. |
Empieza por **Equilibrado**. Si se queda corto o se equivoca, sube a **Razonador**. Si haces tareas repetitivas en masa, baja a **Rápido** para ahorrar.
Si quieres afinar más, hay un selector avanzado donde eliges el modelo concreto comparando su capacidad, su coste y la cantidad de información que admite.
***
## Explora el módulo [#explora-el-módulo]
Conversa con los agentes del Explorer en una ventana flotante mientras sigues trabajando.
Usa el Builder para diseñar tu propio asistente con personalidad, conocimiento y habilidades.
Texto, imagen, voz y búsqueda inteligente, disponibles sin necesidad de crear un agente.
Etiquetas que se rellenan solas (sentimiento, urgencia, idioma…) en cualquier campo de texto.
Cómo se hereda el acceso, cómo se controla el gasto y cómo se activa o desactiva la IA.
Dónde brilla la IA en Pymes, CRM, TPV, RRHH y Proyectos, con ejemplos concretos.
***
## Consumo de cuota [#consumo-de-cuota]
Cuando la IA está activa, su uso consume cuota: cada usuario tiene un límite de gasto que el administrador define, visible en todo momento. Al alcanzar el límite, las acciones de IA se pausan hasta el siguiente periodo; el resto de Dinaup sigue funcionando.
→ [Cuotas y permisos](/docs/rtg/ia/cuotas-y-permisos)
# Panel de uso (/docs/rtg/ia/panel-de-uso)
El **panel de uso** es donde ves, en euros reales, cuánto consume la IA. Es la pantalla de inicio de **Apps → IA**: cada vez que entras al hub, lo primero que aparece es tu consumo de la semana y el histórico. Sin estimaciones ni unidades raras: euros, igual que en cualquier factura.
Complementa a la página de [cuotas y permisos](/docs/rtg/ia/cuotas-y-permisos): allí el administrador **fija** el presupuesto; aquí cualquiera **ve** cómo se gasta.
***
## Qué ves al entrar [#qué-ves-al-entrar]
El panel tiene dos bloques, de arriba abajo:
* **Cuota semanal**: tu consumo de la semana en curso frente a tu límite. Solo aparece si tu empresa tiene una cuota definida.
* **Histórico**: el consumo a lo largo del periodo que elijas, con totales y desglose.
Lo que ves depende de tu rol. Un usuario normal ve **su** consumo. Un administrador ve además el de **todo el equipo**.
***
## Tu cuota de la semana [#tu-cuota-de-la-semana]
En la parte de arriba, una barra te dice cómo vas:
* **Tu consumo**: cuántos euros llevas gastados esta semana.
* **De \[tu límite]**: el tope que el administrador te ha asignado.
* **% utilizado** y **disponible**: lo consumido en porcentaje y los euros que te quedan.
La barra **cambia de color** conforme te acercas al tope, así que sabes si vas holgado o apurado sin leer cifras:
| Color de la barra | Qué significa |
| ----------------- | ---------------------------------- |
| Azul | Vas sobrado, consumo bajo |
| Ámbar | Te estás acercando al límite |
| Rojo | Estás muy cerca de agotar la cuota |
La semana aparece identificada con su número y sus fechas (de qué día a qué día), y el contador se reinicia al empezar la siguiente.
Esta barra es tu aviso temprano. Cuando la veas en rojo, modera el uso o pide al administrador que amplíe tu cuota antes de quedarte sin IA. El detalle de qué ocurre al agotarla está en [cuotas y permisos](/docs/rtg/ia/cuotas-y-permisos).
***
## El consumo del equipo [#el-consumo-del-equipo]
Si eres **administrador**, debajo de tu cuota aparece el bloque **Equipo**: la lista de personas que han usado la IA, cada una con su consumo de la semana y su propia barra de progreso. Tu fila se marca con la etiqueta **Yo** para que te localices rápido.
Ahí detectas quién exprime la IA y quién apenas la toca. Eso es justo lo que necesitas para reajustar las cuotas con criterio: si alguien se queda corto cada semana, le subes el presupuesto; si a otro le sobra de largo, lo bajas.
Si el equipo es grande, la lista muestra los primeros y un botón **Más** para cargar el resto.
***
## El histórico [#el-histórico]
Debajo está el **histórico**, donde miras más allá de la semana en curso. Eliges un **rango de fechas** (por defecto, los últimos 30 días) y el panel recalcula todo para ese periodo.
Arriba del todo verás unos indicadores con los totales del periodo:
| Indicador | Qué cuenta |
| ---------------- | ------------------------------------------------------------------ |
| **Gasto total** | El coste total en euros de toda la IA en el periodo |
| **Mensajes** | Cuántos mensajes se han intercambiado con la IA |
| **Tokens** | El volumen de texto procesado (la "materia prima" que cobra la IA) |
| **Herramientas** | Cuántas veces se han usado herramientas de IA |
| **Usuarios** | Cuántas personas han usado la IA (solo administradores) |
Bajo los totales, dos pestañas te dan dos lecturas distintas del mismo gasto.
### General: en qué se va el dinero [#general-en-qué-se-va-el-dinero]
La pestaña **General** reparte el gasto **por servicio**, para que veas qué tipo de IA se lleva el presupuesto:
* **Chat IA**: lo que cuesta conversar con los agentes y asistentes.
* **Cada herramienta**: corregir texto, generar imágenes, análisis de documentos y demás [herramientas](/docs/rtg/ia/herramientas) aparecen una a una.
Cada línea muestra su actividad (mensajes o número de usos), el **porcentaje** que representa sobre el total y los **euros** que ha costado. Así sabes si el grueso del gasto está en el chat o en una herramienta concreta.
### Detalle: quién gasta y en qué [#detalle-quién-gasta-y-en-qué]
La pestaña **Detalle** ordena el gasto **por persona**. Cada usuario es una fila con su consumo total y el porcentaje sobre el equipo; tu fila vuelve a marcarse con **Yo**.
Despliega cualquier fila y verás en qué se le ha ido a esa persona:
* **Chat IA**: sus mensajes y los tokens que ha consumido.
* **Herramientas**: cada herramienta que ha usado, con su número de usos.
Todo con su coste en euros al lado.
Como usuario normal, en el histórico solo ves tu propia actividad. Como administrador, ves la de toda la empresa y puedes desglosarla persona a persona.
***
## Cómo se cobra la IA [#cómo-se-cobra-la-ia]
El panel te lo deja claro al pie: **los precios se calculan por operación real**. No hay cuotas fijas ni mínimos: pagas solo por lo que usas. Cada consulta, cada documento leído y cada imagen generada tiene su coste, y eso es lo que ves sumado aquí.
Por eso el panel es tu mejor herramienta para decidir dónde merece la pena la IA. Si un servicio se lleva mucho presupuesto y te aporta poco, lo ves en negro sobre blanco y actúas.
***
## Preguntas frecuentes [#preguntas-frecuentes]
En euros reales. El panel no usa créditos ni unidades abstractas: cada cifra es el coste directo de la IA en ese periodo.
Porque el desglose por equipo y por persona es solo para administradores. Como usuario normal ves tu cuota y tu propia actividad, no la de tus compañeros.
Cada semana. La tarjeta de arriba identifica la semana en curso con sus fechas, y al empezar la siguiente el contador vuelve a cero.
Sí. En el histórico eliges el rango de fechas que quieras y el panel recalcula los totales y el desglose para ese periodo.
Estás cerca del límite semanal. Modera el uso de la IA o pide a tu administrador que amplíe tu cuota. Al agotarla, solo se pausan las acciones de IA; el resto de Dinaup sigue funcionando.
***
→ [Cuotas y permisos](/docs/rtg/ia/cuotas-y-permisos)
→ [IA en Dinaup](/docs/rtg/ia)
# Análisis (/docs/rtg/pymes/analisis)
El módulo de **Análisis** reúne los informes que convierten todo lo que registras en Pymes (facturas, gastos, cobros, pagos) en una foto clara de cómo va el negocio. No tienes que sumar nada a mano: Dinaup calcula los números a partir de tus datos reales y te los muestra listos para leer y decidir.
***
## Para qué sirve [#para-qué-sirve]
Cada informe responde a una pregunta concreta del día a día. Esa es la forma de usarlos: no los mires por mirar, ábrelos cuando tengas una decisión delante.
| Informe | Pregunta que responde | Decisión que apoya |
| ------------------------------------ | ----------------------------------------------------- | ------------------------------------------------------ |
| **Dashboard** | ¿Cómo va el mes ahora mismo? | Detectar a tiempo si vas por debajo del mes anterior |
| **Pérdidas y Ganancias** | ¿Estoy ganando o perdiendo dinero? | Saber si el negocio es rentable y dónde se va el gasto |
| **Balance** | ¿Qué tengo y qué debo a fecha de hoy? | Conocer tu situación patrimonial |
| **Flujos de caja** | ¿Tendré dinero para pagar dentro de 30, 60 o 90 días? | Anticipar tensiones de tesorería |
| **Análisis por cliente / proveedor** | ¿Quién me paga bien y quién me da problemas? | Priorizar cobros y revisar condiciones |
***
## Dashboard [#dashboard]
El **dashboard** es tu pantalla de inicio: un resumen del estado del negocio, pensado para abrirlo cada mañana. Reúne los indicadores que más importan:
* **Facturación del mes** comparada con el mes anterior, para ver la tendencia.
* **Tesorería**: el saldo disponible en tus [cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias) y cajas.
* **Pendiente de cobro frente a pendiente de pago**, para saber cuánto te deben y cuánto debes.
* **Top 10 de clientes y proveedores**, por volumen.
El dashboard se alimenta solo de lo que ya tienes registrado. Si la facturación se ve baja, normalmente es que falta emitir o conciliar algo, no que el negocio vaya mal.
***
## Pérdidas y Ganancias (PyG) [#pérdidas-y-ganancias-pyg]
La **cuenta de resultados** (también llamada **Pérdidas y Ganancias** o **PyG**) responde a la pregunta más importante: *¿el negocio gana o pierde dinero?*
Resta a tus **ingresos** todos los **gastos**, agrupados por categoría, y te da el **resultado** del periodo. Puedes consultarla **mensual o anual** para comparar cómo evoluciona.
Es el informe clave para entender la rentabilidad: no solo cuánto facturas, sino cuánto te queda después de pagar todo. Las categorías te dicen *dónde* se va el dinero, así que asignar bien la categoría a cada gasto en [Facturación](/docs/rtg/pymes/facturacion) es lo que hace que este informe sea útil.
***
## Balance [#balance]
El **balance** es la foto de tu patrimonio **a una fecha concreta**: enfrenta lo que tienes (**activo**) con lo que debes (**pasivo**).
Mientras la PyG mide un periodo (lo que ganaste *durante* un mes), el balance mide un instante (lo que tienes *el* día 30). Los dos se complementan: uno te dice si el negocio es rentable, el otro en qué situación está hoy.
***
## Flujos de caja [#flujos-de-caja]
El informe de **flujos de caja** mira hacia adelante. Proyecta cómo quedará tu tesorería **en 30, 60 y 90 días** suponiendo que todo lo pendiente se cobra y se paga en su fecha prevista.
Es tu sistema de alerta temprana: te avisa de un posible agujero de liquidez **antes** de que ocurra, con tiempo para reaccionar: reclamar un cobro, aplazar un pago o pedir financiación.
La proyección es tan fiable como tus fechas de vencimiento. Mantén al día los cobros y pagos pendientes para que los flujos de caja reflejen la realidad.
***
## Análisis por cliente y proveedor [#análisis-por-cliente-y-proveedor]
Además de la foto global, puedes analizar **una entidad concreta**. Eliges un cliente o un proveedor y Dinaup reúne su historial: cuánto le facturas, su **puntualidad de pago**, la **tendencia** en el tiempo y avisos cuando algo cambia (por ejemplo, un cliente que cada vez tarda más en pagarte).
Sirve para tomar decisiones comerciales con datos: a quién priorizar, a quién reclamar y con quién revisar las condiciones de pago.
***
## Cómo consultar un informe [#cómo-consultar-un-informe]
### Abre el módulo de Análisis [#abre-el-módulo-de-análisis]
Entra en **Pymes → Análisis**. Ahí están el dashboard y el resto de informes de negocio.
### Elige el informe y el periodo [#elige-el-informe-y-el-periodo]
Selecciona el informe que responde a tu pregunta y, si aplica, ajusta el rango de fechas (un mes, un año, una fecha concreta para el balance).
### Lee el dato y actúa [#lee-el-dato-y-actúa]
Cada informe está pensado para apoyar una decisión. Si algo no cuadra, suele ser que falta registrar o [conciliar](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) una operación: los informes solo reflejan lo que ya está en el sistema.
***
## Crea tus propios informes con Flex [#crea-tus-propios-informes-con-flex]
Los informes anteriores cubren las necesidades habituales de cualquier negocio. Si necesitas un análisis a tu medida (con tus filtros, tus agrupaciones y tus columnas calculadas) puedes crearlo tú mismo con **Dinaup Flex**, sin programar.
Flex te permite definir informes nuevos sobre cualquier sección de datos del sistema y reutilizar las mismas tablas que alimentan tu facturación y tu [contabilidad](/docs/rtg/pymes/contabilidad).
→ [Informes con Flex](/docs/desarrollo/flex/informes)
***
## Preguntas frecuentes [#preguntas-frecuentes]
La cuenta de Pérdidas y Ganancias mide un periodo: cuánto ganaste o perdiste durante un mes o un año. El balance mide un instante: qué tienes y qué debes a una fecha concreta. Uno te dice si eres rentable; el otro, cuál es tu situación hoy.
De tus propios datos: las facturas que emites, los gastos que registras y los movimientos que concilias. Dinaup los calcula en tiempo real, así que no hay que cuadrar nada a mano.
Lo más habitual es que falte algo por registrar o conciliar. Los informes solo reflejan lo que ya está en el sistema, así que revisa si tienes facturas sin emitir o movimientos bancarios sin conciliar.
Sí. Con Dinaup Flex defines informes propios con tus filtros, agrupaciones y columnas calculadas, sin programar. Consulta Informes con Flex.
***
→ [Facturación](/docs/rtg/pymes/facturacion)
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
→ [Informes con Flex](/docs/desarrollo/flex/informes)
# Capturas de Pantalla (/docs/rtg/pymes/capturas-de-pantalla)
## Tareas [#tareas]
**Vista general de tareas por proyecto**
En esta pantalla ves todo lo que está pasando en el proyecto: qué tareas están en proceso, cuáles quedan pendientes y cuáles ya se han completado. También tienes a mano las fechas límite, las prioridades y los responsables, para que tengas siempre claro qué se está haciendo y qué viene después.
#### **Acciones rápidas en fechas y prioridades** [#acciones-rápidas-en-fechas-y-prioridades]
Aquí cambias la fecha de vencimiento o la prioridad de una tarea desde el menú. Sirve para reaccionar ante cambios, reorganizar el trabajo y mantener el proyecto en orden.
**Actualización del progreso de la tarea**
Esta vista te deja marcar cuánto avanza una tarea: desde empezar a trabajar en ella hasta completarla. El progreso actualizado te ayuda a seguir cómo va el proyecto.
**Asignación de responsables**
En este punto eliges quién se encarga de cada tarea. Busca a la persona del equipo y asígnala. Así las responsabilidades quedan definidas.
## Pymes [#pymes]
***
#### Exporta en Excel Ventas, Compras y extractos bancarios [#exporta-en-excel-ventas-compras-y-extractos-bancarios]
## Recursos Humanos [#recursos-humanos]
## Área de Empleados [#área-de-empleados]
***
***
El empleado puede ver sus vacaciones y estado
***
Desde el portal de empleado puede editar sus fichajes
***
La edición de fichaje deja un registro para poder auditar los cambios
# Documentos oficiales (/docs/rtg/pymes/documentos-oficiales)
Los **documentos oficiales** son los libros, registros y archivos que tu empresa debe presentar o conservar: libros registro de IVA, su clasificación por tipo de operación, balances, escrituras y cualquier documento clave. Dinaup los genera a partir de los datos que ya tienes (facturas, asientos, movimientos) y te da un sitio único donde guardar el resto.
**No rellenas nada dos veces**: si emites facturas y registras gastos, los libros se construyen solos a partir de esas operaciones.
***
## Qué cubre Dinaup [#qué-cubre-dinaup]
Dinaup parte de tus datos del día a día y los organiza en los registros que la normativa española espera. A grandes rasgos, distingues entre lo que **se genera solo** y lo que **conservas tú**.
| Tipo | Qué es | De dónde sale |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| **Libros registro de venta** | Facturas emitidas agrupadas por tipo de operación (nacionales, simplificadas, intracomunitarias, exportaciones…) | Tus facturas de venta |
| **Libros registro de compra** | Facturas recibidas agrupadas por origen (nacionales, intracomunitarias, importaciones) | Tus facturas de proveedor y gastos |
| **Documentos conservados** | Balances, escrituras, declaraciones ya presentadas, contratos y cualquier archivo oficial | Los subes y archivas tú |
Cada factura entra sola en su libro según el **tipo de venta o de compra** que tenga asignado. No tienes que clasificarlas a mano una a una.
***
## Libros registro de IVA [#libros-registro-de-iva]
Los libros registro son el corazón de la parte fiscal. Agrupan y clasifican tus facturas para la organización contable, la trazabilidad y la exportación de datos.
* Cada **factura emitida** se vincula a un libro de venta según su tipo de operación.
* Cada **factura recibida** se vincula a un libro de compra según su origen.
* Esta clasificación es la que alimenta tus declaraciones de IVA y facilita la deducción del IVA soportado.
Como la vinculación es automática, los libros están **siempre al día**: reflejan lo que has facturado y lo que has recibido.
→ [Libros registro de venta](/docs/rtg/pymes/libros-registros-de-venta)
→ [Libros registro de compra](/docs/rtg/pymes/libros-registros-de-compra)
Los libros se cierran por periodos. El marco temporal lo definen tus [ejercicios contables](/docs/rtg/pymes/ejercicios): un ejercicio de 2025 abarca del 1 de enero al 31 de diciembre.
***
## Cómo se generan y exportan [#cómo-se-generan-y-exportan]
No hay un paso de "crear el libro". El libro **existe en cuanto registras la operación**. El flujo es este:
### Registra tus operaciones [#registra-tus-operaciones]
Emite tus facturas de venta y registra tus compras y gastos con su tipo correspondiente. Cada documento se vincula a su libro en el momento.
### Consulta el libro al día [#consulta-el-libro-al-día]
Abre el libro registro de venta o de compra y verás todas las facturas del periodo ya agrupadas y clasificadas, sin trabajo manual.
### Exporta los datos [#exporta-los-datos]
Desde el libro puedes exportar los datos del periodo para entregárselos a tu asesor o usarlos como base de tu declaración de IVA.
Antes de exportar un periodo, conviene dejarlo cuadrado: sin facturas sin clasificar ni gastos sin categoría. La [contabilidad automática](/docs/rtg/pymes/contabilidad) genera los asientos de venta, compra, pagos y nóminas en bloque para que todo encaje.
***
## Documentos que conservas tú [#documentos-que-conservas-tú]
Más allá de los libros que Dinaup genera, hay documentación oficial que necesitas guardar y tener localizada: **balances, escrituras, declaraciones ya presentadas, contratos** y cualquier archivo relevante de la empresa.
En la sección de Documentos Oficiales **centralizas y organizas** toda esa documentación clave. La tienes en un único sitio, accesible cuando la necesites, y preservada a largo plazo.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Los libros se construyen solos a partir de tus facturas. Cada una entra en su libro según el tipo de venta o de compra que tenga asignado.
Los libros de venta agrupan las facturas que emites (nacionales, simplificadas, intracomunitarias, exportaciones). Los de compra agrupan las facturas que recibes (nacionales, intracomunitarias, importaciones). Cada uno organiza un lado de tu actividad para el control del IVA repercutido y soportado.
Por el periodo que marca tu ejercicio contable. Un ejercicio anual abarca del 1 de enero al 31 de diciembre, y los libros reflejan las operaciones registradas dentro de ese marco.
Sí. Además de los libros que Dinaup genera, la sección de Documentos Oficiales sirve para conservar balances, escrituras, contratos y cualquier documento oficial que quieras tener centralizado y a salvo.
***
→ [Libros registro de venta](/docs/rtg/pymes/libros-registros-de-venta)
→ [Libros registro de compra](/docs/rtg/pymes/libros-registros-de-compra)
→ [Ejercicios](/docs/rtg/pymes/ejercicios)
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
# Ejercicios (/docs/rtg/pymes/ejercicios)
Un **ejercicio** es el periodo (normalmente un año) sobre el que tu empresa acumula toda su actividad contable y fiscal: facturas, asientos, impuestos y amortizaciones. Es el contenedor temporal de las cuentas. Cuando hablas de "las cuentas de 2025", hablas del ejercicio 2025.
Por defecto un ejercicio coincide con el **año natural**: empieza el 1 de enero y termina el 31 de diciembre.
***
## Por qué se trabaja por ejercicio [#por-qué-se-trabaja-por-ejercicio]
La contabilidad y los impuestos no son un flujo infinito: se rinden por periodos. Hacienda pide resultados por año, y tu empresa necesita saber cuánto ganó o perdió en un tramo cerrado de tiempo. El ejercicio es ese tramo.
Trabajar por ejercicio te da tres cosas:
* **Resultados acotados.** Sabes el beneficio, los ingresos y los gastos de un año concreto, sin mezclarlos con los de otros.
* **Documentos oficiales coherentes.** Las declaraciones de impuestos y las cuentas anuales se presentan por ejercicio. Si la contabilidad está bien delimitada, esos documentos salen cuadrados.
* **Comparabilidad.** Puedes mirar un ejercicio frente a otro y ver cómo evoluciona el negocio.
***
## Qué se acumula en un ejercicio [#qué-se-acumula-en-un-ejercicio]
Cada operación que registras cae dentro de un ejercicio según su fecha. A lo largo del año se van sumando:
| Elemento | Qué aporta al ejercicio |
| --------------------------------- | --------------------------------------- |
| **Facturas** de venta y compra | Los ingresos y gastos del periodo |
| **Asientos contables** | El reflejo contable de cada operación |
| **Impuestos** (IVA, retenciones…) | Lo devengado y soportado durante el año |
| **Amortizaciones** | El desgaste anual de tus inmovilizados |
La **fecha** de cada documento decide a qué ejercicio pertenece. Una factura con fecha de diciembre cuenta en el ejercicio de ese año, aunque la cobres en enero del siguiente.
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
***
## Abrir y cerrar un ejercicio [#abrir-y-cerrar-un-ejercicio]
Un ejercicio tiene dos momentos clave en su vida:
* **Apertura.** Al empezar el año entra en juego un nuevo ejercicio, listo para recibir la actividad de ese periodo. Es donde se irán anotando las facturas y los asientos a medida que operas.
* **Cierre.** Al terminar el periodo, el ejercicio se da por cerrado: las cuentas quedan consolidadas y se preparan los documentos oficiales del año. A partir de ahí, ese ejercicio refleja el resultado definitivo del periodo.
El cierre es un proceso contable que normalmente revisas con tu asesor: confirma que todo está registrado y cuadrado antes de dar el año por terminado.
A lo largo del año conviene hacer **revisiones periódicas** (por ejemplo cada trimestre). Sirven para detectar facturas sin cobrar, gastos sin clasificar o movimientos pendientes de conciliar. Llegar al cierre con todo al día evita sorpresas.
***
## Relación con la contabilidad y los documentos oficiales [#relación-con-la-contabilidad-y-los-documentos-oficiales]
El ejercicio es el marco temporal; la **contabilidad** es lo que vive dentro de él. Los asientos, el cuadro de cuentas y el resultado del periodo siempre se entienden referidos a un ejercicio concreto.
De ese ejercicio cerrado salen los **documentos oficiales** del año: declaraciones de impuestos, balances y cuentas anuales. Por eso un ejercicio bien llevado (con su contabilidad al día y sus impuestos cuadrados) es la base para que la documentación oficial sea correcta.
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
→ [Documentos oficiales](/docs/rtg/pymes/documentos-oficiales)
***
## Preguntas frecuentes [#preguntas-frecuentes]
Es el periodo (habitualmente un año) sobre el que se acumulan tus facturas, asientos e impuestos. Funciona como el contenedor de las cuentas de ese año. Por defecto coincide con el año natural (1 de enero a 31 de diciembre).
Porque los resultados y las obligaciones fiscales se rinden por periodos. Acotar la actividad a un año te permite conocer el resultado de ese ejercicio, presentar los documentos oficiales del periodo y comparar un año con otro.
Al ejercicio que corresponde a su fecha. Una factura de diciembre cuenta en el ejercicio de ese año, independientemente de cuándo se cobre.
Dar el periodo por terminado una vez registrada y cuadrada toda la actividad del año. El cierre consolida las cuentas y deja el ejercicio listo para generar los documentos oficiales. Suele revisarse con el asesor.
***
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
→ [Documentos oficiales](/docs/rtg/pymes/documentos-oficiales)
→ [Mi Empresa](/docs/rtg/pymes/mi-empresa)
# Herramientas IA (/docs/rtg/pymes/herramientas-ia)
**Herramientas IA** es un conjunto de utilidades de texto para trabajar con documentos contables y fiscales: contratos, facturas, informes o balances. Pegas un texto y la IA lo procesa, lo resume o le saca las palabras clave.
Llegas desde **Pymes → Más → Ayuda**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La pantalla se organiza en tres pestañas, cada una con su propia caja de texto:
| Pestaña | Qué hace |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| **Editor de texto** | Pega texto de facturas, contratos o documentos contables y aplica acciones de texto sobre él. |
| **Resumir documento** | Pega un documento largo (contrato, informe, balance) y obtienes un resumen de hasta 150 palabras. |
| **Keywords** | Pega un texto y extrae sus palabras clave (hasta ocho). |
Cada herramienta trabaja sobre el texto que pegas en su caja. No leen tus facturas ni tus datos del sistema: procesan el texto que les das.
***
→ [Análisis](/docs/rtg/pymes/analisis)
# Pymes (/docs/rtg/pymes)
Con Ready to Go Pymes emites facturas, registras compras, controlas tesorería e inventario y llevas la contabilidad desde el mismo sitio. El cumplimiento VeriFactu viene integrado.
## Herramientas destacadas [#herramientas-destacadas]
Arrastra tus facturas y gastos. La IA los lee, extrae los datos y los registra en el sistema.
Un email dedicado que recibe documentos y los deja listos para revisar y contabilizar.
Visualiza el estado de tu empresa: ventas, gastos, cobros pendientes y flujo de caja.
Importa extractos bancarios y deja que la IA relacione los movimientos con sus facturas.
Conecta tu cuenta de Stripe y tus ventas online se importan solas al sistema.
Facturación verificable que cumple el Real Decreto 1007/2023.
Envía facturas y presupuestos directamente desde tu propio email corporativo.
Punto de venta para mostrador, hostelería o call center, conectado al mismo inventario y contabilidad.
## Funcionalidades destacadas [#funcionalidades-destacadas]
Emite facturas de venta, registra compras de proveedores y controla tus devengos. El sistema distingue operaciones nacionales, intracomunitarias y exportaciones, y asigna los impuestos y libros registro de cada una. Cumplimiento fiscal con VeriFactu.
Controla cobros, pagos, cajas y cuentas bancarias. Importa extractos bancarios y deja que la conciliación inteligente relacione los movimientos con tus facturas. Reglas de clasificación, cierres de caja y alertas de vencimientos.
Gestiona múltiples almacenes, zonas y ubicaciones. Control de stock por lotes con seguimiento de caducidades, costes reales y movimientos entre ubicaciones. Asigna ventas a sucursales y compara resultados entre tiendas.
Define tus productos una vez y úsalos en facturas, pedidos y presupuestos. Crea catálogos de precios por cliente, proveedor o campaña. Tarifas de compra y venta independientes que se aplican según el contexto.
Contabilidad automática que transforma tus ventas, compras y movimientos de tesorería en asientos. Cuadro de cuentas, gestión de inmovilizados y exportación.
# Inicio (/docs/rtg/pymes/inicio)
**Inicio** es la primera pantalla al entrar en Pymes. Reúne el estado de tu empresa, la acción que conviene hacer ahora y accesos directos a las tareas y módulos habituales. Sirve de punto de partida cada día y de guía mientras terminas de configurar el negocio.
Llegas al abrir **Pymes**, o desde **Pymes → Inicio**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
* **Saludo y modo guía.** Una cabecera de bienvenida con el nombre de tu empresa y un botón **Modo guía** que abre un recorrido explicado por los módulos de Pymes.
* **Acción recomendada.** Una tarjeta destacada que cambia según lo que te falte: completar los datos fiscales, activar Verifactu, crear el ejercicio, instalar el cuadro de cuentas, crear un impuesto, emitir la primera factura, registrar la primera compra o conectar el banco. Cuando todo está listo, invita a ver el análisis.
* **Progreso de configuración.** Una lista de comprobaciones con su estado: datos fiscales, cumplimiento (Verifactu), ejercicio, cuadro de cuentas, impuestos, primera venta, primera compra y cuenta bancaria.
* **Qué puedes hacer con Pymes.** Tarjetas que resumen cada área (pre-venta, ventas, compras, equipo, tesorería, inventario, contabilidad y fiscal) con un enlace para abrirla.
* **Accesos rápidos.** Botones para nueva factura, nuevo pedido, nuevo cliente, nuevo proveedor, subir factura de gasto y conciliar banco.
* **Configuración y herramientas externas.** Un acceso a la configuración de la empresa y enlaces a utilidades externas: el conversor de divisa del BCE y el comprobador VIES.
***
## Ventanas [#ventanas]
* **Modo guía**: se abre con el botón del mismo nombre. Un recorrido didáctico por los seis grandes bloques de Pymes (fiscal, contable, laboral, tesorería, inventario y entidades), con explicaciones y un enlace para saltar a cada sección.
***
→ [Mi Empresa](/docs/rtg/pymes/mi-empresa)
→ [Análisis](/docs/rtg/pymes/analisis)
→ [Ponerse al día](/docs/rtg/pymes/ponerse-al-dia)
# Libros Registros de Compra (/docs/rtg/pymes/libros-registros-de-compra)
Los **libros registro de compra** en Dinaup permiten organizar las facturas recibidas según el origen y tipo de operación: compras nacionales, intracomunitarias o importaciones desde fuera de la UE.
Cada factura de proveedor se clasifica sola en un libro según el **tipo de compra** elegido. Esa clasificación alimenta el control fiscal, la deducción del IVA soportado y la preparación de informes.
Estos libros agrupan las operaciones según su tratamiento contable y fiscal, lo que facilita auditorías internas y exportaciones periódicas.
# Mi Empresa (/docs/rtg/pymes/mi-empresa)
**Mi Empresa** es la ficha central con la identidad y los datos fiscales de tu negocio: denominación, NIF/CIF, forma jurídica, domicilio fiscal, actividad y logo. Es la fuente de la que beben tus facturas, tus documentos oficiales y las validaciones fiscales. Si un dato está mal aquí, sale mal en cada factura que emitas.
Estos datos se rellenan por primera vez al [registrar tu empresa](/docs/cuenta/registrar-empresa) durante el alta, y los revisas y actualizas desde esta sección siempre que cambien.
***
## Por qué importa tenerla correcta [#por-qué-importa-tenerla-correcta]
La ficha de empresa no es un formulario que rellenas y olvidas: alimenta el resto del sistema.
* **Cada factura la usa.** Tu denominación, NIF/CIF y domicilio fiscal aparecen como emisor en todas las facturas de venta. Es un dato obligatorio de cualquier factura y, si está mal, la factura es incorrecta.
* **Los documentos oficiales la heredan.** Presupuestos, pedidos, albaranes y demás [documentos oficiales](/docs/rtg/pymes/documentos-oficiales) toman de aquí los datos del emisor.
* **Las validaciones fiscales dependen de ella.** Tu NIF/CIF se valida contra la AEAT, y el régimen fiscal correcto solo funciona si tus datos de identidad están bien.
* **El logo da imagen de marca.** Si subes el logo de tu empresa, se incrusta en las facturas y documentos en PDF que envías a tus clientes.
Antes de emitir tu primera factura, comprueba que la denominación, el NIF/CIF y el domicilio fiscal son exactos. Corregir la ficha luego no reescribe las facturas ya emitidas: una factura emitida con datos erróneos hay que rectificarla.
***
## Qué datos contiene [#qué-datos-contiene]
| Dato | Para qué sirve |
| ------------------------------- | -------------------------------------------------------------------------------------------------- |
| **Denominación / Razón social** | Nombre legal de la empresa. Aparece como emisor en facturas y documentos. |
| **NIF / CIF** | Número de identificación fiscal. Se valida contra la AEAT y es obligatorio en cada factura. |
| **Forma jurídica** | Tipo de entidad (autónomo, S.L., S.A., etc.). |
| **Domicilio fiscal** | Dirección, municipio, provincia, código postal y país. Es la dirección que figura en las facturas. |
| **Actividad** | A qué se dedica tu empresa. |
| **Logo** | Imagen de marca que se incrusta en facturas y documentos PDF. |
El domicilio fiscal es la dirección oficial de la empresa. Si tienes varias ubicaciones físicas (tiendas, almacenes, oficinas), esas se gestionan aparte: la ficha de empresa guarda únicamente el domicilio fiscal que sale en los documentos.
***
## Dónde se editan [#dónde-se-editan]
### Abre Mi Empresa [#abre-mi-empresa]
Ve a **Pymes → Mi Empresa**. Verás la ficha con todos los datos de identidad y fiscales del negocio.
### Revisa y actualiza los datos [#revisa-y-actualiza-los-datos]
Comprueba que la denominación, el NIF/CIF, la forma jurídica y el domicilio fiscal son correctos y están al día. Corrige lo que haya cambiado.
### Sube el logo [#sube-el-logo]
Añade el logo de tu empresa para que aparezca en las facturas y documentos que generas en PDF.
### Guarda [#guarda]
Al guardar, los nuevos datos se aplican a las próximas facturas y documentos que emitas.
Los cambios afectan a lo que emitas **a partir de ahora**. Los documentos ya generados conservan los datos que tenían en el momento de emitirse.
***
## Relación con el resto de la configuración [#relación-con-el-resto-de-la-configuración]
La ficha de empresa define **quién eres** (tu identidad fiscal). Cómo numeras y clasificas tus facturas (series, tipos y libros registro) se define aparte, en la [configuración de Pymes](/docs/rtg/pymes/configuracion). Son dos cosas distintas: una es tu identidad como emisor, la otra son las reglas de tus documentos.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Durante el alta, al registrar tu empresa. Después los revisas y actualizas desde Pymes → Mi Empresa.
No. Los cambios afectan a las facturas y documentos que emitas a partir de ese momento. Una factura ya emitida con un dato erróneo se corrige rectificándola, no editando la ficha de empresa.
Para asegurar que el identificador fiscal de tu empresa es correcto antes de que figure en las facturas. Dinaup valida el NIF/CIF contra la AEAT.
Sí. Si subes el logo de tu empresa, se incrusta en las facturas y documentos que generas en PDF y les da imagen de marca.
***
→ [Registrar empresa (alta)](/docs/cuenta/registrar-empresa)
→ [Configuración de Pymes](/docs/rtg/pymes/configuracion)
→ [Documentos oficiales](/docs/rtg/pymes/documentos-oficiales)
→ [Ejercicios](/docs/rtg/pymes/ejercicios)
# Otros ingresos (/docs/rtg/pymes/otros-ingresos)
No todo el dinero que entra en tu negocio viene de una factura de venta. Una **subvención**, la devolución de un impuesto, un ingreso extraordinario o cualquier entrada puntual también suman, pero no encajan en tu facturación ordinaria. **Otros ingresos** es el sitio donde registras y consultas todas esas entradas. Así tu contabilidad y tus informes reflejan el dinero real que recibes, no solo lo facturado.
***
## Para qué sirve [#para-qué-sirve]
Usa Otros ingresos cuando recibas dinero que **no corresponde a una venta normal con factura**. Casos típicos:
* **Subvenciones y ayudas** públicas o privadas.
* **Devoluciones de impuestos** u otros reintegros.
* **Ingresos extraordinarios**: indemnizaciones, intereses, ingresos puntuales fuera de tu actividad habitual.
Si es dinero que entra pero no es una de tus ventas habituales, va aquí. Así no lo pierdes de vista y queda disponible para tu [análisis](/docs/rtg/pymes/analisis) y tu [contabilidad](/docs/rtg/pymes/contabilidad).
Un "otro ingreso" es una entrada **sin factura de venta** asociada. Si lo que registras es una venta a un cliente con su factura, eso va en [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas), no aquí.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La vista de Otros ingresos organiza la información en pestañas para que pases de lo general al detalle sin perderte:
| Pestaña | Qué muestra |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| **Otros ingresos** | El listado de todas las entradas registradas como ingreso sin factura, con sus importes y fechas. Es tu punto de partida. |
| **Conceptos** | El desglose por concepto de lo que has ingresado, para ver de dónde viene el dinero. |
| **Cobros** | Los cobros asociados a esos ingresos: cuándo y cómo has recibido efectivamente el dinero. |
Desde cualquiera de las listas puedes filtrar y buscar para localizar un ingreso concreto.
***
## Cómo se registra un ingreso [#cómo-se-registra-un-ingreso]
Un "otro ingreso" se crea con el **mismo flujo que una venta**, pero usando un tipo pensado para entradas sin factura. La clave está en los **tipos de venta**: cualquiera marcado como **"Es un ingreso sin factura"** genera un ingreso en lugar de una venta facturada.
### Prepara un tipo para ingresos sin factura [#prepara-un-tipo-para-ingresos-sin-factura]
En tus [tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) marca la casilla **"Es un ingreso sin factura"** en el tipo que vayas a usar (por ejemplo, uno llamado "Subvenciones" o "Ingresos"). Eso le dice al sistema que ese movimiento es un ingreso contable, no una venta con factura.
### Crea el ingreso desde el botón correspondiente [#crea-el-ingreso-desde-el-botón-correspondiente]
En la pantalla de Otros ingresos, pulsa el botón del tipo que preparaste. Se abre la ventana de registro, igual que al crear una venta: indicas importe, concepto y los datos que necesites.
### Guárdalo y consúltalo [#guárdalo-y-consúltalo]
Al guardar, el ingreso aparece en la pestaña **Otros ingresos**, su concepto en **Conceptos** y el cobro correspondiente en **Cobros**. A partir de ahí ya cuenta para tu análisis y tu contabilidad.
¿No te aparece ningún botón para crear? Significa que aún no tienes ningún tipo de venta marcado como **"Es un ingreso sin factura"**. Créalo o edítalo primero en [tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos).
***
## Otros ingresos frente a ventas [#otros-ingresos-frente-a-ventas]
Ambos comparten la misma maquinaria, pero el resultado y el propósito son distintos:
| | Venta con factura | Otro ingreso |
| ----------------- | ----------------------------------------------------------- | ---------------------------------------------------------- |
| Qué representa | Una venta a un cliente | Una entrada de dinero que no es una venta |
| Documento | Genera factura | Sin factura de venta |
| Ejemplos | Producto vendido, servicio prestado | Subvención, devolución de impuesto, ingreso extraordinario |
| Dónde se gestiona | [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas) | Esta pantalla |
En el fondo, un ingreso sin factura es un **tipo de venta especial**: por eso se configura en el mismo sitio y se crea con el mismo flujo, solo que sin emitir factura.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Cualquier entrada de dinero que no sea una venta con factura ordinaria: subvenciones, devoluciones de impuestos, indemnizaciones, intereses u otros ingresos extraordinarios.
Porque no tienes ningún tipo de venta marcado como "Es un ingreso sin factura". Ve a tus tipos de ventas e ingresos, marca esa casilla en el tipo que quieras usar, y el botón aparecerá.
No. Por definición es una entrada sin factura de venta. Si necesitas emitir una factura, lo que estás registrando es una venta y va en Facturación de ventas.
Sí. Quedan registrados como ingresos y entran en tu análisis y en tu contabilidad junto al resto de movimientos.
***
→ [Tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
→ [Análisis](/docs/rtg/pymes/analisis)
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
# Ponerse al día (/docs/rtg/pymes/ponerse-al-dia)
**Ponerse al día** es tu lista de pendientes del ciclo contable. Dinaup recorre tus datos (compras, ventas, nóminas, banco y asientos) en busca de lo que falta por registrar o cuadrar, y te lo presenta como acciones concretas. En lugar de descubrir un descuadre meses después, lo ves hoy y sabes exactamente qué hacer.
No tienes que configurar nada ni lanzar ningún proceso pesado: se calcula sobre tus datos reales en el momento en que entras. Y **no modifica nada**: solo mira y cuenta lo que está pendiente; las correcciones las haces tú desde los botones de cada aviso.
***
## Tu progreso: "X / 5 al día" [#tu-progreso-x--5-al-día]
La vista resume el estado de tu contabilidad en **cinco áreas** y, arriba del todo, un indicador de progreso del tipo **"X / 5 al día"**. Cuando las cinco están en orden, verás el mensaje **Todo al día** y no habrá nada que hacer.
Cada área es una tarjeta con un **semáforo**:
| Color | Significado | Qué hacer |
| ----------------------- | ------------------------------------- | -------------------------- |
| 🟢 **Al día** | Esa área no tiene pendientes | Nada |
| 🟡 Pendiente (aviso) | Hay algo por revisar, pero no urgente | Atiéndelo cuando puedas |
| 🔴 Pendiente (atención) | Hay bastante acumulado | Conviene resolverlo pronto |
Las cinco áreas siguen el orden natural del trabajo: primero registras (compras, ventas, nóminas), luego ordenas el banco (importar, clasificar, conciliar) y, al final, contabilizas (asientos).
### Compras y gastos [#compras-y-gastos]
Comprueba que no se queda nada sin registrar por el lado de las compras:
* **PDFs en cola**: facturas o gastos que subiste y siguen esperando a digitalizarse. Desde aquí saltas directo a **revisar la cola**.
* **Proveedores recurrentes sin factura del mes anterior**: si un proveedor habitual no te facturó el mes pasado, puede ser un olvido.
Puedes desplegar la **matriz de facturación por proveedor** para ver, mes a mes, qué importes hay y dónde falta una factura.
### Ventas e ingresos [#ventas-e-ingresos]
Lo mismo por el lado de las ventas: te avisa de los **clientes recurrentes sin factura del mes anterior**, por si a alguno se le pasó emitir. También puedes desplegar la **matriz de facturación por cliente** para verlo entidad por entidad.
### Nóminas [#nóminas]
Verifica que los empleados con contrato vigente tengan su **nómina del mes actual**. Si falta alguna, te indica cuántos empleados están sin nómina y te lleva a **Nóminas** para registrarla.
También te avisa, a título informativo, si hay empleados marcados como activos pero **sin contrato vigente**: es un hueco en los datos que conviene corregir.
### Movimientos bancarios [#movimientos-bancarios]
Reúne, cuenta a cuenta y en una sola tarjeta, las tres tareas del banco:
* **Extractos**: si una cuenta lleva días sin movimientos nuevos aparece como desactualizada, con un botón para **importar** el extracto al momento.
* **Clasificar**: cuenta los movimientos sin tipo ni entidad asignados y abre la herramienta de **clasificación** de esa cuenta.
* **Conciliar**: muestra los movimientos aún sin vincular a su factura, cobro o pago, con su botón para **conciliar**.
Cada cuenta enseña su última importación, para que veas de un vistazo cuál se ha quedado atrás.
### Asientos contables [#asientos-contables]
Detecta las **operaciones recientes sin asiento**: ventas, compras, cobros, pagos y nóminas que todavía no se han contabilizado. Te las desglosa por tipo y te ofrece lanzar la **contabilidad automática** para generarlos de una vez.
***
## Cómo leer cada aviso [#cómo-leer-cada-aviso]
Cada línea de una tarjeta funciona igual:
* Un **check verde** significa que esa comprobación concreta está en orden.
* Un **icono de aviso** señala que hay algo pendiente, con el **número** afectado en negrita (por ejemplo, "3 PDFs en cola" o "5 movimientos sin clasificar").
* Junto al aviso, un **botón de acción** te lleva al sitio exacto donde se arregla. No tienes que buscar el módulo: la tarjeta te abre la puerta.
**Lees el aviso, pulsas el botón, lo resuelves.** Cuando vuelves, esa línea pasa a verde.
***
## Cuándo pasar por aquí [#cuándo-pasar-por-aquí]
No hace falta una rutina rígida, pero estos son los buenos momentos:
* **Antes de conciliar**: resolver los pendientes primero hace que la [conciliación](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) fluya sin sorpresas.
* **Al cierre de cada mes**, para asegurarte de que no quedó nada sin registrar ni contabilizar.
* **Cuando un informe no cuadra**: si en [Análisis](/docs/rtg/pymes/analisis) ves una cifra rara, aquí suele estar la explicación (algo sin emitir, sin importar o sin conciliar).
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Solo revisa y cuenta lo que está pendiente. Cualquier corrección la haces tú desde los botones de cada aviso (importar un extracto, clasificar, conciliar o lanzar la contabilidad automática).
Es tu progreso: de las cinco áreas que Dinaup revisa (compras y gastos, ventas e ingresos, nóminas, movimientos bancarios y asientos), cuántas están en verde. Cuando llegan a 5, tu contabilidad está al día.
No necesariamente. Dinaup marca los proveedores recurrentes que no te facturaron el mes pasado por si fue un olvido. Si ese mes realmente no había factura, puedes ignorarlo.
Lo habitual es antes de conciliar y al cierre de cada mes. También es el primer sitio donde mirar si un informe de Análisis muestra una cifra que no esperabas.
***
→ [Análisis](/docs/rtg/pymes/analisis)
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
→ [Contabilidad automática](/docs/rtg/pymes/procesos/contabilidad-automatica)
# Por cobrar (/docs/rtg/pymes/por-cobrar)
**Ventas pendientes de cobro** es tu lista de lo que te deben. Reúne todas las facturas de venta que aún no están cobradas del todo, agrupadas por cliente y ordenadas por urgencia: lo más vencido, arriba. Desde aquí ves cuánto te deben, quién y desde cuándo, y reclamas el pago.
***
## Lo que ves al entrar [#lo-que-ves-al-entrar]
Arriba tienes un resumen rápido del estado de tus cobros con varias métricas:
* **Deuda vencida**: el importe total de facturas que ya pasaron su fecha de vencimiento. Es el dinero que deberías haber cobrado ya.
* **Total pendiente**: toda la deuda, esté vencida o no.
* **Vence en 7 días**: lo que te deben pagar en la próxima semana, para anticiparte.
* **Clientes**: cuántos clientes te deben algo ahora mismo.
* **DSO promedio**: los días que de media tardas en cobrar (Days Sales Outstanding). Cuanto más bajo, mejor cobras.
La lista se actualiza sola al entrar. Si registras un cobro y quieres ver el cambio al momento, usa el botón de **refrescar** que hay junto al título.
***
## Cómo se organiza la deuda [#cómo-se-organiza-la-deuda]
Debajo del resumen, los clientes aparecen agrupados por **antigüedad de la deuda** (lo que se llama *aging*), de lo más crítico a lo más reciente:
* **Vencido +60 días**: lo más urgente, marcado en rojo.
* **Vencido 30-59 días**: deuda que empieza a preocupar.
* **Vencido 1-29 días**: vencido hace poco.
* **Al día**: clientes con facturas pendientes que aún no han vencido.
Cada grupo muestra cuántos clientes contiene y el total que suman, para que sepas dónde está el grueso del problema sin contar a mano.
***
## La ficha de cada cliente [#la-ficha-de-cada-cliente]
Por cada cliente que te debe, ves una tarjeta con:
* Su **nombre** y, si tiene facturas vencidas, una etiqueta con los **días de retraso** del caso más antiguo.
* El **total pendiente** que te debe y, aparte, cuánto de eso ya está **vencido**.
* El número de **facturas pendientes**.
* Una etiqueta **Sin vencimiento** si alguna de sus facturas no tiene fecha de pago asignada.
Dentro de la tarjeta tienes el **detalle de cada factura**:
| Columna | Qué te dice |
| ----------- | ---------------------------------------------------------------- |
| Fecha | Cuándo se emitió la factura |
| Número | El número de factura (haz clic para abrirla) |
| Vencimiento | Cuándo debería pagarse, o *Sin vencimiento* si no tiene fecha |
| Estado | Días vencida, *Hoy* si vence hoy, o *en X días* si aún no vence |
| Cobrado | Cuánto se ha cobrado ya, con una barra que muestra el porcentaje |
| Pendiente | Lo que falta por cobrar de esa factura |
Haz clic en cualquier fila de factura para abrirla y trabajar sobre ella: registrar un cobro, revisar líneas o consultar su estado. Es el puente directo entre lo que debes cobrar y la [factura de venta](/docs/rtg/pymes/facturacion/ventas).
***
## Encontrar lo que buscas [#encontrar-lo-que-buscas]
Cuando tienes muchos clientes, la barra de filtros te ayuda a centrarte:
* **Buscar cliente**: escribe el nombre para quedarte solo con ese cliente.
* **Antigüedad**: filtra por tramos de vencimiento (más de 90 días, 60-89, 30-59, 1-29, al día, o sin vencimiento).
* **Importe**: filtra por cuánto te deben (más de 10.000, 5.000-9.999, 1.000-4.999, o menos de 1.000).
Los filtros que tengas activos aparecen como **chips** debajo de la barra. Quita uno haciendo clic en él, o usa el botón de limpiar para empezar de cero.
***
## Reclamar el pago [#reclamar-el-pago]
No solo ves la deuda: la **reclamas** sin salir de la pantalla. Cada cliente tiene dos botones de recordatorio.
### Recordatorio por email [#recordatorio-por-email]
El botón **Email** abre un recordatorio de pago listo para enviar a ese cliente, partiendo de una plantilla de documento. Si tienes configurada tu propia plantilla de recordatorio en los datos de tu empresa, se usa esa; si no, se usa la que trae Dinaup por defecto.
### Recordatorio por WhatsApp [#recordatorio-por-whatsapp]
El botón de **WhatsApp** abre un asistente para mandar el recordatorio por mensajería. Funciona así:
### Elige el tono [#elige-el-tono]
Arriba ves el cliente y el total que te debe. Debajo, eliges entre cuatro tonos según la situación:
* **Cordial**: amable, para un primer aviso.
* **Formal**: trato de usted, profesional.
* **Directo**: al grano, sin rodeos.
* **Urgente**: para deuda vencida que necesita atención inmediata.
### Revisa el mensaje [#revisa-el-mensaje]
Cada tono te muestra una **vista previa** del mensaje tal y como le llegará al cliente, con forma de chat. El texto ya incluye tu nombre de empresa, el importe total, el **detalle de las facturas pendientes** y, si la factura tiene **enlace de pago**, un enlace para que pague directamente.
### Envía por WhatsApp [#envía-por-whatsapp]
Pulsa **Enviar por WhatsApp** y se abre WhatsApp con el mensaje ya escrito. Solo tienes que elegir el contacto del cliente y darle a enviar.
***
## Preguntas frecuentes [#preguntas-frecuentes]
De tus facturas de venta. Cualquier factura con importe pendiente de cobro aparece aquí sola, asociada a su cliente. En cuanto la cobras del todo, deja de aparecer.
Que esa factura no tiene una fecha de pago asignada. Dinaup no puede calcular su retraso, así que la marca aparte para que no se te pase. Asigna una fecha de vencimiento en la factura para incluirla en el control de antigüedad.
No. Dinaup prepara el mensaje con todo el detalle y abre WhatsApp por ti, pero tú eliges el contacto y confirmas el envío. Mantienes el control de qué se manda y a quién.
Es la media de días que tardas en cobrar tus ventas (Days Sales Outstanding). Un DSO bajo significa que cobras rápido; uno alto, que el dinero tarda en entrar. Te sirve para medir la salud de tus cobros de un mes a otro.
Significa que tienes un volumen muy alto de facturas sin cobrar, más de lo que la pantalla muestra de golpe. Es señal de que conviene ponerse al día con los cobros; trabaja primero los clientes y tramos más vencidos.
***
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
→ [Tesorería](/docs/rtg/pymes/tesoreria)
→ [Análisis](/docs/rtg/pymes/analisis)
# Stripe (/docs/rtg/pymes/stripe)
La pantalla de **Stripe** trae a Pymes lo que ocurre en tu cuenta de Stripe: facturas, suscripciones, productos, pagos y transferencias a tu banco. Desde aquí revisas tu actividad de cobro online y **importas las facturas de Stripe como ventas** en Dinaup.
Llegas desde **Pymes → Más → Stripe**. Está marcada como funcionalidad **Beta**.
Necesitas una cuenta de Stripe conectada. La conexión la activa un administrador desde la configuración de la empresa.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La información se reparte en pestañas, cada una con su propio botón **Recargar** y sus filtros:
| Pestaña | Qué muestra | Columnas |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| **Facturas** | Las facturas de Stripe, con filtro por estado, por rango de fechas y por pendientes de importar. | Estado, número, cliente, vencimiento, fecha, total |
| **Suscripciones** | Las suscripciones activas y su periodicidad. | Estado, producto, cliente, importe, impuesto, periodo actual |
| **Productos** | Los productos de tu catálogo de Stripe, con opción de ver solo los activos o todos. | Estado, nombre, descripción, ID |
| **Pagos** | Los pagos recibidos en un rango de fechas. | Estado, descripción, fecha, importe, moneda |
| **Cobros** | Las transferencias de Stripe a tu cuenta bancaria. Expande una fila para ver sus transacciones (bruto, comisión, neto). | Estado, fecha, llegada estimada, descripción, importe, moneda |
| **Clientes** | Los clientes registrados en Stripe. | Nombre, email, teléfono, alta, ID |
En la pestaña **Facturas**, la etiqueta **Nueva** marca las que aún no están en Dinaup.
***
## Importar una factura de Stripe como venta [#importar-una-factura-de-stripe-como-venta]
En la pestaña **Facturas**, cada factura que todavía no existe en Dinaup trae un botón para **agregarla al ERP**. Al pulsarlo, Dinaup crea una venta a partir de esa factura. Junto a él tienes accesos para **descargar el PDF** y **ver la factura online** en Stripe.
Para que la importación funcione, la empresa debe tener configurado un **tipo de venta predeterminado para Stripe**. Si el cliente de Stripe no está vinculado a ningún cliente de Dinaup, se te pide vincularlo antes de importar.
El tipo de venta predeterminado para Stripe debe tener los **impuestos incluidos** y **no** puede tener activada la opción de factura emitida con otro software: Stripe no es compatible con Verifactu, así que Dinaup emite y envía la factura con normalidad.
***
## Ventanas [#ventanas]
* **Vincular Cliente**: se abre al importar una factura cuyo cliente de Stripe aún no tiene equivalente en Dinaup. Muestra los datos del cliente de Stripe (nombre, email, teléfono, ID) y un buscador para elegir con qué cliente de Dinaup se vincula. Se confirma con **Vincular**.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. La pantalla te muestra cuáles están pendientes (etiqueta Nueva), pero cada importación la lanzas tú con el botón de agregar al ERP. Así mantienes el control de qué entra como venta.
Casi siempre por la configuración del tipo de venta predeterminado de Stripe: tiene que existir, llevar los impuestos incluidos y no estar marcado como factura de otro software. El mensaje de error indica cuál de estas condiciones falla.
Las transferencias que Stripe hace a tu cuenta bancaria (los payouts). Cada una se puede desplegar para ver las transacciones que la componen, con su importe bruto, la comisión y el neto.
***
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
→ [Tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
→ [Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu)
# Convertir divisa (/docs/rtg/tpv/convertir-divisa)
La ventana **Convertir divisa** pasa los importes de la operación de **dólares (USD) a euros (EUR)**. La abres desde el botón **Divisa** de la ventana de venta y aplica el tipo de cambio a todos los conceptos del documento de una vez.
Se abre como un panel sobre la operación. Arriba ves la divisa de origen y destino y la fecha del tipo de cambio.
***
## Qué muestra [#qué-muestra]
* **Tipo de cambio**: el valor `1 USD = ... EUR`. Viene relleno con el dato del **BCE** (Banco Central Europeo) para la fecha del documento, y puedes cambiarlo a mano.
* **Fuentes**: un botón con el tipo del **BCE** y, si has tecleado otro, una etiqueta **Manual**. Pulsa la fuente que quieras usar.
* **Vista previa**: el importe **Original** en USD frente al **Resultado** en EUR con el cambio actual.
Si el BCE no tiene dato para esa fecha, o no está disponible, el panel te lo dice y te deja introducir el tipo de cambio a mano.
***
## Convertir [#convertir]
### Abre la ventana [#abre-la-ventana]
Pulsa **Divisa** en la operación. El panel carga el tipo de cambio del BCE para la fecha del documento.
### Revisa o ajusta el tipo [#revisa-o-ajusta-el-tipo]
Deja el del BCE o teclea el tuyo. La vista previa te muestra el importe resultante en euros antes de aplicar nada.
### Aplica la conversión [#aplica-la-conversión]
Pulsa **Aplicar conversión**. Cada concepto se recalcula multiplicando su precio (y su descuento fijo) por el tipo de cambio, y el total pasa a euros.
Al aplicarla, Dinaup añade una nota a las **observaciones** de la operación con la divisa, el tipo usado, su fuente y el total original en USD, para dejar rastro de la conversión.
La conversión **multiplica** los precios por el tipo de cambio. Si la aplicas dos veces sobre el mismo documento, los importes se vuelven a multiplicar. El panel te avisa si ya se aplicó una conversión y te pide confirmación antes de repetirla.
***
→ [Ventana de venta](/docs/rtg/tpv/ventana-de-venta)
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
# DataFlow (/docs/rtg/tpv/dataflow)
**DataFlow** es la vista que reúne, en un solo panel, todo lo que mueve una operación: el **dinero** (cobros o pagos) y el **inventario** (entradas y salidas de producto), más sus **devoluciones**. La abres sobre una operación concreta: una venta, una compra, un pedido o un presupuesto. Desde ahí ves qué está hecho y qué queda pendiente, y lo completas sin saltar de pantalla.
Es una pieza central del TPV: en lugar de ir a la tesorería para cobrar, al almacén para dar salida al producto y a otra pantalla para la devolución, lo haces todo desde el mismo sitio, con el contexto de la operación delante.
DataFlow no crea la operación: trabaja sobre una que ya existe. Primero registras la venta, compra, pedido o presupuesto; después abres su DataFlow para cobrarla, mover el stock y gestionar devoluciones.
***
## Qué muestra [#qué-muestra]
El panel se organiza en **tarjetas**, una por cada faceta de la operación. Aparecen solo las que tienen sentido para esa operación, así que no todas las verás siempre. Cada tarjeta lleva un **título con icono** y un **distintivo de estado** que te dice cómo va:
| Estado | Significado |
| ---------------------------- | ----------------------------------------------------------- |
| **Pendiente** | Queda algo por hacer (cobrar, dar salida, recibir entrada). |
| **Completado / Completadas** | Esa faceta está cerrada, nada pendiente. |
La cabecera del panel identifica la operación: su **número** (de factura, de pedido o de presupuesto), el **cliente o proveedor** y, si procede, una etiqueta **Rectificativa**.
***
## Cobro y pago: el dinero de la operación [#cobro-y-pago-el-dinero-de-la-operación]
La primera tarjeta es la del dinero. Se llama **Cobro** en ventas y pedidos, y **Pago** en compras. Funciona igual en ambos casos: arriba ves los importes, debajo registras el movimiento.
Ves tres cifras:
* **Total factura**: lo que suma la operación.
* **Cobrado / Pagado**: lo que ya se ha movido.
* **Pendiente**: lo que falta, destacado como cifra principal.
Para cobrar (o pagar):
### Indica el importe [#indica-el-importe]
Por defecto te propone el **pendiente** completo, pero puedes teclear menos para registrar un cobro o pago **parcial**.
### Elige caja o cuenta bancaria [#elige-caja-o-cuenta-bancaria]
En un cobro, seleccionas el **depósito** donde entra el dinero: una caja de efectivo o una cuenta bancaria. Es obligatorio; si no lo eliges, Dinaup te avisa.
### Confirma [#confirma]
Pulsa **Cobrar** o **Pagar**. El importe se anota, el pendiente se recalcula y, si quedaba algo, la tarjeta sigue abierta para el siguiente movimiento.
Cuando la operación queda saldada, la tarjeta se contrae y muestra el distintivo **Completado**. Debajo tienes **Ver cobros / Ver pagos** para desplegar el historial: cada movimiento con su fecha, el depósito, el importe, su estado y la opción de abrirlo o eliminarlo.
→ [Cómo cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
***
## Entradas y salidas: el inventario [#entradas-y-salidas-el-inventario]
Las operaciones que mueven producto tienen tarjetas de **inventario**:
* **Salidas**: producto que sale del almacén (lo que entregas en una venta, o lo que devuelves al proveedor en una compra).
* **Entradas**: producto que entra (lo que recibes en una compra, o lo que vuelve a tu almacén en una devolución de venta).
Cada tarjeta tiene dos pestañas:
* **Pendiente**: los movimientos que aún tienes que hacer. Por cada producto ves cuántas unidades hay **facturadas** y cuántas **pendientes**, y una fila para registrar el movimiento.
* **Historial**: lo ya movido, con un contador de cuántos apuntes hay. Cada línea muestra producto, lote y unidades, y puedes abrirla para ver el detalle.
Para registrar un movimiento de stock desde la pestaña **Pendiente**:
### Elige almacén [#elige-almacén]
Selecciona el almacén de origen o destino. Si lo eliges, los **lotes** disponibles se filtran a ese almacén.
### Elige el lote [#elige-el-lote]
Escoge el lote del producto. La lista te enseña su estado, el **stock disponible**, el **stock de inventario** y la fecha, para que elijas con criterio. Si solo hay un lote, se selecciona solo. También puedes **crear un lote nuevo** ahí mismo si no existe.
### Indica la cantidad y añade [#indica-la-cantidad-y-añade]
Teclea las unidades (en una salida no te deja pasarte del stock del lote) y pulsa el botón de **añadir**. El movimiento se registra y pasa al historial.
Cuando no quedan movimientos pendientes, la pestaña te lo dice con un "No hay movimientos pendientes" y la tarjeta marca **Completadas**.
***
## Devoluciones [#devoluciones]
Casi todas las operaciones tienen una tarjeta de **Devolución**. Desde ella generas la **rectificativa** correspondiente sin rehacer los datos: Dinaup arrastra el cliente o proveedor, los productos y las condiciones de la operación original.
* En una **venta**, pulsas **Iniciar devolución** y se prepara la rectificativa con los importes a ajustar. No se puede emitir una rectificativa sobre otra rectificativa: en ese caso, Dinaup te lo indica y debes partir de la factura original.
* En una **compra**, **Iniciar devolución** prepara la devolución de unidades al proveedor.
* Si ya hay devoluciones de esa operación, las ves listadas en la misma tarjeta con su número e importe.
***
## DataFlow según la operación [#dataflow-según-la-operación]
El panel se adapta a lo que estás mirando. Estas son las cuatro variantes:
| Operación | Qué reúne su DataFlow |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Venta** | Cobro, salidas y entradas de producto, devolución y, según tu configuración, sustitución de la factura. |
| **Compra** | Pago, entradas y salidas de producto, y devolución al proveedor. |
| **Pedido** | Total facturado frente a pendiente, las **ventas** generadas desde el pedido (cada una con su progreso de cobro y envío) y las devoluciones. Desde aquí agregas una nueva venta del pedido. |
| **Presupuesto** | Total del presupuesto y las **ventas** facturadas a partir de él. Desde aquí conviertes el presupuesto en venta. |
En el caso del **pedido**, cada venta se muestra como una tarjeta con su estado, su fecha, su total y unas barras de progreso para el **cobro** y el **envío**, además de sus devoluciones. Es la vista más completa para seguir un pedido de principio a fin.
***
## Cómo leer el panel [#cómo-leer-el-panel]
Para interpretar el panel:
1. **Mira los distintivos de estado.** Todo en verde (**Completado / Completadas**) significa que la operación está cerrada por ese lado. Si hay algún **Pendiente**, ahí tienes trabajo.
2. **Empieza por el dinero.** La tarjeta de Cobro o Pago te dice cuánto falta por liquidar; el **Pendiente** destacado es la cifra que importa.
3. **Sigue por el inventario.** Las pestañas **Pendiente** te listan exactamente qué producto y cuántas unidades quedan por mover.
4. **Cierra con las devoluciones** si la operación las necesita.
Cuando todas las tarjetas estén en verde, la operación está completa: cobrada (o pagada), con el stock movido y sin nada colgando.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Es un panel que reúne el dinero y el inventario de una operación (venta, compra, pedido o presupuesto) en un mismo sitio. Desde él cobras o pagas, das entrada y salida al producto, y gestionas devoluciones, sin cambiar de pantalla.
No. La tarjeta de Cobro (o Pago) te propone el pendiente completo, pero puedes teclear un importe menor para registrar un cobro o pago parcial. El resto queda como pendiente.
Porque el dinero tiene que aterrizar en un depósito de tu tesorería: el efectivo en una caja, lo demás en una cuenta bancaria. Es lo que luego hace que tus cierres cuadren. Si no eliges depósito, Dinaup no te deja confirmar.
Las salidas son producto que sale de tu almacén (lo que entregas en una venta, o lo que devuelves al proveedor). Las entradas son producto que entra (lo que recibes en una compra, o lo que vuelve a tu almacén en una devolución). Cada movimiento se registra contra un lote y un almacén.
En la tarjeta de Devolución, pulsas "Iniciar devolución" y Dinaup prepara la rectificativa con los datos de la operación original. No hace falta volver a teclear cliente, productos ni condiciones.
***
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
→ [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida)
→ [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
# Devoluciones en el TPV (/docs/rtg/tpv/devoluciones)
Una **devolución** deshace, total o parcialmente, una venta o un pedido que ya cobraste. El cliente trae el producto, le reintegras el dinero y la operación queda registrada como una **factura rectificativa** vinculada a la original. Desde el TPV no borras nada ni repites la venta al revés a mano: el sistema crea la rectificativa con los importes en negativo y te lleva al cobro para devolver el efectivo.
Una devolución en Dinaup **siempre es una rectificativa**, no un borrado. La venta original se conserva intacta y la devolución queda enganchada a ella, para que el rastro fiscal y contable sea correcto. Por eso una venta anulada y una venta devuelta no son lo mismo.
***
## Dónde se inician: el Flujo de la operación [#dónde-se-inician-el-flujo-de-la-operación]
Las devoluciones viven dentro del **Flujo** de cada venta o pedido. El Flujo es la vista que reúne todo el ciclo de una operación (cobros, entradas y salidas de stock, y devoluciones) en un mismo sitio.
Para abrirlo, busca la venta o el pedido en su listado y entra en su **Flujo** (el mismo botón que usas para gestionar cobros parciales o pagos mixtos). Dentro encontrarás una tarjeta **Devolución**, con dos cosas:
* El **historial** de devoluciones ya hechas sobre esa operación.
* El botón **Iniciar devolución** para crear una nueva.
La devolución de **pedidos** está marcada como **Beta**: funciona, pero es una incorporación reciente que seguimos puliendo.
***
## Devolver una venta [#devolver-una-venta]
### Abre el Flujo de la venta [#abre-el-flujo-de-la-venta]
Localiza la venta en su listado y abre su **Flujo**. La cabecera te muestra el número de factura y el cliente, y si la operación ya es una rectificativa, lo marca con una etiqueta **Rectificativa**.
### Pulsa "Iniciar devolución" [#pulsa-iniciar-devolución]
En la tarjeta **Devolución**, pulsa **Iniciar devolución**. Dinaup prepara una **rectificativa por diferencias**: una nueva factura, vinculada a la original, que arrastra el cliente, los datos fiscales, los impuestos y los descuentos de la venta de partida.
### Ajusta lo que devuelves [#ajusta-lo-que-devuelves]
La rectificativa nace con las líneas de la venta en **negativo**. Si el cliente devuelve todo, la dejas tal cual; si devuelve solo una parte, ajustas las cantidades o quitas líneas para que refleje exactamente lo que entra de vuelta.
### Devuelve el efectivo y finaliza [#devuelve-el-efectivo-y-finaliza]
Al llegar al cobro, el total sale en negativo y la pantalla se adapta a una devolución. Indicas el dinero que entregas al cliente y finalizas. La devolución queda registrada y aparece en el historial de la venta.
**No se puede hacer una rectificativa sobre otra rectificativa.** Si abres el Flujo de una factura que ya es una devolución, no verás el botón para devolverla: Dinaup te avisa de que, si necesitas corregir, crees una nueva rectificativa vinculada a la **factura original**.
***
## Devolver un pedido [#devolver-un-pedido]
Los pedidos tienen su propio Flujo, con una tarjeta **Devolución** equivalente. Al pulsar **Iniciar devolución** sobre un pedido, Dinaup genera un **pedido de devolución** vinculado al original, copiando sus líneas con el importe en negativo. Igual que en la venta, queda enganchado al pedido de partida y se suma a su historial de devoluciones.
Dentro del Flujo del pedido ves las ventas que ha generado y, en cada una, si tiene devoluciones asociadas y si ya están reintegradas o quedan pendientes.
***
## Cómo cambia el cobro en una devolución [#cómo-cambia-el-cobro-en-una-devolución]
Cuando cobras una venta normal, introduces lo que **recibes** del cliente y Dinaup calcula el cambio. En una devolución el dinero va al revés, y la pantalla de cobro lo refleja **trabajando siempre con importes en positivo**, aunque el total de la operación sea negativo. Así nadie tiene que teclear cantidades con signo menos en una pantalla táctil.
Lo que cambia respecto a un cobro normal:
| En una venta normal | En una devolución |
| ---------------------------------------------- | -------------------------------------------------------- |
| **A cobrar** | **A devolver al cliente** |
| **Pago recibido** | **Dinero entregado al cliente** |
| Si te quedas corto: *Falta por cobrar* | Si entregas de menos: *Te falta por entregar al cliente* |
| Si recibes de más: el **cambio** que devuelves | Si entregas de más: **lo que el cliente debe devolver** |
Tecleas siempre en positivo: en **A devolver** ves la cantidad que le toca al cliente, y en **Dinero entregado** anotas lo que sacas de la caja. Para finalizar, tienes que entregar **al menos** el importe a devolver; si te quedas corto, Dinaup no deja cerrar la operación.
El botón **Automático**, que rellena el cobro de un tirón, funciona solo con **efectivo**. En una devolución, entrega exactamente el importe que hay que reintegrar.
***
## Historial y trazabilidad [#historial-y-trazabilidad]
Cada devolución queda registrada y enlazada a su operación de origen, de forma que el rastro nunca se pierde:
* En el **Flujo** de la venta o el pedido, la tarjeta **Devolución** lista todas las devoluciones hechas, con su fecha, su número de factura, su importe y su estado.
* Cada fila del historial es **navegable**: la abres para ver el detalle de esa rectificativa concreta.
* En el Flujo de un **pedido**, cada venta muestra además si tiene devoluciones y si están ya **devueltas** o **pendientes** de reintegrar.
Como la devolución es una rectificativa, hereda la serie y el tratamiento fiscal que le corresponde (incluido el cumplimiento de VeriFactu cuando aplica), sin que tengas que configurarlo a mano.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. La venta original se conserva intacta. La devolución es una factura rectificativa nueva, vinculada a ella, con los importes en negativo. Por eso queda trazada y no se pierde el rastro de lo ocurrido.
Sí. Al iniciar la devolución, la rectificativa nace con todas las líneas en negativo; ajustas las cantidades o quitas líneas para que refleje únicamente lo que el cliente trae de vuelta.
Porque esa factura ya es una rectificativa, y no se puede rectificar una rectificativa. Si necesitas corregir, crea una nueva devolución vinculada a la factura original.
No. La pantalla de cobro trabaja en positivo: ves cuánto hay que devolver y anotas el dinero que entregas al cliente, sin signos. Solo tienes que entregar al menos el importe a devolver para poder finalizar.
Sí. Una devolución es una factura rectificativa y se trata como tal a efectos fiscales, con su serie y su registro. El detalle de los tipos de rectificativa está en la página de VeriFactu.
***
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
→ [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida)
→ [VeriFactu y facturas rectificativas](/docs/rtg/pymes/facturacion/ventas/verifactu)
→ [Ventas (Pymes)](/docs/rtg/pymes/facturacion/ventas)
# Preguntas frecuentes (/docs/rtg/tpv/faq-tpv)
Dudas frecuentes del punto de venta: dispositivos, cajas, cobros y pedidos. Si no encuentras la respuesta, escribe a `soporte@dinaup.com` o abre el chat de ayuda en [play.dinaup.com](https://play.dinaup.com).
***
## Compatibilidad y requisitos [#compatibilidad-y-requisitos]
El TPV funciona en cualquier dispositivo con navegador web moderno, ya sea ordenador, tablet o móvil, independientemente del sistema operativo: Windows, macOS, Android, iOS o Linux.
El sistema es compatible con impresoras de tickets térmicas que utilicen el protocolo ESC/POS, el estándar más extendido en el sector.
También con impresoras convencionales.
Sí. Los cajones portamonedas que se conectan a través de la impresora POS se abren solos al emitir un ticket.
Sí, el TPV requiere conexión a internet para funcionar, ya que opera sobre la plataforma Dinaup en la nube.
## Configuración [#configuración]
La caja se asocia al dispositivo mediante una cookie del navegador. Ve a **TPV → Cajas**, selecciona la caja que deseas vincular y el sistema la recordará en ese navegador. Detalle en [Configurar y vincular una caja](/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja).
Al dar de alta una caja, asocia una cuenta bancaria en el campo **"Cuenta bancaria (Pago con tarjeta)"**. Cuando selecciones pago con tarjeta, el importe se registrará en esa cuenta en lugar de en la caja de efectivo.
En el **Tipo de Venta** que utilices, activa la opción **"TPV Modo Táctil"**. Este modo está pensado para pantallas sin teclado ni ratón, como en hostelería o kioscos. Para hostelería hay un tipo de venta específico: [TPV Hostelería](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-tpv-hosteleria).
* Ve a **Pymes → Configuración → Categorías de Venta**
* Crea o edita una categoría
* Activa el checkbox **"Mostrar en TPV Modo Táctil"**
* Asigna un color e icono si lo deseas
* La categoría aparecerá como pestaña en el TPV táctil
* Ve a **Pymes → Configuración → Empresa**
* Establece el tipo predeterminado para ventas y pedidos
* Si prefieres elegirlo manualmente cada vez, deja el campo vacío
## Uso diario [#uso-diario]
Sí. Varias sucursales pueden trabajar a la vez, cada una con sus propias cajas y configuración.
El número de usuarios depende de tu licencia contratada con Dinaup.
Pulsa el botón **"Flujo"** y ve agregando los importes parciales. Esto permite pagos mixtos combinando tarjeta y efectivo en la misma venta.
Sí. Busca la venta en el listado de ventas y pulsa **"Imprimir"** para generar una copia del ticket.
* En el TPV, accede al menú de Caja
* Selecciona **"Cierre de caja"**
* Cuenta el efectivo físico e introdúcelo
* El sistema lo compara con el efectivo teórico
* Revisa las diferencias si las hay
* Confirma el cierre
El cierre del TPV vuelca el resultado del periodo a la caja de tesorería, así que no tienes que registrar a mano cada cobro en efectivo.
## Ventas y cobros [#ventas-y-cobros]
Tienes tres niveles de descuento y se combinan entre sí:
* **Por línea (%)**: sobre cada línea, en su campo de descuento, rebajas un producto concreto.
* **Global**: un descuento sobre el total de la venta, una vez tienes todas las líneas añadidas.
* **Automático por cliente VIP**: si asignas un cliente registrado con descuento, se aplica solo, sin teclearlo.
Con cliente genérico no hay descuento automático: lo metes tú a mano, por línea o global. Tienes el detalle en [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida).
Las dos cosas. Para un ticket sin datos, vende a **cliente genérico**: es lo habitual en mostrador. Si necesitas el histórico del cliente, su tarifa, sus descuentos o emitir factura con sus datos fiscales, asígnale un **cliente registrado** (lo buscas por nombre o NIF, o lo creas en el momento con nombre y teléfono). Puedes empezar con genérico y asignar el cliente registrado después, antes de cobrar.
El TPV trabaja contra el **almacén** que eliges al abrir la caja. Al cobrar una venta, el stock de ese almacén **baja solo**, sin que lo ajustes a mano. Para productos sin control de existencias (por ejemplo, servicios de hostelería), puedes dejar desactivado **"Evaluar Stock"** en la ficha del producto y la venta no descuenta nada.
Puedes **anular** la venta desde el histórico, siempre con el permiso correspondiente y dejando un motivo. La operación queda registrada y trazada, así que no se pierde el rastro de lo que pasó.
Sí. Desde el TPV crea una **compra** (factura recibida) y sube una **foto** o un **PDF** de la factura del distribuidor. La IA lee el documento y propone proveedor, número y fecha, líneas e importes. Eliges si detecta solo las bases o el documento completo, revisas lo extraído y grabas. Al confirmar, se registra la compra, sube el stock y se genera el asiento contable. Lo tienes detallado en [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida).
## Pedidos y delivery [#pedidos-y-delivery]
Los pedidos en marcha viven en un **tablero kanban** con cuatro columnas: **Pendiente → Preparando → Listo → Entregado**. Para avanzar un pedido, **arrastra su tarjeta** a la siguiente columna; el cambio lo ve todo el equipo. Sirve tanto para hostelería (preparar en cocina o barra) como para delivery. Tienes la guía completa en [Pedidos y delivery](/docs/rtg/tpv/procesos/pedidos-y-delivery).
La tarifa de envío se calcula **por zona**: según el destino del pedido se aplica la tarifa correspondiente y se suma al total. La dirección de entrega se autocompleta si el cliente ya la tiene guardada en su ficha; si no, la introduces con provincia y código postal.
En los pedidos de delivery indicas una **hora estimada de entrega** que aparece en la tarjeta del tablero. Así todo el equipo tiene claro el compromiso con el cliente y puede ordenar el trabajo por las entregas más próximas.
No. El tablero sirve para preparar y entregar; el **cobro se hace en el TPV** como cualquier otra venta. Marcar un pedido como entregado y cobrarlo son acciones separadas: asegúrate de cobrarlo además de moverlo a "Entregado".
## Personalización [#personalización]
Puedes cambiar el logo de tu empresa desde **Pymes > Configuración > Empresas Administradas**, editando el campo **"URL Logo Factura"**. Para personalizaciones más avanzadas del diseño, contacta con soporte técnico.
Sí. Con la API de Dinaup puedes integrar una interfaz de usuario propia con la marca de la franquicia.\
\
Para una integración así, consulta el listado de partners en [dinaup.com/partners](https://dinaup.com/partners).
## Integraciones y automatización [#integraciones-y-automatización]
Sí. Puedes conectar el TPV con n8n, Zapier o cualquier plataforma de automatización mediante webhooks y la API de Dinaup para crear flujos de trabajo personalizados.
Sí. Todas las ventas realizadas desde el TPV se sincronizan con el módulo de análisis de Pymes, donde puedes consultar métricas, gráficos y tendencias.
Sí. Puedes exportar las ventas, cierres de caja y libros de facturas en formato Excel o CSV para compartirlos con tu asesor fiscal o contable.
## Cumplimiento normativo [#cumplimiento-normativo]
Sí. El TPV es compatible con VeriFactu y cumple la normativa de facturación electrónica en España.
# TPV (/docs/rtg/tpv)
El **TPV** (punto de venta) de Dinaup es donde vendes, cobras en efectivo o tarjeta, emites el ticket y cierras la caja al final del turno. Funciona en **tablet** con pantalla táctil o en **PC** con ratón y teclado, para el mostrador de una tienda, la barra de un bar o el reparto a domicilio.
Cada venta **descuenta stock del inventario**, queda asociada al **cliente** y genera su **asiento contable**.
***
## Dos modos de pantalla [#dos-modos-de-pantalla]
El TPV se adapta al dispositivo desde el que trabajas. El modo se elige en la configuración y no cambia tus datos, solo la forma de operar.
| Modo | Dispositivo | Para qué |
| -------------- | -------------- | --------------------------------------------------------------------------------- |
| **Táctil** | Tablet o móvil | Botones grandes, sin teclado. Ideal para cobrar de pie en el mostrador o en sala. |
| **Escritorio** | PC con ratón | Vista más densa y con atajos. Ideal para puestos fijos con mucho volumen. |
***
## Para qué tipo de negocio [#para-qué-tipo-de-negocio]
Un mismo TPV cubre tres formas de vender, y puedes combinarlas si tu negocio lo necesita.
| Caso | Cómo trabaja el TPV |
| -------------------------- | ---------------------------------------------------------------------------------------------------- |
| **Retail / tienda** | Venta rápida sobre el mostrador: ticket y baja de stock al cobrar. |
| **Hostelería** | Mesas y comandas, cambios sobre la marcha y aviso a cocina. |
| **Delivery / para llevar** | Pedidos con dirección de entrega y seguimiento de estados (pendiente, preparando, listo, entregado). |
No tienes que elegir uno solo. Un bar con reparto puede atender mesas y pedidos a domicilio desde el mismo punto de venta.
***
## Conectado en directo con el resto de Dinaup [#conectado-en-directo-con-el-resto-de-dinaup]
El TPV no es una caja registradora aislada. Cada operación se sincroniza al momento con los demás módulos:
* **Inventario**: al cobrar, el stock del almacén que tengas asignado baja solo.
* **Clientes**: puedes vender a un cliente genérico para un ticket anónimo, o asociar la venta a un cliente registrado para llevar su histórico, descuentos y cobros pendientes.
* **Contabilidad**: cada venta y cada cierre generan sus apuntes sin que tengas que tocar nada.
* **Tesorería**: el cierre de caja del TPV vuelca el efectivo del turno a tu [caja de tesorería](/docs/rtg/pymes/tesoreria/cajas).
***
## Cómo empezar [#cómo-empezar]
Activa el punto de venta, elige modo y conéctalo a tu negocio.
Asocia el cajón de efectivo y el almacén desde el que descuentas stock.
Arquea el turno, cuadra el efectivo y vuelca el resultado a tesorería.
Bloquea el dispositivo para que solo se use como punto de venta.
***
## El recorrido de un turno [#el-recorrido-de-un-turno]
Un turno completo sigue siempre los mismos pasos:
| Paso | Qué haces |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Abre la caja** | Eliges la caja (cajón de dinero) y el almacén del que se descuenta stock. Si solo tienes uno de cada, se preselecciona. |
| **Haz la venta** | Eliges cliente (genérico o registrado) y añades productos por nombre, código o últimos usados. Ajustas cantidades, descuentos por línea o globales y, en delivery, la dirección de entrega. |
| **Cobra** | Forma de pago: efectivo (con cálculo de cambio), tarjeta, mixto o cobro parcial dejando el resto pendiente en la ficha del cliente. |
| **Entrega el comprobante** | Ticket o factura simplificada con datos fiscales. Imprime o envía por email. |
| **Cierra el turno** | Cuentas el efectivo real; Dinaup lo compara con lo esperado y avisa de descuadres. |
→ La guía completa del turno, en [El TPV de principio a fin](/docs/guias/tpv).
***
## Funcionalidades [#funcionalidades]
Vende rápido sobre el mostrador: busca productos, ajusta cantidades y aplica descuentos.
Cobra en efectivo, tarjeta, mixto o deja parte pendiente en la ficha del cliente.
Arquea el turno, cuadra el efectivo y vuelca el resultado a tesorería.
Cumple el Real Decreto 1007/2023 con facturación verificable desde el punto de venta.
El TPV comparte datos con Pymes: facturación, compras, tesorería e inventario.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Vale cualquiera de los dos. El modo táctil está pensado para tablet o móvil con botones grandes; el modo escritorio, para PC con ratón y atajos. Eliges el que encaje con tu puesto.
Sí. Al cobrar una venta, el stock del almacén asignado al TPV se descuenta sin que tengas que ajustarlo a mano.
Sí. Cada punto de venta trabaja con su propia caja y su almacén, y luego se consolidan en los informes globales.
El cierre de caja del TPV vuelca el efectivo del turno a tu caja de tesorería, así que no tienes que registrar a mano los cobros en metálico. Lo cuentas una vez al cerrar.
→ [Más preguntas frecuentes del TPV](/docs/rtg/tpv/faq-tpv)
***
→ [Procesos del TPV](/docs/rtg/tpv/procesos)
→ [Recursos](/docs/rtg/tpv/recursos)
→ [Cajas de tesorería](/docs/rtg/pymes/tesoreria/cajas)
# Modo kiosko (/docs/rtg/tpv/modo-kiosko)
### Qué es el modo kiosko [#qué-es-el-modo-kiosko]
El modo kiosko abre Dinaup ocupando toda la pantalla al encender el ordenador, sin escritorio de Windows ni acceso a otras aplicaciones. El equipo queda dedicado al punto de venta.
Qué aporta:
* El empleado solo ve Dinaup.
* Los tickets se imprimen solos, sin pulsar "Aceptar" cada vez.
* Menos errores y distracciones en el puesto de cobro.
***
### Antes de empezar [#antes-de-empezar]
**Importante: equipo dedicado**
El modo kiosko está pensado para ordenadores que se usan **exclusivamente** como terminal de cobro. No lo configures en un ordenador que también uses para otras tareas como consultar el correo, hacer pedidos a proveedores o llevar la contabilidad.
**Dinaup no ofrece soporte para configuraciones de modo kiosko en equipos de uso mixto.**
#### Lo que necesitas [#lo-que-necesitas]
* Un ordenador con Windows dedicado al punto de venta
* Google Chrome o Mozilla Firefox instalado
* Tu impresora de tickets configurada y funcionando
* Conexión a internet
***
### Configuración con Google Chrome [#configuración-con-google-chrome]
Chrome es la opción más sencilla. La impresión automática se activa directamente al abrir el navegador.
#### Crear el acceso directo [#crear-el-acceso-directo]
1. Haz clic derecho en el escritorio
2. Selecciona **Nuevo** → **Acceso directo**
3. Copia y pega esta línea en el campo de ubicación:
```
"C:\Program Files\Google\Chrome\Application\chrome.exe" -kiosk --kiosk-printing "https://play.dinaup.com"
```
4. Pulsa **Siguiente**
5. Ponle un nombre fácil de identificar, por ejemplo: **Dinaup TPV**
6. Pulsa **Finalizar**
#### Probarlo [#probarlo]
Haz doble clic en el acceso directo. Deberías ver Dinaup a pantalla completa, sin barras ni menús.
#### ¿Cómo salir? [#cómo-salir]
Pulsa `Alt + F4` en el teclado para cerrar el modo kiosko.
### Configuración con Mozilla Firefox [#configuración-con-mozilla-firefox]
Firefox también funciona, aunque requiere un paso adicional para activar la impresión automática.
#### Paso 1: Activar la impresión automática [#paso-1-activar-la-impresión-automática]
Antes de crear el acceso directo, hay que decirle a Firefox que imprima sin preguntar:
1. Abre Firefox de forma normal
2. Escribe `about:config` en la barra de direcciones y pulsa Enter
3. Aparecerá un aviso de precaución. Pulsa **Aceptar el riesgo y continuar**
4. En el buscador, escribe: `print.always_print_silent`
5. Si no aparece ningún resultado:
* Haz clic en el icono **+** que aparece a la derecha
* Selecciona que el valor sea **true** (verdadero)
6. Cierra Firefox
#### Paso 2: Crear el acceso directo [#paso-2-crear-el-acceso-directo]
1. Haz clic derecho en el escritorio
2. Selecciona **Nuevo** → **Acceso directo**
3. Copia y pega esta línea:
```
"C:\Program Files\Mozilla Firefox\firefox.exe" -kiosk "https://play.dinaup.com"
```
4. Pulsa **Siguiente**
5. Ponle nombre: **Dinaup TPV**
6. Pulsa **Finalizar**
#### ¿Cómo salir? [#cómo-salir-1]
Igual que con Chrome: pulsa `Alt + F4` en el teclado.
***
### Hacer que arranque solo al encender [#hacer-que-arranque-solo-al-encender]
Para que Dinaup se abra solo en modo kiosko al encender el ordenador:
1. Pulsa `Windows + R` en el teclado
2. Escribe `shell:startup` y pulsa Enter
3. Se abrirá una carpeta. Copia ahí el acceso directo que creaste antes
La próxima vez que enciendas el ordenador, Dinaup se abre solo en modo kiosko.
# Recursos (/docs/rtg/tpv/recursos)
## Iconos [#iconos]
Te dejamos un pack de iconos en formato cuadrícula para que puedas usarlos en tu TPV táctil. Están pensados para identificar las principales categorías de venta en bares, restaurantes o cafeterías.
### Hostelería [#hostelería]
### Peluquería [#peluquería]
# Ventana de venta (/docs/rtg/tpv/ventana-de-venta)
La ventana de venta es la pantalla central del TPV: el documento sobre el que añades productos, eliges el cliente y cierras la operación. Es la misma para una **venta**, un **pedido**, un **presupuesto** o una **compra**; cambia el color de la cabecera y poco más.
Se abre de dos formas: como **ventana** sobre el listado (al pulsar Iniciar o al abrir un registro existente) o a **pantalla completa** en `/App/TPV/POS`, pensada para el mostrador. El contenido es el mismo en ambas.
***
## Qué ves [#qué-ves]
La ventana se divide en tres zonas fijas.
### Barra superior [#barra-superior]
Ahí eliges con quién y cómo trabajas. Según el tipo de operación y tu configuración, aparecen unos campos u otros:
* **Cliente o proveedor**: el selector de la entidad de la operación. Puedes crearlo o abrir su ficha desde el mismo campo.
* **Datos fiscales**: los datos de facturación de esa entidad, cuando aplican.
* **Tipo de venta o compra** y **Categoría**: definen impuestos, numeración y almacén.
* **Envío**: la dirección de entrega, en ventas con reparto.
* **Almacén**: el almacén de la operación, si tienes más de uno.
* **Estado**, **Número** y **Fecha** del documento.
En **modo hostelería** la barra muestra el **Total** en grande en lugar de la fecha, para verlo de un golpe en la barra.
Junto a estos campos, una **píldora de validación** avisa si algo bloquea el cierre (ver [Validaciones](#validaciones)).
### Lista de conceptos [#lista-de-conceptos]
El cuerpo de la ventana. Aquí buscas productos y los vas sumando como líneas. Sobre cada línea cambias cantidad, precio o descuento, o la eliminas. En modo táctil, el buscador muestra las **categorías con imagen** y los productos en rejilla, con un contador de unidades por categoría.
El recorrido completo para montar la venta está en [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida).
### Pie de acciones [#pie-de-acciones]
La barra inferior reúne los botones de la operación:
| Botón | Qué hace |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Cobrar** | Abre la ventana de cobro. Solo en ventas. Si hay avisos, cambia de color; si hay errores, abre antes las validaciones. |
| **Aceptar** | Guarda la operación. Avisa si no hay conceptos. |
| **Imprimir** | Imprime el ticket o documento de la operación guardada. |
| **Flujo** | Abre el [Flujo (DataFlow)](/docs/rtg/tpv/dataflow) de la operación: cobros, stock y devoluciones. |
| **Abrir formulario** | Abre la ficha completa del registro, para los campos que no caben en el TPV. |
En ventas, tu empresa puede exigir cobrar para guardar. Si es el caso, el botón **Aceptar** no aparece en una venta nueva: cierras la operación desde **Cobrar**.
***
## Ventanas [#ventanas]
Desde la ventana de venta se abren estas ventanas secundarias:
* **Cobro**: eliges forma de pago, importe y cierras la venta. Detalle en [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro).
* **Flujo (DataFlow)**: cobros, entradas y salidas de stock y devoluciones de la operación. Detalle en [DataFlow](/docs/rtg/tpv/dataflow).
* **Convertir divisa**: pasa los importes del documento de una divisa a otra. Detalle en [Convertir divisa](/docs/rtg/tpv/convertir-divisa).
* **Almacenes y accesos**: abre desde **Ver accesos**. Lista todos los almacenes de la empresa y marca cuáles tienes disponibles en el TPV, para entender por qué un almacén no te aparece.
* **Validaciones**: ver abajo.
***
## Validaciones [#validaciones]
Antes de cerrar una venta, el TPV comprueba que todo cuadra. La **píldora de validación** de la barra superior resume el resultado:
* **Sin avisos**: puedes cobrar y guardar con normalidad.
* **Avisos**: hay algo que revisar (por ejemplo, stock por debajo de lo que vendes), pero puedes continuar. El botón **Cobrar** o **Aceptar** se marca en amarillo.
* **Errores**: algo impide cerrar la operación. El botón se marca en rojo y, al pulsarlo, se abre la ventana de validaciones con el detalle de qué falta.
Los datos fiscales de la empresa se comprueban al entrar al TPV. Sin CIF ni datos de facturación completos, el TPV no te deja emitir tickets.
***
→ [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida)
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
→ [DataFlow](/docs/rtg/tpv/dataflow)
→ [Convertir divisa](/docs/rtg/tpv/convertir-divisa)
# Análisis (/docs/rtg/recursos-humanos/analisis)
El análisis de RRHH convierte todo lo que tu equipo ya registra cada día (fichajes, turnos, ausencias) en **indicadores claros**. Tomas decisiones de personal con datos en vez de con intuición. No tienes que introducir nada nuevo: Dinaup agrega la información del [control horario](/docs/rtg/recursos-humanos/control-horario), los [fichajes](/docs/rtg/recursos-humanos/fichaje) y las [ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias) y te la presenta lista para leer.
Sirve para responder preguntas concretas: ¿quién acumula más retrasos?, ¿estamos cumpliendo las horas previstas?, ¿qué persona falta más de lo normal?, ¿dónde se va el tiempo del equipo?
***
## Para qué sirve [#para-qué-sirve]
Tomar decisiones de personal con respaldo. Algunos usos típicos:
* **Detectar problemas a tiempo**: un empleado que encadena retrasos o ausencias salta a la vista antes de que se convierta en un conflicto.
* **Repartir mejor la carga**: comparas horas trabajadas entre personas y ves quién está saturado y quién tiene margen.
* **Preparar una conversación**: llegas a la reunión con cifras objetivas, no con impresiones.
* **Justificar decisiones**: refuerzos de plantilla, ajustes de horario o reconocimientos apoyados en datos.
El análisis **lee** datos, no los modifica. Si una cifra no cuadra, el origen está en el fichaje o el turno correspondiente: corrígelo ahí (con justificación) y el indicador se recalcula. Los registros de fichaje son inmutables; lo que se ajusta es el tiempo imputado, no el fichaje original.
***
## Indicadores de plantilla [#indicadores-de-plantilla]
Estos son los indicadores que Dinaup calcula a partir de la actividad registrada. Se pueden mirar para toda la plantilla o para un empleado concreto.
| Indicador | Qué mide | Para qué te sirve |
| --------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| **Horas trabajadas vs. teóricas** | Las horas reales fichadas frente a las que marca el horario asignado. | Ver si el equipo cumple la jornada prevista, detectar exceso o defecto de horas. |
| **Puntualidad** | La media de minutos de retraso sobre la hora de entrada programada. | Identificar patrones de impuntualidad por persona o por equipo. |
| **Ausencias totales** | El total de ausencias, separando las **justificadas** de las que están **sin justificar**. | Medir el absentismo real y distinguir lo cubierto (vacaciones, bajas, permisos) de lo que requiere atención. |
| **Productividad por empleado** | La actividad de cada persona puesta una al lado de otra. | Comparar el rendimiento dentro de un mismo equipo y repartir la carga con criterio. |
### Horas trabajadas vs. teóricas [#horas-trabajadas-vs-teóricas]
Las **horas teóricas** salen del horario que cada empleado tiene asignado: son las que *debería* hacer según su jornada. Las **horas trabajadas** son las que realmente ha fichado. La diferencia entre ambas es la señal más directa de si la jornada se está cumpliendo.
Un desajuste no siempre es un problema: puede deberse a una ausencia justificada, un turno extra o una corrección pendiente. El indicador te dice *dónde mirar*, no *qué hacer*.
### Puntualidad [#puntualidad]
Mide la **media de minutos de retraso** respecto a la hora de entrada prevista. Un retraso puntual no dice nada; una media alta y sostenida sí. Cruzar este indicador con la persona y el periodo te ayuda a distinguir un mal día de un hábito.
### Ausencias totales [#ausencias-totales]
Suma las ausencias del periodo y las separa en dos grupos:
* **Justificadas**: tienen un motivo asignado (vacaciones, baja médica, permiso, formación…).
* **Sin justificar**: el empleado no vino y no hay motivo registrado.
Esta distinción es la clave del absentismo. Una plantilla con muchas ausencias *justificadas* está funcionando bien; una con ausencias *sin justificar* necesita seguimiento. Si ves ausencias sin justificar, el sitio para resolverlas es la [línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo), asignando el motivo a cada turno.
### Productividad por empleado [#productividad-por-empleado]
Pone la actividad de cada persona en comparación con la del resto de su equipo: horas cumplidas, puntualidad y ausencias, persona a persona. El valor no está en el número aislado, sino en la **comparación**: ver quién está por encima y quién por debajo de la media del equipo.
Lee estos indicadores en contexto. Un empleado con menos horas puede estar a media jornada; otro con más ausencias puede arrastrar una baja médica larga. Los datos señalan, pero la decisión es tuya.
***
## La línea de tiempo del empleado [#la-línea-de-tiempo-del-empleado]
Donde los indicadores te dan la foto agregada, la **línea de tiempo** te da el detalle día a día de una sola persona. Es la vista a la que bajas cuando un indicador te ha hecho saltar una alarma y quieres entender qué pasó exactamente.
En una sola línea por jornada ves, superpuesto:
* **Turnos**: lo que estaba programado.
* **Fichajes**: lo que realmente ocurrió (entradas y salidas).
* **Ausencias**: los días sin actividad y su motivo, si lo tienen.
* **Festivos**: los días no laborables del calendario asignado.
* **Eventos y tareas**: hitos y trabajo asociado al empleado.
Distingues una jornada correcta, un fichaje sin cierre, una ausencia justificada o una ausencia sin justificar. Es la herramienta para **auditar un caso concreto** y, si hace falta, corregirlo en su origen.
→ [Cómo interpretar la línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo)
***
## De los datos a la decisión [#de-los-datos-a-la-decisión]
El análisis cierra el círculo del módulo de RRHH:
### El equipo trabaja y ficha [#el-equipo-trabaja-y-ficha]
Los [empleados](/docs/rtg/recursos-humanos/empleados) cumplen sus [turnos](/docs/rtg/recursos-humanos/turnos) y fichan desde móvil, tótem o web. Cada jornada queda registrada.
### Dinaup agrega los indicadores [#dinaup-agrega-los-indicadores]
Sin que tengas que hacer nada, esa actividad se convierte en horas trabajadas vs. teóricas, puntualidad y ausencias totales.
### Detectas dónde mirar [#detectas-dónde-mirar]
Un indicador fuera de lo normal (demasiados retrasos, horas por debajo, ausencias sin justificar) te dice qué persona o equipo merece atención.
### Bajas al detalle y actúas [#bajas-al-detalle-y-actúas]
Abres la [línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo) del empleado, entiendes el caso concreto y tomas la decisión: corregir un fichaje, hablar con la persona, reforzar el equipo o reconocer un buen rendimiento.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Los indicadores se calculan solos a partir de los fichajes, los turnos y las ausencias que ya registras. El análisis solo lee y agrega esa información.
Las horas teóricas son las que el empleado debería hacer según su horario asignado. Las trabajadas son las que realmente ha fichado. La diferencia te indica si se está cumpliendo la jornada prevista.
Cuenta en el total de ausencias, pero se separa de las ausencias sin justificar. Lo relevante para el seguimiento son las ausencias sin justificar: las justificadas (vacaciones, bajas, permisos) ya tienen un motivo registrado.
El indicador refleja lo que hay en el fichaje o el turno de origen. Corrige ahí el dato (por ejemplo, ajustando un turno o asignando el motivo de una ausencia desde la línea de tiempo) y el indicador se recalculará. El fichaje original es inmutable; lo que se ajusta es el tiempo imputado.
***
→ [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo)
→ [Control horario](/docs/rtg/recursos-humanos/control-horario)
→ [Historial de fichaje](/docs/rtg/recursos-humanos/fichaje)
→ [Empleados](/docs/rtg/recursos-humanos/empleados)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
# Cargos (/docs/rtg/recursos-humanos/cargos)
Un **cargo** es la función que ocupa un empleado dentro de la empresa: comercial, administrativo, encargado, técnico, repartidor… Es el "qué hace" de la persona. Junto con el [departamento](/docs/rtg/recursos-humanos/departamentos) (el "dónde encaja"), forma la base con la que organizas tu plantilla y describes el puesto de cada empleado.
***
## Cargo frente a departamento [#cargo-frente-a-departamento]
Los dos clasifican a un [empleado](/docs/rtg/recursos-humanos/empleados), pero responden a preguntas distintas y se complementan. Un empleado tiene un departamento y un cargo a la vez.
| | Cargo | [Departamento](/docs/rtg/recursos-humanos/departamentos) |
| ---------------- | --------------------------------------------- | -------------------------------------------------------- |
| Qué responde | Qué función desempeña la persona | En qué parte de la empresa trabaja |
| Ejemplos | Comercial, administrativo, encargado, técnico | Ventas, Administración, Almacén |
| Cómo se organiza | Lista de funciones de la empresa | Estructura jerárquica (sede → departamento → equipo) |
Dos personas del mismo departamento pueden tener cargos distintos: en **Ventas** puedes tener un **encargado** y varios **comerciales**. Y un mismo cargo, como **administrativo**, puede repetirse en varios departamentos.
***
## Para qué sirve [#para-qué-sirve]
Asignar un cargo a cada empleado te da tres cosas:
* **Organización de la plantilla.** Sabes quién hace qué sin abrir la ficha de cada persona.
* **Responsabilidades claras.** El cargo describe la función esperada y sirve de base para repartir trabajo.
* **Análisis y filtrado.** Puedes agrupar y filtrar a tu equipo por cargo para responder preguntas como "¿cuántos comerciales tengo?" o "¿qué encargados hay por sede?".
***
## Crear un cargo [#crear-un-cargo]
### Abre los cargos de RRHH [#abre-los-cargos-de-rrhh]
Ve a **RRHH → Cargos**. Ahí tienes la lista de funciones que existen en tu empresa.
### Añade un cargo nuevo [#añade-un-cargo-nuevo]
Crea el cargo y dale un nombre claro que describa la función (por ejemplo, *Comercial* o *Encargado de almacén*). Usa siempre el mismo nombre para la misma función, así los listados y filtros quedan limpios.
### Reutilízalo en toda la plantilla [#reutilízalo-en-toda-la-plantilla]
Un cargo se crea una vez y se asigna a todos los empleados que desempeñen esa función. No hace falta crear un cargo por persona.
Define los cargos antes de dar de alta a tu equipo. Así, al crear cada empleado, solo tienes que elegir su función de la lista en lugar de escribirla a mano.
***
## Asignar un cargo a un empleado [#asignar-un-cargo-a-un-empleado]
El cargo se asigna desde la ficha del empleado, junto con su departamento, dentro de sus datos laborales.
### Abre la ficha del empleado [#abre-la-ficha-del-empleado]
Ve a **RRHH → Empleados** y entra en la persona que quieras configurar (o créala si aún no existe).
### Elige su departamento y su cargo [#elige-su-departamento-y-su-cargo]
En los datos laborales, selecciona el [departamento](/docs/rtg/recursos-humanos/departamentos) al que pertenece y el **cargo** que desempeña. Ambos se eligen de las listas que ya tienes creadas.
### Guarda [#guarda]
Con el cargo asignado, el empleado queda clasificado y aparecerá agrupado por su función en los listados y análisis de tu equipo.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El cargo es la función que desempeña la persona (comercial, administrativo, encargado). El departamento es la parte de la empresa donde trabaja (Ventas, Administración, Almacén). Cada empleado tiene los dos a la vez.
Sí. Un cargo se crea una vez y se asigna a todas las personas que desempeñan esa función. Lo normal es tener varios empleados compartiendo cargo.
En la ficha del empleado, dentro de sus datos laborales, junto con el departamento. Se elige de la lista de cargos que ya tienes creada.
Para organizar la plantilla, dejar claras las responsabilidades de cada persona y poder filtrar y agrupar a tu equipo por función al analizarlo.
***
→ [Departamentos](/docs/rtg/recursos-humanos/departamentos)
→ [Empleados](/docs/rtg/recursos-humanos/empleados)
# Configuración (/docs/rtg/recursos-humanos/configuracion)
La pantalla de **Configuración** reúne los catálogos que alimentan el resto del módulo de Recursos Humanos. Vive en **Recursos Humanos → Más → Configuración**.
Un menú lateral agrupa los ajustes por bloques. Cada opción abre su tabla, donde das de alta y editas los registros. Solo ves los bloques sobre los que tu usuario tiene permiso de lectura.
***
## Qué configuras aquí [#qué-configuras-aquí]
| Bloque | Ajustes | Para qué sirve |
| --------------------------- | -------------------------------- | ---------------------------------------------------------- |
| **Horarios** | Jornadas, Horarios, Asignaciones | Las plantillas de horas y su vínculo con cada empleado |
| **Departamentos** | Departamentos, Subdepartamentos | La estructura de áreas de la empresa |
| **Vacaciones & Ausencias** | Tipos | Los motivos por los que un empleado no trabaja |
| **Correspondencia interna** | Tipos, Estados | Cómo se clasifican y en qué estado avanzan los comunicados |
| **Incentivos** | Objetivos de venta | Las metas de venta que premian a la plantilla |
***
## Dónde se usa cada catálogo [#dónde-se-usa-cada-catálogo]
Lo que defines aquí es la base de las pantallas del día a día:
* Las **jornadas, horarios y asignaciones** son la materia prima de los [turnos](/docs/rtg/recursos-humanos/turnos) y el [planificador](/docs/rtg/recursos-humanos/planificador).
* Los **tipos de ausencia** son los [motivos de ausencia](/docs/rtg/recursos-humanos/motivos-de-ausencia) que asignas a un turno sin fichar o a una solicitud.
* Los **tipos y estados de correspondencia** clasifican cada [correspondencia](/docs/rtg/recursos-humanos/correspondencias).
* Los **objetivos de venta** son la base de los [incentivos y comisiones](/docs/rtg/recursos-humanos/incentivos-y-comisiones).
***
→ [Horarios](/docs/rtg/recursos-humanos/horarios)
→ [Departamentos](/docs/rtg/recursos-humanos/departamentos)
→ [Motivos de ausencia](/docs/rtg/recursos-humanos/motivos-de-ausencia)
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
# Contratos (/docs/rtg/recursos-humanos/contratos)
Un **contrato** guarda la relación laboral de un empleado: el vínculo formal que Dinaup usa como referencia al calcular el calendario de trabajo de cada día.
La pantalla vive en **Recursos Humanos → Personas → Contratos**. Solo aparece si tu usuario tiene permiso de lectura sobre los contratos laborales.
***
## Qué ves [#qué-ves]
La pantalla muestra el **listado de contratos** de tu empresa en una tabla. Cada fila es un contrato, con las columnas que tenga definido el informe. Desde la barra de herramientas filtras, ordenas y buscas dentro de la lista.
Junto a los datos tienes una pestaña de **notas** para dejar anotaciones internas asociadas a esta pantalla.
***
## Qué puedes hacer [#qué-puedes-hacer]
| Acción | Dónde |
| ----------------- | -------------------------------------------------------------------- |
| Crear un contrato | Botón **Contratos** del menú lateral, o el botón de alta de la tabla |
| Abrir un contrato | Clic en su fila |
| Filtrar y ordenar | Barra de herramientas de la tabla |
| Anotar | Pestaña de notas de la pantalla |
Al crear un contrato se abre el formulario de alta con los campos de la ficha del contrato.
***
## Dónde aparece el contrato [#dónde-aparece-el-contrato]
El contrato de cada empleado se cruza con el resto del módulo. Al revisar un día concreto en el [editor de fichaje](/docs/rtg/recursos-humanos/perfil-de-trabajador/editar-fichaje), Dinaup muestra el contrato vigente ese día junto al horario y los festivos, como contexto de la jornada.
***
→ [Empleados](/docs/rtg/recursos-humanos/empleados)
→ [Nóminas](/docs/rtg/recursos-humanos/nominas)
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
# Control horario (/docs/rtg/recursos-humanos/control-horario)
El control horario de Dinaup separa tres cosas que a menudo se mezclan: lo que un empleado **debería trabajar**, lo que **cuenta como trabajado** y la **prueba de lo que marcó en el reloj**. Cada una vive en su sitio y no se pisa con las otras.
| Pieza | Qué es | ¿Se edita? |
| ----------- | ---------------------------------------------------------------------------------- | ------------------------------------------------ |
| **Horario** | La planificación: qué jornada toca cada día de la semana. | Sí, en configuración. |
| **Turno** | El registro oficial de cada día: programado y realizado. Es lo que llega a nómina. | Sí, un responsable lo corrige con justificación. |
| **Fichaje** | La marca física de entrada y salida en el reloj. | No. Es la prueba para una inspección de trabajo. |
Si un empleado olvida fichar la salida, corriges el **turno**. El fichaje se queda tal cual: su valor es precisamente que nadie lo puede retocar.
## Los turnos del día se crean solos [#los-turnos-del-día-se-crean-solos]
Cada día, Dinaup genera los turnos de cada empleado activo a partir de su horario asignado. Un horario define qué **jornada** toca cada día de la semana, y cada jornada se compone de tramos: mañana, descanso, tarde.
Para que esto funcione, cada empleado necesita:
* Estar marcado como **Activo**.
* Tener un **horario asignado** vigente. [Asignar horario a empleado](/docs/rtg/recursos-humanos/procesos/asignar-horario-a-empleado)
* Tener un **calendario de festivos**. [Crear un calendario de festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos)
Al crear los turnos, el sistema revisa si ese día hay festivo o una ausencia ya registrada (vacaciones, baja, permiso) y lo anota en el propio turno. Una ausencia justificada no resta horas al saldo del empleado.
Los turnos se generan para el día en curso, no hacia atrás. Si registras una ausencia después de que el turno exista, edita el turno y asigna el motivo desde su ficha.
## Márgenes y políticas [#márgenes-y-políticas]
La configuración vive en la empresa y aplica a todos sus empleados:
| Opción | Qué controla | Valor inicial |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------ | ---------------------------- |
| **Margen de inicio anticipado** | Cuántos minutos antes de su hora puede fichar un empleado y quedar enlazado a su turno. | 15 minutos |
| **Margen de cierre** | Cuánto espera el sistema tras el fin oficial del turno antes de cerrar solo un fichaje olvidado. | 240 minutos |
| **Política para fichajes sin turno** | Qué pasa si alguien ficha sin turno programado: crear un turno fuera de horario, o impedir el fichaje. | Crear turno fuera de horario |
Con margen anticipado de 15 minutos, un empleado con turno a las 8:00 puede fichar desde las 7:45 y su fichaje cuenta como entrada de ese turno. Si ficha antes de las 7:45, se aplica la política de fichajes sin turno.
## Qué pasa si alguien olvida fichar la salida [#qué-pasa-si-alguien-olvida-fichar-la-salida]
El sistema cierra el fichaje solo, siguiendo dos reglas:
* **Con turno programado**: al pasar el fin oficial más el margen de cierre, el fichaje se cierra con la **hora oficial de fin**, no con la hora del cierre. Un turno de 8:00 a 17:00 con margen de 60 minutos se cierra a las 18:00, y la salida registrada es las 17:00.
* **Sin turno programado** (turno fuera de horario): a las 12 horas de la entrada, como tope de seguridad.
En ambos casos el turno queda marcado como **salida automática**, y la línea de tiempo lo señala con un aviso para que un responsable lo revise. El panel de inicio de Recursos Humanos agrupa estos casos en **Olvidos de salida**.
## Los descansos no se fichan [#los-descansos-no-se-fichan]
Los descansos que declaras en una jornada son **informativos** para el fichaje: nadie pasa por el reloj por un descanso. El empleado sigue fichado durante el café.
| Descanso | Cómo se define | ¿Computa como trabajado? | Ejemplo |
| ----------------- | ------------------------------------------ | ------------------------------------- | --------------------------------- |
| **Retribuido** | Dentro del tramo de trabajo, sin partirlo. | Sí, dentro del derecho de la jornada. | El café de media mañana. |
| **No retribuido** | Como hueco entre dos tramos de trabajo. | No | La comida en una jornada partida. |
El **descanso retribuido** vive dentro de la jornada continua: el empleado ficha a las 9:00 y a las 14:00, el café corre por dentro y computa como horas efectivas. La jornada declara su derecho en **Tiempo de descanso retribuido (minutos)**.
El **descanso no retribuido** es un hueco: la jornada partida se define con dos tramos de trabajo (9:00-14:00 y 15:00-18:00) y la comida queda en medio, sin computar. El empleado ficha la salida al irse y la entrada al volver, como en cualquier salida y entrada.
Si tu empresa quiere medir las pausas, existe una pantalla propia para registrarlas, separada del fichaje: las pausas retribuidas dentro del derecho siguen contando como trabajo, y se descuentan el exceso y las pausas no retribuidas. Detalle en [Descansos](/docs/rtg/recursos-humanos/descansos).
## Turnos que cruzan la medianoche [#turnos-que-cruzan-la-medianoche]
Un turno de 22:00 a 6:00 es normal en hostelería y en industria. Dinaup lo registra en el día en que **empieza** el turno y calcula las horas de forma continua: de 22:00 a 6:00 son 8 horas, no un error de calendario.
El cierre automático también lo respeta: si el empleado olvida fichar la salida, el fichaje se cierra con la hora oficial de fin, aunque caiga en el día siguiente.
## Zona horaria por empleado [#zona-horaria-por-empleado]
El inicio del día y las horas de cada turno se calculan con la **zona horaria de la ficha del empleado** (o la de la empresa, si no tiene una propia). Con equipo en varias regiones, cada jornada se registra en la hora local de la persona.
## El ciclo de un día, sección a sección [#el-ciclo-de-un-día-sección-a-sección]
Dos secciones guardan el control horario, y cada una tiene sus escritores fijos:
| Momento | Turnos de trabajo | Historial de fichajes |
| ---------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| De madrugada | Nacen los turnos del día desde el horario (estado Programada). | Nada. |
| El empleado ficha la entrada | Nada. | Nace el fichaje: hora, IP, huella, GPS. |
| Cada minuto | El sistema compara turnos y fichajes por solape y actualiza estado, horas, retrasos y saldos. | Nada. |
| El empleado ficha la salida | Nada directo: al minuto, el turno queda Presente con su realización. | El fichaje se completa con la salida y no se toca nunca más. |
| Ficha tiempo sin turno | El sistema agrega ese tiempo en un turno adicional del día. | El fichaje se registra igual. |
| Olvida la salida | El turno queda con lo cubierto hasta el fin oficial. | El sistema completa el fichaje con la hora oficial de fin. |
| Un responsable corrige | Se reescriben los turnos del día: los planificados y los reconocidos. Los reconocidos mandan. | Intacto. La corrección queda en el log legal. |
El fichaje nunca escribe en los turnos, y nada escribe nunca en un fichaje cerrado.
## De dónde salen las horas y los saldos [#de-dónde-salen-las-horas-y-los-saldos]
De **Turnos de trabajo**, siempre. Los saldos de cada turno (horas de plan, horas realizadas, extras, complementarias) los calcula el sistema comparando el plan con los fichajes, y son lo que leen los indicadores, la exportación y la nómina. El fichaje guarda sus propios minutos solo como dato informativo: ningún informe agrega desde fichajes.
## Preguntas frecuentes [#preguntas-frecuentes]
No. Fichar solo crea o completa el registro del fichaje. El sistema compara después los fichajes con los turnos del día y actualiza los turnos por su cuenta.
De los turnos de trabajo. Los fichajes son la prueba; los turnos son la cuenta.
El fichaje no se toca: es la prueba de lo que marcó el reloj. Un responsable abre el día en la línea de tiempo, ajusta el horario realizado y acepta. Esa corrección pasa a ser la verdad del día y queda trazada en el log legal, con el fichaje original intacto.
Los minutos cubiertos. Con turno de 9:00 a 14:00 y fichajes de 10:00 a 11:00 y de 13:00 a 13:30, el turno registra 90 minutos realizados de 300, con la primera entrada a las 10:00.
Según la política de la empresa: se registra como tiempo fuera de plan en un turno adicional del día, o se rechaza el fichaje.
Ninguna de las dos. El retraso nunca es negativo, y el tiempo fichado antes del inicio del turno cuenta como tiempo fuera de plan, no infla el turno.
## Dónde se supervisa [#dónde-se-supervisa]
* [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo): el día entero de cada empleado en cuatro barras: programado, realizado, fichaje y ausencias.
* [Turnos](/docs/rtg/recursos-humanos/turnos): la lista completa de turnos, con saldos y estados.
* [Turnos sin fichar](/docs/rtg/recursos-humanos/turnos-sin-fichar): las ausencias pendientes de justificar.
* [Exportar](/docs/rtg/recursos-humanos/exportar): el informe anual por empleado, listo para una inspección.
Para el registro físico de entradas y salidas, sigue en [Fichaje](/docs/rtg/recursos-humanos/fichaje).
# Departamentos (/docs/rtg/recursos-humanos/departamentos)
Un **departamento** es una unidad organizativa de tu empresa. Los departamentos forman la estructura jerárquica de la plantilla (de lo general a lo concreto, **sede → departamento → equipo**) y cada empleado pertenece a uno. Es el esqueleto sobre el que ordenas a las personas, repartes permisos por área y segmentas el análisis.
***
## Para qué sirve [#para-qué-sirve]
La estructura de departamentos no es solo un organigrama bonito: condiciona cómo funciona el día a día en RRHH. Tres usos concretos:
* **Organizar la plantilla.** Cada empleado vive dentro de un departamento, así que sabes quién pertenece a qué área. Los listados, fichajes y planificadores se pueden agrupar y filtrar por departamento.
* **Gestionar permisos por área.** La jerarquía es la base para decidir quién ve y gestiona a quién. Un responsable de área accede a la información de su departamento; RRHH accede a toda la plantilla.
* **Segmentar el análisis.** Al consultar productividad, ausencias o nóminas, puedes acotar por departamento y comparar áreas entre sí, en lugar de mirar la empresa como un único bloque.
***
## La jerarquía: sede, departamento, equipo [#la-jerarquía-sede-departamento-equipo]
La estructura se lee de arriba abajo, de la unidad más amplia a la más pequeña:
| Nivel | Qué representa | Ejemplo |
| ---------------- | ----------------------------------------- | ------------------------------- |
| **Sede** | El centro de trabajo o ubicación física | Oficina central, Tienda Madrid |
| **Departamento** | El área funcional dentro de la sede | Ventas, Administración, Almacén |
| **Equipo** | El grupo concreto dentro del departamento | Ventas Norte, Soporte N1 |
No estás obligado a usar los tres niveles. Una empresa pequeña puede tener solo un par de departamentos colgando de una sede; una grande puede anidar varios niveles hasta llegar al equipo. Crea solo la profundidad que de verdad necesitas para ordenar a tu gente.
Cada departamento puede tener un **responsable** asignado. Ese responsable es la referencia del área y la pieza sobre la que se apoyan los permisos: quién gestiona a quién dentro de la estructura.
***
## Crear la estructura [#crear-la-estructura]
### Abre los departamentos [#abre-los-departamentos]
Ve a **RRHH → Departamentos**. Ahí ves la estructura jerárquica completa de tu empresa, con cada departamento colgando del nivel que le corresponde.
### Crea el primer nivel [#crea-el-primer-nivel]
Añade tus departamentos de mayor nivel (por ejemplo, las sedes o las grandes áreas) y dales un nombre claro que cualquiera reconozca. Empieza por lo amplio: ya irás bajando.
### Anida departamentos y equipos [#anida-departamentos-y-equipos]
Cuelga los departamentos y equipos más concretos dentro de los de nivel superior hasta reflejar tu organización real. Así reconstruyes el árbol **sede → departamento → equipo** con la profundidad que necesites.
### Asigna un responsable [#asigna-un-responsable]
A cada departamento puedes asignarle un responsable. Es quien encabeza el área y la base sobre la que se reparten después los permisos de gestión.
Monta la estructura **antes** de dar de alta a la plantilla. Si los departamentos ya existen, al crear cada empleado solo tienes que elegir el suyo en un desplegable.
***
## Asignar empleados a un departamento [#asignar-empleados-a-un-departamento]
El departamento se asigna desde la ficha de cada empleado, dentro de sus datos laborales. Cuando das de alta a alguien, eliges su departamento igual que eliges su [cargo](/docs/rtg/recursos-humanos/cargos) o su horario.
Un empleado pertenece a un departamento, y ese vínculo es lo que después alimenta los filtros de los listados, la agrupación en el planificador y el alcance de los permisos por área.
→ [Cómo dar de alta a un empleado](/docs/rtg/recursos-humanos/empleados)
***
## Departamentos y cargos [#departamentos-y-cargos]
Departamento y cargo responden a dos preguntas distintas sobre la misma persona:
| | Departamento | [Cargo](/docs/rtg/recursos-humanos/cargos) |
| ---------- | ----------------------------------------- | ------------------------------------------ |
| Responde a | **Dónde** trabaja la persona | **Qué** hace la persona |
| Define | El área u ubicación en la organización | El puesto o rol y sus responsabilidades |
| Estructura | Jerárquica (sede → departamento → equipo) | Catálogo de puestos |
Dos personas del mismo departamento pueden tener cargos distintos (un responsable de ventas y un comercial conviven en **Ventas**), y dos personas con el mismo cargo pueden estar en departamentos distintos (un administrativo en la sede central y otro en una sucursal).
***
## Preguntas frecuentes [#preguntas-frecuentes]
La profundidad que necesites. El modelo va de la sede al equipo (sede → departamento → equipo), pero no estás obligado a usar todos los niveles: una empresa pequeña puede tener solo unos pocos departamentos bajo una sede.
Cada empleado pertenece a un departamento, el que eliges en su ficha de datos laborales. Ese vínculo es el que alimenta los filtros, la agrupación y los permisos por área.
Es la referencia del área y la base de los permisos de gestión: quién accede y gestiona a quién dentro de la estructura. RRHH, por su parte, accede a toda la plantilla.
El departamento dice dónde está la persona dentro de la organización (su área); el cargo dice qué hace (su puesto). Son independientes: mismo departamento con cargos distintos, o mismo cargo en departamentos distintos.
***
→ [Empleados](/docs/rtg/recursos-humanos/empleados)
→ [Cargos](/docs/rtg/recursos-humanos/cargos)
# Descansos (/docs/rtg/recursos-humanos/descansos)
Un **descanso** es una pausa dentro de la jornada: el café, un paseo, una llamada personal. No se ficha salida para tomarlo. El empleado lo registra en la pantalla de descansos, sigue fichado y el sistema mide cuánto duró.
El descanso y el fichaje son registros separados. Fichar salida significa que te vas; iniciar un descanso significa que sigues en tu jornada. Registrar un descanso no toca los fichajes ni los turnos.
## Poner en marcha la pantalla de descansos [#poner-en-marcha-la-pantalla-de-descansos]
La pantalla de descansos es una página web con URL propia de tu empresa, separada de la de fichaje. Sirve en el mismo tótem, tablet o móvil.
### Define los tipos de descanso [#define-los-tipos-de-descanso]
En la sección **Tipos de Descansos** de tu Dinaup, crea el catálogo: Café, Paseo, Llamada. Cada tipo declara su etiqueta, si es retribuido y su duración máxima en minutos.
### Declara los descansos en la jornada [#declara-los-descansos-en-la-jornada]
En cada **definición de jornada**, elige hasta 4 descansos seleccionables y los minutos de **descanso retribuido** a los que da derecho ese día. Solo los descansos declarados en la jornada aparecen en la pantalla.
### Copia la URL de descansos [#copia-la-url-de-descansos]
Abre **Recursos Humanos → Inicio**. La URL de descansos aparece junto a la de fichaje, lista para copiar y abrir en el dispositivo que haga de reloj.
## Iniciar y detener un descanso [#iniciar-y-detener-un-descanso]
El empleado escribe su identificador y pulsa **Ver mis descansos**. La pantalla le enseña sus descansos disponibles bajo **Elige tu descanso**, con la duración máxima de cada uno, y los minutos que lleva descansados hoy. Pulsa uno y empieza a contar. Al volver, se identifica otra vez y pulsa **Detener descanso**.
Un empleado solo puede tener un descanso en curso. Si el tipo tiene duración máxima y nadie lo detiene, el sistema lo cierra solo al llegar al límite.
## Cómo computan los descansos [#cómo-computan-los-descansos]
| Situación | Qué computa |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Descanso retribuido dentro del derecho de la jornada | Cuenta como tiempo trabajado. No descuenta nada. |
| Descanso retribuido por encima del derecho | El exceso es tiempo no trabajado: se descuenta. |
| Descanso no retribuido | Se descuenta entero. |
| Nadie registró descansos ese día | Se entiende que el empleado hizo el descanso declarado en su horario. No descuenta nada. |
El cálculo lo hace la [exportación de horarios](/docs/rtg/recursos-humanos/exportar): el Excel legal muestra las columnas **Horas descansadas** y **Exceso descanso**, y descuenta el exceso de las horas trabajadas del día.
## Dónde se ven [#dónde-se-ven]
* En la [línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo), cada empleado tiene una fila **Descansos** con sus pausas del día y el total descansado.
* En la sección **Historial de Descansos** de tu Dinaup, cada registro guarda inicio, fin, duración, tipo y los datos del dispositivo, igual que un fichaje.
## Preguntas frecuentes [#preguntas-frecuentes]
No. El empleado sigue fichado durante el descanso. Solo registra la pausa en la pantalla de descansos, si tu empresa la usa.
No pasa nada. El sistema entiende que cada empleado hizo el descanso declarado en su jornada y no descuenta tiempo. Registrarlos aporta detalle, no es obligatorio.
El sistema lo cierra solo al llegar a la duración máxima del tipo. Si el tipo no declara máximo, se aplica un tope de seguridad de 4 horas.
La jornada de hoy de ese empleado no declara descansos seleccionables. Se añaden en la definición de jornada, en la configuración de horarios.
Solo lo que exceda del derecho declarado en la jornada. Con 20 minutos de derecho y 15 de café, no se descuenta nada; con 30 de café, se descuentan 10.
No. Son un registro aparte. Los turnos y los fichajes siguen funcionando igual con o sin descansos registrados.
Para el modelo completo de horarios, turnos y fichajes, sigue en [Control horario](/docs/rtg/recursos-humanos/control-horario).
# Drive (/docs/rtg/recursos-humanos/drive)
**Drive** es el espacio de archivos del módulo de Recursos Humanos. Guardas aquí la documentación del área y la tienes a mano desde **Recursos Humanos → Más → Drive**.
***
## Qué ves [#qué-ves]
Un **explorador de archivos**: la vista de carpetas y documentos del módulo. Navegas entre ellos, los abres y subes los tuyos, como en cualquier gestor de archivos.
Estos documentos pertenecen al ámbito de Recursos Humanos y son distintos de los archivos personales o de departamento que cada empleado tiene en su [área de empleado](/docs/rtg/area-de-empleado).
***
## Qué puedes hacer [#qué-puedes-hacer]
* **Navegar** entre carpetas y documentos.
* **Abrir** un archivo.
* **Subir** documentos nuevos.
***
→ [Área de empleado](/docs/rtg/area-de-empleado)
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
# Empleados (/docs/rtg/recursos-humanos/empleados)
En Dinaup, los **empleados** se gestionan como usuarios del sistema. Esto permite asignarles permisos, horarios, fichajes y otras funcionalidades clave dentro del área de Recursos Humanos.\
Cada empleado debe tener su propio **usuario con email personal y válido**, lo que garantiza que pueda identificarse correctamente y recibir notificaciones o acceder a sus datos cuando lo necesite.
## ¿Por qué debo crear un usuario? [#por-qué-debo-crear-un-usuario]
Aunque un empleado no utilice Dinaup activamente al principio, es importante que **pueda acceder con su cuenta personal cuando sea necesario**.
La legislación española sobre control horario obliga a que cada empleado pueda:
* Consultar sus propios fichajes
* Descargar sus registros de jornada
* Justificar y editar fichajes incorrectos (si la empresa lo permite)
Para cumplir con esta normativa, **es imprescindible que el empleado tenga acceso al sistema mediante su propio inicio de sesión**.
## ¿Qué diferencia hay entre un usuario y un empleado? [#qué-diferencia-hay-entre-un-usuario-y-un-empleado]
En Dinaup, **todos los empleados son usuarios**, pero no todos los usuarios son empleados.\
Por ejemplo, un asesor externo o un responsable de área puede tener acceso al sistema sin ser parte del equipo de Recursos Humanos como empleado gestionado.
# Exportar horas (/docs/rtg/recursos-humanos/exportar)
La pantalla de **Exportar** genera el desglose de horas de un empleado en un periodo concreto. Vive en **Recursos Humanos → Rendimiento → Exportar**.
Esta pantalla está marcada como **Beta**.
***
## Qué ves [#qué-ves]
La pantalla tiene tres partes, de arriba abajo:
1. **Empleado**: un selector para elegir de quién quieres las horas.
2. **Periodo**: un selector de rango de fechas. El rango debe estar **dentro del mismo año** y no puede superar los 366 días.
3. **Exportación**: el resultado, una vez elegidos empleado y fechas.
El resultado se muestra en dos pestañas:
| Pestaña | Qué muestra |
| ----------- | --------------------------------------------------------------------------- |
| **Excel** | El desglose de horas en una hoja de cálculo, dentro del visor de documentos |
| **Gráfica** | Las mismas horas en una vista de línea de tiempo |
***
## Qué puedes hacer [#qué-puedes-hacer]
* **Elegir el empleado** y el **periodo** para calcular el desglose.
* **Consultar** el resultado en tabla Excel o en gráfica.
El archivo Excel se genera con el nombre `Horas.xlsx`.
El rango de fechas tiene que empezar y terminar en el **mismo año** y no pasar de un año de duración. Si eliges fechas fuera de esos límites, la pantalla te avisa y no genera la exportación.
***
→ [Análisis](/docs/rtg/recursos-humanos/analisis)
→ [Historial de fichaje](/docs/rtg/recursos-humanos/fichaje)
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
# Preguntas frecuentes (/docs/rtg/recursos-humanos/faq-recursos-humanos)
Respuestas rápidas a las dudas más habituales sobre la gestión de personal en Dinaup: altas y bajas de empleados, fichajes, horarios, vacaciones, saldos e informes. Cada respuesta enlaza a la página de detalle cuando necesitas el procedimiento completo. Si no encuentras la respuesta, escribe a `soporte@dinaup.com` o abre el chat de ayuda en [play.dinaup.com](https://play.dinaup.com).
***
## Alta y gestión de empleados [#alta-y-gestión-de-empleados]
En Dinaup cada empleado es un usuario del sistema, así que el alta tiene cuatro pasos:
1. **Crea el usuario** con su email personal y válido (lo necesita para identificarse, recibir notificaciones y consultar sus fichajes).
2. **Marca al empleado como `Activo`** en su ficha, para que aparezca en los desplegables del sistema.
3. **Decide su control horario**: si tiene jornada estructurada, activa el control horario y asígnale un horario; si no, registrará su jornada al entrar y salir sin restricciones.
4. **Asígnale un calendario de festivos** desde la pestaña `Recursos Humanos` de su ficha.
Tienes la guía completa en [Alta de empleado](/docs/rtg/recursos-humanos/procesos/alta-de-empleado).
No se borra: se desactiva. Abre la ficha del empleado y desmarca la opción `Activo`. A partir de ahí queda como **inactivo**: deja de aparecer en los listados y desplegables por defecto, pero todo su historial (fichajes, contratos, ausencias) se conserva para auditoría y cumplimiento legal.
Mantener el dato en vez de eliminarlo es lo que te permite responder ante una inspección sobre periodos pasados.
Todos los empleados son usuarios, pero no todos los usuarios son empleados. Un asesor externo o un responsable puede tener acceso al sistema sin ser un empleado gestionado en RRHH. Cada empleado, en cambio, necesita su propio usuario con email para cumplir la normativa de control horario (poder consultar y descargar sus fichajes).
Más detalle en [Empleados](/docs/rtg/recursos-humanos/empleados).
***
## Fichajes y control horario [#fichajes-y-control-horario]
El fichaje automático evita que un empleado tenga que fichar muchas veces al día. Basta con que **fiche la entrada al inicio y la salida al final de la jornada**: los turnos intermedios se registran solos según el horario definido.
Es ideal para jornadas partidas o con varios turnos al día. Por ejemplo, en una jornada con tres turnos y pausas, sin fichaje automático el empleado ficharía hasta seis veces; con él, solo dos. La alternativa es el **fichaje manual**, donde cada entrada y salida se registra una a una.
Configúralo en [Control horario](/docs/rtg/recursos-humanos/control-horario).
Desde tres canales, y todos alimentan el mismo historial:
* **App móvil**: para personal en movimiento o sin puesto fijo.
* **Tótem en recepción** (modo kiosko): una pantalla táctil compartida en la entrada.
* **Web**: desde cualquier navegador, sin instalar nada.
Si activas la geolocalización (opcional y desactivable por RGPD), cada fichaje guarda también las coordenadas. Más detalle en [Fichaje](/docs/rtg/recursos-humanos/fichaje).
El fichaje en sí es inmutable y no se edita nunca. Lo que se corrige es el **turno realizado** (el tiempo que se reconoce como trabajado). Si la empresa lo permite, el propio empleado puede revisar y justificar sus fichajes desde su cuenta; si no, lo hace un responsable.
Para avisarle puedes usar una **correspondencia interna**, que deja constancia de cuándo la abrió y leyó. La corrección se hace desde la [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo) del empleado.
No modificas el horario base del empleado: ajustas solo ese día. Hay dos formas según lo que necesites:
* **Corregir el tiempo trabajado** de una jornada (un olvido de fichaje, una imputación errónea): edita el **turno realizado** desde la [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo). El fichaje original se conserva intacto. Guía: [Cómo editar un fichaje](/docs/rtg/recursos-humanos/procesos/como-editar-un-fichaje-en-dinaup).
* **Reorganizar el horario de un día** (rotación, refuerzo, cambio puntual): sobrescribe ese turno en el planificador. Cuando termina la sobrescritura, el empleado vuelve solo a su horario habitual.
Cambiar un turno suelto nunca toca el horario base. Más sobre esto en [Turnos](/docs/rtg/recursos-humanos/turnos).
En los [Registros de eventos legales](/docs/rtg/recursos-humanos/registros-de-eventos-legales). Ahí se centralizan todas las acciones con impacto legal de RRHH, incluidas las ediciones de fichajes. Cada evento guarda automáticamente la IP de origen, el dispositivo, la huella del navegador y la fecha y hora exactas, además de una referencia única.
Así sabes siempre quién corrigió qué y cuándo, sin alterar el registro original.
Ve a `Recursos Humanos` → `Línea de Tiempo`. Cada línea representa la jornada de un empleado y muestra superpuestos tres niveles: lo **programado** (turnos previstos), lo **realizado** (tiempo reconocido) y los **fichajes** reales. Distingues una jornada correcta, un fichaje sin cierre, una ausencia justificada o una sin justificar.
Aprende a interpretarla en [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo).
***
## Configuración de horarios y descansos [#configuración-de-horarios-y-descansos]
El descanso forma parte de la **jornada**, el molde de un día de trabajo. Al crearla defines su entrada, su **descanso** (la pausa intermedia de comida o café), su salida y su margen de flexibilidad.
El descanso **no cuenta como tiempo trabajado**: se resta del cómputo. Una jornada de 09:00 a 18:00 con una hora de comida son 8 horas efectivas, no 9. Defines la jornada una vez y la reutilizas en todos los horarios que la necesiten.
Detalle en [Jornadas](/docs/rtg/recursos-humanos/horarios/jornadas) y guía en [Alta de horarios](/docs/rtg/recursos-humanos/procesos/alta-de-horarios).
***
## Vacaciones y ausencias [#vacaciones-y-ausencias]
Una vez el empleado tiene su usuario activo, puede solicitar vacaciones y permisos desde su cuenta, indicando el tipo, las fechas y un motivo (y adjuntando un justificante si hace falta). Tú, como responsable, las apruebas o rechazas. Así centralizas solicitudes, aprobaciones y justificantes en un mismo lugar y mantienes el control del tiempo libre de cada persona.
Más detalle en [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias).
En la sección de [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias). Ahí se listan las solicitudes de tu equipo y puedes filtrar las que están **pendientes** de aprobación, de modo que no se te escape ninguna.
Abre la solicitud para ver su detalle (tipo, fechas, motivo y posibles choques con otros del equipo) y **apruébala o recházala**. El empleado recibe el aviso del resultado. Una solicitud pasa de **pendiente** a **aprobada** o **rechazada**.
Ojo: si la ausencia se registra **después** de que ya se hayan generado los turnos de esos días, tendrás que asignar el motivo a cada turno manualmente desde la [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo), porque Dinaup no reasigna ausencias a turnos ya creados.
Cuando un empleado no fichó y había turno previsto, la jornada queda marcada como **ausencia sin justificar** en la [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo). Para justificarla, haz clic en cada turno programado y asígnale su **motivo de ausencia** (vacaciones, baja médica, permiso, formación…). Puedes poner motivos distintos en cada turno del día.
Los motivos los defines y clasificas en [Motivos de ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias/motivos-de-ausencias).
Cuando alguien se ausenta solo una parte de la jornada, no necesitas una ausencia de día completo: editas el horario de ese día concreto. Ve al calendario del empleado, abre el día en cuestión, busca el contenedor **"Horario Oficial"** y ajústalo teniendo en cuenta la ausencia y su motivo. Guarda y listo.
Paso a paso en [Cómo planificar una ausencia parcial](/docs/rtg/recursos-humanos/procesos/como-planificar-una-ausencia-parcial).
***
## Saldos y balances [#saldos-y-balances]
Tienes dos vistas según lo que busques:
* **Saldo de horas**: el [análisis de RRHH](/docs/rtg/recursos-humanos/analisis) compara las **horas trabajadas** (lo realmente fichado) con las **horas teóricas** (lo que marca el horario asignado). La diferencia te dice si la jornada se cumple, sin que tengas que introducir nada: Dinaup lo calcula a partir de fichajes y turnos.
* **Saldo de vacaciones y ausencias**: lo revisas en la sección de [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias), donde ves lo solicitado, lo aprobado y lo que queda disponible.
Si una cifra no cuadra, corrige el fichaje o el turno de origen y el saldo se recalcula.
***
## Informes y exportación [#informes-y-exportación]
Desde el [análisis de RRHH](/docs/rtg/recursos-humanos/analisis) tienes los indicadores de horas trabajadas frente a teóricas, puntualidad y ausencias, para toda la plantilla o para un empleado concreto. Para el detalle día a día de una persona, baja a su [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo), donde ves turno a turno lo programado, lo fichado y las ausencias.
El historial de fichajes es inmutable y está pensado para que puedas presentarlo ante una inspección de trabajo.
En **Recursos Humanos → Festivos** creas calendarios de días no laborables. Dinaup trae **precargados** los festivos nacionales, autonómicos y locales por región; tú solo añades encima los días propios de tu empresa. Luego asignas a cada empleado el calendario de su centro de trabajo desde su ficha.
Un festivo que caiga dentro de unas vacaciones **no descuenta saldo**, porque ya era no laborable. Detalle en [Festivos](/docs/rtg/recursos-humanos/festivos) y guía en [Agregar calendario de festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos).
Sí. Como cada empleado tiene su usuario, dispone de su **área de empleado** para consultar y descargar sus fichajes, registros de jornada y la documentación que le corresponde. Esto no es solo cómodo: la normativa española de control horario obliga a que cada persona pueda consultar y descargar sus propios registros.
Más detalle en [Área de empleado](/docs/rtg/area-de-empleado).
Sí. Cada fichaje lleva su sello de fecha y hora, el historial es **inmutable** y toda corrección queda trazada (quién, cuándo y qué) en los [Registros de eventos legales](/docs/rtg/recursos-humanos/registros-de-eventos-legales), con IP, dispositivo y huella del navegador. El empleado puede consultar y descargar sus registros desde su cuenta. Con esto puedes responder ante una inspección de trabajo.
***
→ [Control horario](/docs/rtg/recursos-humanos/control-horario)
→ [Fichaje](/docs/rtg/recursos-humanos/fichaje)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
→ [Análisis](/docs/rtg/recursos-humanos/analisis)
# Festivos (/docs/rtg/recursos-humanos/festivos)
Un **calendario de festivos** es la lista de días no laborables que se aplican a tus empleados: festivos nacionales, autonómicos, locales y los días propios de tu empresa. Dinaup los usa para saber qué días no se trabaja y, con eso, calcular correctamente las horas teóricas, las ausencias y las nóminas.
Sin un calendario asignado, Dinaup contaría como laborable un día festivo y descuadraría el control horario y el saldo de vacaciones. Por eso cada empleado debe tener su calendario según su centro de trabajo.
***
## Qué tipos de festivos hay [#qué-tipos-de-festivos-hay]
En España un mismo día puede ser festivo a la vez por tres niveles distintos. Dinaup los contempla todos dentro de un único calendario:
| Tipo | A quién afecta | Ejemplo |
| -------------- | ---------------------- | --------------------------------------- |
| **Nacional** | Todo el país | Día de la Constitución (6 de diciembre) |
| **Autonómico** | Una comunidad autónoma | Día de la comunidad |
| **Local** | Un municipio | Fiestas patronales del pueblo o ciudad |
| **De empresa** | Solo tu plantilla | Día del fundador, cierre por inventario |
Dinaup trae **precargados** los festivos nacionales, autonómicos y locales por región, así que no tienes que teclear los días oficiales uno a uno. Los **festivos propios de empresa** los añades tú encima.
Como un empleado del centro de Alicante no tiene los mismos festivos locales que uno de Madrid, lo normal es tener **un calendario por centro de trabajo** y asignar a cada empleado el que le corresponde.
***
## Para qué sirve el calendario [#para-qué-sirve-el-calendario]
El calendario de festivos no es solo una lista informativa: alimenta los cálculos de RRHH.
* **Horas teóricas**: un día festivo no suma horas de jornada esperadas, así que el [control horario](/docs/rtg/recursos-humanos/control-horario) compara lo fichado contra lo que realmente tocaba trabajar.
* **Vacaciones y ausencias**: al solicitar [vacaciones](/docs/rtg/recursos-humanos/vacaciones-y-ausencias), los días festivos que caigan dentro del periodo no descuentan saldo, porque ya eran no laborables.
* **Nóminas**: el cálculo de la nómina parte de los días efectivamente trabajables del mes.
***
## Cómo se organiza [#cómo-se-organiza]
Cada calendario cubre un **periodo** (normalmente un año natural, del 1 de enero al 31 de diciembre) y contiene la lista de festivos de ese periodo. Cada festivo es un **título** (el nombre del día) y una **fecha**.
Como los festivos cambian cada año, lo habitual es crear un calendario nuevo por año (por ejemplo, *Festivos Alicante 2026*) en lugar de reutilizar el del año anterior.
La cantidad de días del calendario se calcula sola a medida que añades festivos. Tú solo te preocupas de meter las fechas; el contador lo lleva Dinaup.
***
## El cambio de año [#el-cambio-de-año]
Un empleado apunta a un calendario, no a un año, así que estrenar año no obliga a repasar la plantilla. Cada calendario tiene el campo **Próximo calendario**, que lo enlaza con el siguiente: al calcular los festivos de un empleado, Dinaup recorre la cadena completa de calendarios enlazados y suma los días de todos.
El relevo anual queda en dos pasos:
1. Crea el calendario del año nuevo (*Festivos Alicante 2027*) con sus días.
2. Abre el calendario del año en curso y selecciona el nuevo en **Próximo calendario**.
Todos los empleados que apuntan al calendario actual heredan los festivos del nuevo a través del enlace. Las fichas no se tocan.
Deja el calendario nuevo enlazado antes de planificar los turnos de ese año: el control horario consulta los festivos en el momento de generar cada turno.
***
## Crear y asignar un calendario [#crear-y-asignar-un-calendario]
El alta de un calendario tiene su propia guía, pero la idea es sencilla:
### Abre los festivos [#abre-los-festivos]
Ve a **Recursos Humanos → Festivos**. Verás la lista de calendarios que ya existen.
### Crea el calendario y rellena el periodo [#crea-el-calendario-y-rellena-el-periodo]
Crea uno nuevo, dale una **descripción** clara (incluye el año y el centro, por ejemplo *Festivos Alicante 2026*) y fija el **periodo de validez**.
### Añade los festivos [#añade-los-festivos]
Carga los días no laborables. A cada festivo le pones un **título** y su **fecha**. Aquí incluyes tanto los oficiales como los propios de tu empresa.
### Asígnalo a cada empleado [#asígnalo-a-cada-empleado]
Guarda y, desde la ficha de cada empleado (pestaña **Recursos Humanos**), selecciona su **calendario de festivos** según su centro de trabajo.
→ [Guía completa: Agregar calendario de festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos)
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Los festivos nacionales, autonómicos y locales vienen precargados por región. Tú solo añades, si quieres, los días propios de tu empresa.
Porque los festivos locales (e incluso los autonómicos) cambian según el centro de trabajo. Un empleado de un municipio no tiene los mismos días libres que otro de una provincia distinta, así que cada uno necesita el calendario que le corresponde.
Dinaup contaría sus días festivos como laborables, lo que descuadraría las horas teóricas del control horario y el saldo de vacaciones. Asigna siempre un calendario a cada empleado.
No. Si un festivo cae dentro de un periodo de vacaciones, no resta saldo, porque ya era un día no laborable.
Sí, lo recomendable. Como las fechas de los festivos varían de un año a otro, lo habitual es crear un calendario por año natural en vez de reaprovechar el anterior. Enlázalo desde el anterior con **Próximo calendario** y los empleados lo heredan sin tocar sus fichas.
No. El empleado sigue apuntando a su calendario de siempre. Crea el del año nuevo y selecciónalo en el campo **Próximo calendario** del actual: la cadena hace el resto.
***
→ [Agregar calendario de festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos)
→ [Horarios](/docs/rtg/recursos-humanos/horarios)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
→ [Control horario](/docs/rtg/recursos-humanos/control-horario)
# Fichaje (/docs/rtg/recursos-humanos/fichaje)
Un **fichaje** es la marca de entrada y salida de un empleado en el reloj. Queda sellado con fecha, hora y los datos del dispositivo, y **no se puede editar**: es el historial que presentas ante una inspección de trabajo.
Fichaje no es lo mismo que jornada reconocida. Si hay un error humano, un responsable corrige el **turno** (el tiempo que cuenta); el fichaje original se conserva intacto. Detalle en [Corregir una jornada](#corregir-una-jornada).
## Poner en marcha el punto de fichaje [#poner-en-marcha-el-punto-de-fichaje]
La pantalla de fichaje es una página web con URL propia de tu empresa. Sirve igual en un tótem de recepción, una tablet en la entrada o el navegador de un móvil.
### Copia la URL de fichaje [#copia-la-url-de-fichaje]
Abre **Recursos Humanos → Inicio**. La URL de fichaje aparece en la parte superior, lista para copiar.
### Ábrela en el dispositivo que hará de reloj [#ábrela-en-el-dispositivo-que-hará-de-reloj]
Pega la URL en el navegador del tótem, tablet o móvil. La pantalla queda lista, sin iniciar sesión de ningún usuario.
### Cada empleado ficha con su identificador [#cada-empleado-ficha-con-su-identificador]
El empleado escribe o escanea su **identificador de empleado** y pulsa **Fichar**. La pantalla confirma la marca al momento y vuelve a quedar lista para el siguiente.
## Un botón que sabe qué toca [#un-botón-que-sabe-qué-toca]
No hay botón de entrada y botón de salida: hay **uno**, y el significado depende de la situación del empleado.
| Situación al pulsar Fichar | Qué hace el sistema |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| No tiene fichaje abierto | Registra la entrada. El sistema la compara después con su turno programado. |
| Tiene fichaje abierto | Cierra la salida. Y ahí termina: una pulsación nunca abre y cierra a la vez. |
| No tiene fichaje abierto ni turno programado | Según la política de la empresa: registra el tiempo como trabajo fuera de plan, o rechaza el fichaje. |
Una jornada partida son cuatro pulsaciones: entras a las 9:00, sales a comer a las 14:00, vuelves a las 15:00 y sales a las 18:00. Las dos primeras cierran el tramo de mañana; las dos últimas abren y cierran el de tarde. La comida es un hueco que no computa.
El fichaje y el turno son capas independientes: el sistema calcula cuántos minutos de cada turno quedaron cubiertos por fichajes, y de ahí salen el tiempo realizado, los retrasos y las ausencias. Llegar unos minutos antes de la hora no cuenta como retraso.
## Qué guarda cada fichaje [#qué-guarda-cada-fichaje]
Cada marca de entrada y de salida guarda, por separado:
| Dato | Para qué |
| ----------------------- | ------------------------------------------------------- |
| Fecha y hora | El momento exacto, en la zona horaria del empleado. |
| Dirección IP | Desde dónde se fichó. |
| Navegador y dispositivo | Con qué se fichó. |
| Huella del dispositivo | Identifica el equipo concreto, aunque cambie la IP. |
| Ubicación GPS | Opcional. Solo si el navegador tiene el permiso activo. |
La pantalla de fichaje indica si el GPS está disponible y permite probarlo. Si el permiso está bloqueado, los fichajes funcionan igual, sin coordenadas.
## Si alguien olvida fichar la salida [#si-alguien-olvida-fichar-la-salida]
El fichaje no se queda abierto para siempre. El sistema lo cierra solo con la **hora oficial de fin del turno** una vez pasado el margen de cierre de la empresa; si no había turno programado, a las 12 horas como tope de seguridad.
Los fichajes cerrados por el sistema quedan marcados como **cierre automático** y aparecen con un aviso en la [línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo) y en el panel de **Olvidos de salida**, para que un responsable confirme o corrija la jornada.
## Historial de fichajes [#historial-de-fichajes]
En **Recursos Humanos → Historial de fichajes** tienes todos los registros: entrada, salida, duración, empleado y los datos de auditoría de cada marca. Filtra por empleado y por fecha para acotar.
## Corregir una jornada [#corregir-una-jornada]
El fichaje **nunca se modifica ni se borra**. Lo que un responsable ajusta es el turno: el tiempo que se reconoce como trabajado ese día.
La corrección se hace desde el editor del día, en la línea de tiempo: se ajustan las horas esperadas y las realizadas, y se registran las ausencias con su motivo. Cada corrección queda anotada en los [registros de eventos legales](/docs/rtg/recursos-humanos/registros-de-eventos-legales) con el antes y el después.
→ [Cómo editar un fichaje en Dinaup](/docs/rtg/recursos-humanos/procesos/como-editar-un-fichaje-en-dinaup)
## Preguntas frecuentes [#preguntas-frecuentes]
No. El fichaje es la prueba de lo que se marcó y cuándo. Lo que se corrige es el turno: el tiempo reconocido como trabajado. Esa corrección queda trazada con quién, cuándo y qué cambió.
No. Fichar solo registra la marca. El sistema compara después los fichajes con los turnos del día y actualiza los turnos por su cuenta: estado, horas realizadas, retrasos y saldos.
De los turnos de trabajo, nunca de los fichajes. El fichaje es la prueba; el turno es la cuenta.
Desde cualquier navegador con la URL de fichaje de tu empresa: un tótem, una tablet en recepción o un móvil. Todos alimentan el mismo historial.
No. Los descansos declarados en la jornada son informativos y el fichaje los ignora. El café retribuido corre dentro del tramo de trabajo. En una jornada partida, la comida es un hueco: fichas la salida al irte y la entrada al volver, como en cualquier salida y entrada. Si tu empresa quiere medir las pausas, se registran en la [pantalla de descansos](/docs/rtg/recursos-humanos/descansos), sin fichar salida.
El retribuido sí: va dentro del tramo continuo y se declara en la jornada como minutos de descanso retribuido. El no retribuido no: es el hueco entre dos tramos de trabajo y ese tiempo no computa.
Un turno de 22:00 a 6:00 se registra en el día en que empieza y las horas se calculan de forma continua: 8 horas. El cierre automático usa la hora oficial de fin aunque caiga en el día siguiente.
Solo si el permiso de ubicación del navegador está activo. Es opcional: sin GPS, el fichaje funciona igual y guarda el resto de datos de auditoría.
Sí. Cada marca lleva sello de fecha y hora con datos del dispositivo, el historial es inmutable y las correcciones quedan registradas con su justificación.
Para el modelo completo de horarios, turnos y márgenes, sigue en [Control horario](/docs/rtg/recursos-humanos/control-horario).
# Incentivos y comisiones (/docs/rtg/recursos-humanos/incentivos-y-comisiones)
Los **incentivos de venta** premian a cada empleado en función de lo que vende. Fijas un **objetivo** y un **porcentaje de comisión** para una persona, y Dinaup calcula solo cuánto le corresponde cobrar cada mes a partir de sus ventas reales. No tienes que sumar nada a mano: eliges un mes, pulsas calcular y obtienes la comisión de cada empleado con su detalle.
Es la pieza que cierra el módulo de RRHH por el lado del rendimiento comercial: mientras el [análisis](/docs/rtg/recursos-humanos/analisis) mide horas y puntualidad, los incentivos miden ventas y las traducen en dinero para el empleado.
***
## Qué necesitas para empezar [#qué-necesitas-para-empezar]
Para que un empleado aparezca con comisión, hacen falta dos cosas:
* **Un objetivo de venta activo** asignado a esa persona (lo configuras tú).
* **Ventas suyas registradas** en el periodo que consultas.
Si una de las dos falta, el empleado no genera comisión ese mes. Sin objetivo no hay nada que calcular; sin ventas, no hay sobre qué calcularlo.
Cada empleado consigue su comisión por las **ventas que tiene asociadas a su nombre**. Por eso es importante que las ventas queden registradas con el vendedor correcto. Revisa cómo se registran las → [ventas](/docs/rtg/pymes/facturacion/ventas).
***
## Cómo se configura un objetivo [#cómo-se-configura-un-objetivo]
Un **objetivo de venta** es la regla que define cuánto debe vender un empleado y qué se lleva por superarlo. Cada objetivo se asigna a una persona concreta y queda **activo** hasta que decides retirarlo. Estos son los datos que lo componen:
| Dato | Qué significa |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Empleado** | La persona a la que aplica el objetivo. |
| **Objetivo base** | El importe de ventas a partir del cual empieza a generarse comisión. Lo que vende por debajo de esta cifra no comisiona. |
| **Comisión** | El **porcentaje** que el empleado se lleva sobre lo que **supere** el objetivo base. |
| **Calcular sobre** | Si el objetivo se mide sobre **ventas** o sobre **pedidos**. Eliges el tipo de operación que cuenta para esta persona. |
| **Con o sin impuestos** | Si los importes se miden **incluyendo impuestos** (total) o **sin impuestos** (base imponible). Marca la base de cálculo. |
| **Límite de comisión** | Un **tope máximo** opcional. Si lo fijas, la comisión nunca pasa de esa cifra por mucho que el empleado venda. |
| **Periodo de validez** | El rango de fechas en el que el objetivo está vigente. Solo cuenta para los meses dentro de ese rango. |
| **Mensaje para el empleado** | Una descripción que explica el incentivo en lenguaje claro, pensada para que la propia persona entienda qué tiene que hacer para ganar su comisión. |
Si una persona tiene **varios objetivos** que coinciden en el tiempo, Dinaup aplica el **más reciente** para ese periodo. Mantén un objetivo activo por empleado para evitar confusiones.
***
## Cómo se calcula la comisión [#cómo-se-calcula-la-comisión]
El cálculo es directo y siempre el mismo: Dinaup mira lo que el empleado ha vendido en el mes, lo compara con su objetivo base y aplica el porcentaje **solo a la parte que supera** ese objetivo.
### Suma las ventas del empleado en el mes [#suma-las-ventas-del-empleado-en-el-mes]
Reúne todas las ventas (o pedidos, según el objetivo) asociadas a esa persona dentro del mes seleccionado, contadas con o sin impuestos según hayas configurado.
### Calcula cuánto supera el objetivo [#calcula-cuánto-supera-el-objetivo]
Resta el objetivo base a esas ventas. Si vendió por debajo del objetivo, la diferencia es cero y **no hay comisión**. Si lo superó, esa diferencia es la base sobre la que comisiona.
### Aplica el porcentaje [#aplica-el-porcentaje]
Sobre la cantidad que supera el objetivo, aplica el porcentaje de comisión configurado. El resultado es lo que el empleado se lleva ese mes.
### Respeta el tope, si lo hay [#respeta-el-tope-si-lo-hay]
Si fijaste un límite de comisión y el cálculo lo sobrepasa, la comisión se queda en ese tope y se marca como **limitada**.
La comisión se genera **por superar el objetivo**, no por venderlo. Un empleado que llega justo al objetivo base ha cumplido, pero su comisión es cero: solo se premia lo que vende **de más**.
***
## Cómo se consultan [#cómo-se-consultan]
La consulta de comisiones vive dentro del módulo de **Recursos Humanos**, en la zona de análisis de productividad. Funciona por **mes y año**: eliges el periodo y Dinaup recalcula al momento.
### Elige el mes y el año [#elige-el-mes-y-el-año]
Indica el **mes** y el **año** que quieres revisar. Por defecto se muestra el mes en curso.
### Pulsa **Calcular** [#pulsa-calcular]
Dinaup reúne las ventas del periodo, las cruza con los objetivos activos y muestra el resultado. Si no hay datos para ese periodo, te avisa de que no hay nada que mostrar.
### Lee los resultados [#lee-los-resultados]
Verás un resumen general (los KPIs) y, debajo, el detalle empleado por empleado.
### El resumen del periodo [#el-resumen-del-periodo]
Arriba, tres indicadores te dan la foto del mes:
| Indicador | Qué te dice |
| ---------------------------- | ---------------------------------------------------------------------------------- |
| **Total ventas** | El importe total vendido por los empleados con incentivo y en cuántas operaciones. |
| **Empleados con incentivos** | Cuántas personas han generado resultado en el periodo. |
| **Total comisiones** | La suma de todo lo que vas a pagar en comisiones ese mes. |
### El detalle por empleado [#el-detalle-por-empleado]
Cada empleado aparece en su propia tarjeta con todo lo que necesitas para entender su comisión:
* **Tipo de objetivo**: si se calcula sobre ventas o sobre pedidos.
* **Objetivo**: la cifra que tenía que superar.
* **Realizado**: lo que realmente ha vendido, en color que indica si va por encima o por debajo del objetivo.
* **Operaciones**: en cuántas ventas (o pedidos) lo ha conseguido.
* **Progreso del objetivo**: una barra que compara el avance real con el **ritmo esperado** según los días transcurridos del mes. Así ves si la persona va adelantada o se está quedando corta antes de cerrar el mes.
* **Comisión**: el importe que se lleva. Si ha superado el objetivo, lo verás resaltado; si no, aparece como **sin comisión**. Cuando el cálculo ha tocado el tope, se marca como **limitada**.
El mensaje que escribiste para el empleado al crear el objetivo viaja con el resultado. Sirve para que cada persona entienda, en sus propias palabras, qué incentivo tiene y cómo lo ha cumplido.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Defines el objetivo y el porcentaje una vez, y Dinaup calcula la comisión de cada empleado a partir de sus ventas. Solo eliges el mes y pulsas calcular.
Probablemente no tiene un objetivo de venta activo asignado, o sus ventas no superan el objetivo base. La comisión solo se genera por la parte que **supera** el objetivo: si vende por debajo, la comisión es cero.
Depende de cómo configures el objetivo. Puedes medir las ventas incluyendo impuestos (el total) o sin ellos (la base imponible). Lo decides en el propio objetivo.
Sí. El objetivo admite un límite de comisión opcional. Si lo fijas, la comisión nunca supera ese tope, por mucho que el empleado venda, y se marca como limitada.
Sí. Cada objetivo se calcula sobre ventas o sobre pedidos. Eliges el tipo de operación que cuenta para cada persona.
***
→ [Análisis de RRHH](/docs/rtg/recursos-humanos/analisis)
→ [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo)
→ [Ventas](/docs/rtg/pymes/facturacion/ventas)
# Recursos Humanos (/docs/rtg/recursos-humanos)
Gestión de personal: empleados, horarios, turnos, vacaciones, control horario y fichaje, en un mismo módulo.
## Funcionalidades [#funcionalidades]
Visualiza quién trabaja y quién está ausente, con turnos y vacaciones en un calendario o un Gantt del equipo.
Registra entrada, salida y pausas desde el móvil, el tótem o la web.
Visualiza cada jornada como una línea que diferencia fichajes, ausencias y festivos, lista para auditar.
Gestiona el perfil y la documentación de cada empleado.
Define roles y responsabilidades, con sus permisos y jerarquías.
Organiza la empresa por áreas y subáreas con responsables asignados.
Mensajes enviados con trazabilidad completa: sabes si se entregaron, abrieron y leyeron, con fecha, hora e IP.
Asigna y controla los horarios de trabajo de la plantilla.
Crea calendarios laborales; los festivos se reflejan solos en horarios y turnos.
Solicitudes, aprobaciones y justificantes en un mismo lugar.
Organiza, publica y gestiona los turnos de trabajo.
Registro inmutable de entradas / salidas con IP, dispositivo y huella digital.
#### Asistencia [#asistencia]
Clasificación de motivos de ausencias y retrasos con sus implicaciones laborales específicas.
Definición de los tipos de jornada laboral y de turno que usa tu empresa.
## Soluciones relacionadas [#soluciones-relacionadas]
## Guías [#guías]
Da de alta a un nuevo empleado y déjalo listo para trabajar.
Crea un horario de trabajo desde cero.
Vincula un horario existente a un empleado.
Configura el calendario laboral de festivos.
Corrige una entrada o salida registrada por error.
# Línea de Tiempo (/docs/rtg/recursos-humanos/linea-de-tiempo)
En el sistema de fichajes de Dinaup, cada línea representa la jornada laboral de un empleado. Estos son los casos más comunes que puedes encontrarte:
## Fichaje Automático Correcto [#fichaje-automático-correcto]
El sistema detectó correctamente la jornada a partir del fichaje de entrada y salida.
* **Programado**: Tres turnos asignados.
* **Realizado**: Tres turnos completados (check verde).
* **Fichaje**: Entrada y salida bien marcadas.
**¿Qué hacer?**\
Puedes modificar el tiempo realizado si hay alguna corrección, pero no el fichaje (es inmutable).
***
## Fichaje Automático (sin cierre) [#fichaje-automático-sin-cierre]
El empleado fichó al entrar, pero olvidó fichar al salir. El sistema marcó los turnos como completados porque la entrada existió.
* **Programado**: Tres turnos asignados.
* **Realizado**: Tres turnos completados (check verde).
* **Fichaje**: Rectángulo naranja continuo hasta final del día.
**¿Qué hacer?**\
Recursos humanos puede revisar si corresponde ajustar el tiempo. Solo es necesario intervenir si el fichaje automático no refleja correctamente la realidad.
***
## Ausencia sin justificar [#ausencia-sin-justificar]
El empleado no ha venido y no hay ningún motivo asignado.
* **Programado**: Tres turnos asignados.
* **Realizado**: Vacío.
* **Fichaje**: Vacío.
**¿Qué hacer?**\
Recursos humanos debe hacer clic en cada turno azul de “Programado” y asignar el motivo de la ausencia. Pueden ser distintos motivos en cada turno
***
## Ausencia justificada [#ausencia-justificada]
El empleado no trabajó, pero se justificó la ausencia (en este caso, vacaciones).
* **Programado**: Tres turnos asignados.
* **Realizado**: Tres bloques grises *(VACACIONES).*
**¿Qué hacer?**\
No requiere ninguna acción adicional.
***
## Festivos [#festivos]
# Motivos de ausencia (/docs/rtg/recursos-humanos/motivos-de-ausencia)
Un **motivo de ausencia** es la categoría que explica por qué un empleado no trabaja: vacaciones, baja médica, asuntos propios, permiso retribuido, formación... Cada motivo no es solo una etiqueta: define **cómo se comporta** esa ausencia en Dinaup, es decir, si descuenta del saldo de vacaciones, si es retribuida y cómo se refleja en la nómina.
Clasificar bien las ausencias te da un control claro de la asistencia y hace que los saldos y las nóminas salgan solos, sin ajustes a mano.
Esta página explica cómo **crear y configurar** los motivos. Si buscas el concepto general dentro de la gestión de vacaciones, consulta la página hermana → [Motivos de ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias/motivos-de-ausencias).
***
## Por qué un motivo importa [#por-qué-un-motivo-importa]
Dos empleados pueden estar igual de ausentes un lunes y, sin embargo, ese día contar de forma muy distinta. La diferencia está en el motivo:
* Si el motivo son **vacaciones**, el día **descuenta del saldo** de vacaciones del empleado.
* Si es una **baja médica**, normalmente **no toca el saldo** de vacaciones y sí cambia cómo se trata en la nómina.
* Si es un **permiso retribuido**, el empleado cobra igual pero el día no sale de sus vacaciones.
* Si es un **asunto propio**, puede descontar de una bolsa de días propia distinta a las vacaciones.
El motivo es lo que le dice a Dinaup qué hacer con cada ausencia. Por eso conviene crear los motivos **antes** de empezar a registrar ausencias.
***
## Cómo computa cada motivo [#cómo-computa-cada-motivo]
Al definir un motivo decides su comportamiento. Estos son los ejes que determinan cómo afecta a los saldos y a la nómina:
| Eje | Qué controla |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Descuenta del saldo de vacaciones** | Si los días de este motivo se restan de los días de vacaciones que tiene el empleado. Típico de vacaciones; no de bajas. |
| **Es retribuido** | Si el empleado cobra esos días. Un permiso retribuido sí; una ausencia no justificada, no. |
| **Cómo aparece en la nómina** | Cómo se refleja el periodo ausente en el cálculo de la nómina del mes. |
No todos los días de ausencia restan vacaciones. Vacaciones sí; una baja médica o un permiso retribuido normalmente no. Configura cada motivo según cómo deba comportarse en tu organización.
***
## Motivos típicos [#motivos-típicos]
Estos son los motivos más habituales y cómo suelen comportarse. Úsalos como punto de partida y ajústalos a tu convenio:
| Motivo | Descuenta vacaciones | Retribuido |
| --------------------------- | -------------------- | --------------- |
| **Vacaciones** | Sí | Sí |
| **Baja médica** | No | Según normativa |
| **Permiso retribuido** | No | Sí |
| **Asuntos propios** | Según tu política | Sí |
| **Formación** | No | Sí |
| **Ausencia no justificada** | No | No |
***
## Crear un motivo de ausencia [#crear-un-motivo-de-ausencia]
### Abre los motivos de ausencia [#abre-los-motivos-de-ausencia]
Ve a **RRHH** y entra en la configuración de **Vacaciones y ausencias**. Ahí encontrarás la lista de motivos disponibles.
### Añade un motivo nuevo [#añade-un-motivo-nuevo]
Crea un motivo y dale un **nombre claro** que cualquiera entienda al solicitar o aprobar una ausencia (por ejemplo, "Vacaciones", "Baja médica" o "Asuntos propios"). El nombre es lo que verán empleados y managers, así que evita abreviaturas confusas.
### Define su comportamiento [#define-su-comportamiento]
Indica cómo debe computar: si **descuenta del saldo de vacaciones**, si es **retribuido** y cómo se refleja en la **nómina**. Aquí es donde el motivo deja de ser una etiqueta y se convierte en una regla automática.
### Guarda y empieza a usarlo [#guarda-y-empieza-a-usarlo]
Una vez guardado, el motivo aparece como opción al registrar cualquier ausencia. Crea de una vez todos los que use tu empresa para no interrumpir el trabajo del día a día.
***
## Usar un motivo al registrar una ausencia [#usar-un-motivo-al-registrar-una-ausencia]
Cuando un empleado solicita una ausencia o un manager la registra, lo primero que se elige es el **motivo**. A partir de ahí Dinaup aplica el comportamiento que configuraste: descuenta (o no) del saldo, marca el periodo como retribuido y lo prepara para la nómina.
El flujo es siempre el mismo:
1. Eliges el **motivo** de la ausencia.
2. Indicas el **periodo** (desde / hasta).
3. Confirmas la solicitud, que pasa por la aprobación del manager.
Para ausencias que solo ocupan parte de un día (por ejemplo, salir dos horas para una cita médica), puedes registrarlas directamente sobre el horario del empleado. → [Cómo planificar una ausencia parcial](/docs/rtg/recursos-humanos/procesos/como-planificar-una-ausencia-parcial)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
***
## Preguntas frecuentes [#preguntas-frecuentes]
El motivo es lo que le dice a Dinaup cómo computar el periodo. Si eliges un motivo que descuenta vacaciones cuando no debería, ese día saldrá del saldo del empleado. Por eso conviene definir los motivos con cuidado antes de empezar a registrar ausencias.
No debería. Las vacaciones descuentan del saldo; una baja médica normalmente no toca ese contador. Configura cada motivo según cómo deba comportarse en tu organización.
Sí. Más allá de los habituales (vacaciones, baja, asuntos propios), puedes crear los motivos que necesite tu empresa y definir para cada uno si descuenta saldo, si es retribuido y cómo aparece en la nómina.
Es el primer dato de la solicitud: al registrar una ausencia eliges el motivo y luego el periodo. Dinaup aplica el comportamiento configurado para ese motivo.
***
→ [Motivos de ausencias (concepto)](/docs/rtg/recursos-humanos/vacaciones-y-ausencias/motivos-de-ausencias)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
→ [Cómo planificar una ausencia parcial](/docs/rtg/recursos-humanos/procesos/como-planificar-una-ausencia-parcial)
# Nóminas (/docs/rtg/recursos-humanos/nominas)
La pantalla de **Nóminas** reúne los registros de nómina de tu empresa en un solo listado. Vive en **Recursos Humanos → Personas → Nóminas** y solo aparece si tu usuario tiene permiso de lectura sobre las nóminas.
***
## Qué ves [#qué-ves]
Una **tabla con las nóminas** registradas. Cada fila es una nómina, con las columnas del informe. La barra de herramientas te deja filtrar, ordenar y buscar dentro de la lista.
Hay una pestaña de **notas** para dejar anotaciones internas ligadas a esta pantalla.
***
## Qué puedes hacer [#qué-puedes-hacer]
| Acción | Dónde |
| ----------------- | --------------------------------- |
| Añadir una nómina | Botón de alta de la tabla |
| Abrir una nómina | Clic en su fila |
| Filtrar y ordenar | Barra de herramientas de la tabla |
| Anotar | Pestaña de notas de la pantalla |
***
## La nómina en la ficha del empleado [#la-nómina-en-la-ficha-del-empleado]
Cada empleado ve sus propias nóminas desde su [perfil de trabajador](/docs/rtg/recursos-humanos/perfil-de-trabajador) y desde su [área de empleado](/docs/rtg/area-de-empleado), donde las tiene listas para consultar o descargar.
***
→ [Empleados](/docs/rtg/recursos-humanos/empleados)
→ [Contratos](/docs/rtg/recursos-humanos/contratos)
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
# Planificador (/docs/rtg/recursos-humanos/planificador)
El **planificador** es la vista panorámica de tu plantilla: en una sola pantalla ves a tu equipo con sus turnos y sus ausencias colocados sobre un eje de tiempo. Sirve para entender **cómo queda planificada la semana o el mes** (quién entra cada día, quién está de vacaciones, dónde hay un hueco) antes de bajar al detalle.
Lo encuentras en **Recursos Humanos → Día a día → Planificador**.
***
## Qué resuelve [#qué-resuelve]
Cuando tienes varias personas con horarios distintos, mirar los turnos uno a uno no da la foto completa. El planificador junta a todo el equipo en la misma vista para que respondas a las preguntas que importan al organizar:
* ¿Quién está trabajando cada día y en qué franja?
* ¿Quién está de vacaciones, de baja o ausente esta semana?
* ¿Hay algún día sin cubrir o alguien con turnos que se pisan?
No es un listado: es una **representación visual** pensada para captar el conjunto, comparar personas entre sí y detectar a ojo lo que se sale de lo normal.
***
## Elegir a quién ves [#elegir-a-quién-ves]
Arriba del planificador eliges qué empleados quieres mostrar. Por defecto parte de tu plantilla **activa**, ordenada por departamento, y tú seleccionas a quién incluir en la vista.
Si no hay nadie seleccionado, el planificador te lo dice ("Sin empleados seleccionados") y no pinta nada. Elige al menos una persona en el filtro superior para ver su planificación.
Cada empleado aparece identificado con su **avatar, su nombre y su departamento**, para que no haya dudas de quién es quién cuando la lista es larga.
***
## Trabajando frente a ausencias [#trabajando-frente-a-ausencias]
El planificador tiene dos modos, y solo enseña uno a la vez. Cambias entre ellos con el conmutador **Trabajando / Ausencias**:
| Modo | Qué pinta |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Trabajando** | Los **turnos programados** de cada empleado, con su franja horaria. Es la vista para planificar la cobertura: ver quién entra cada día y cuándo. |
| **Ausencias** | Todo lo que **aparta** a una persona del trabajo: **vacaciones**, **baja médica**, **otras ausencias** y **festivos**. Es la vista para anticipar huecos: saber quién no va a estar. |
Separar los dos mundos evita el ruido. Cuando montas la semana miras **Trabajando**; cuando compruebas quién falta o se va de vacaciones, cambias a **Ausencias**.
Cada tipo de ausencia se distingue con su propio color e icono (vacaciones, baja, ausencia genérica y festivo) para que los identifiques sin leer.
***
## Gantt o calendario [#gantt-o-calendario]
Para los mismos datos puedes elegir la forma de verlos con el conmutador **Gantt / Calendario**, según lo que estés buscando:
### Vista Gantt: el equipo en filas [#vista-gantt-el-equipo-en-filas]
Cada **fila es un empleado** y el tiempo avanza en horizontal. Las **barras** son sus turnos (o sus ausencias, si estás en ese modo). Es la vista ideal para **comparar personas entre sí**: ver quién trabaja cuándo y dónde quedan los huecos de cobertura.
### Vista Calendario: el tiempo como rejilla [#vista-calendario-el-tiempo-como-rejilla]
Los mismos turnos y ausencias colocados sobre un **calendario**. Puedes mirarlo por **día, semana, mes** o como **planificador anual**, según el horizonte que quieras abarcar. Es la vista cómoda para pensar en clave de fechas: "la semana que viene", "todo agosto".
Cambiar entre Gantt y calendario no altera nada: es solo otra forma de mirar la misma planificación.
***
## Detectar problemas con el equipo delante [#detectar-problemas-con-el-equipo-delante]
El valor del planificador es que **los conflictos saltan a la vista** cuando tienes a todo el equipo delante. Mirando el conjunto detectas situaciones que en un listado pasarían desapercibidas:
* **Días sin cubrir**: alguien que debería tener turno y aparece vacío ese día.
* **Turnos que se solapan**: dos franjas de la misma persona pisándose.
* **Choques con vacaciones**: un turno asignado justo cuando el empleado está de vacaciones o ausente. Por eso es útil comparar el modo **Trabajando** con el modo **Ausencias**: lo que en uno es un turno, en el otro debería ser un hueco.
El planificador es para **ver y detectar**. Cuando encuentras algo que corregir (reasignar un turno, cubrir un hueco, cancelar un solape) lo arreglas desde [Turnos](/docs/rtg/recursos-humanos/turnos) o, si es cuestión de fichajes y jornada real, desde la [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo).
***
## Cómo planificar con esta vista [#cómo-planificar-con-esta-vista]
### Ten los turnos generados [#ten-los-turnos-generados]
El planificador refleja los turnos que ya existen, que Dinaup crea a partir del [horario](/docs/rtg/recursos-humanos/horarios) de cada empleado. Si aún no has asignado horarios, hazlo primero para que haya algo que ver.
→ [Turnos](/docs/rtg/recursos-humanos/turnos) · [Horarios](/docs/rtg/recursos-humanos/horarios)
### Selecciona a tu equipo y elige el modo [#selecciona-a-tu-equipo-y-elige-el-modo]
Abre el planificador, marca a los empleados que quieras revisar y ponlo en **Trabajando** para ver la cobertura.
### Cruza con las ausencias [#cruza-con-las-ausencias]
Cambia a **Ausencias** para comprobar quién estará de vacaciones, de baja o fuera. Así no planificas a alguien que no va a estar.
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
### Corrige donde toque [#corrige-donde-toque]
Si detectas un hueco, un solape o un choque con vacaciones, ajústalo desde [Turnos](/docs/rtg/recursos-humanos/turnos). El planificador volverá a reflejar la planificación corregida.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El planificador está pensado para ver la planificación de todo el equipo y detectar problemas. La creación y el ajuste de turnos se gestionan desde Turnos; los fichajes y la jornada real, desde la Línea de tiempo.
Porque no has seleccionado empleados. La vista parte vacía hasta que eliges a quién mostrar en el filtro superior. Marca al menos una persona y aparecerá su planificación.
Trabajando muestra los turnos programados (la cobertura). Ausencias muestra vacaciones, bajas, otras ausencias y festivos (quién no estará). Son dos lecturas del mismo equipo: una para planificar, otra para anticipar huecos.
No. Son dos formas de ver lo mismo. El Gantt pone a los empleados en filas para comparar; el calendario coloca turnos y ausencias sobre fechas (día, semana, mes o año). Eliges la que mejor te encaje.
***
→ [Turnos](/docs/rtg/recursos-humanos/turnos)
→ [Horarios](/docs/rtg/recursos-humanos/horarios)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
→ [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo)
→ [Control horario](/docs/rtg/recursos-humanos/control-horario)
# Registros de Eventos Legales (/docs/rtg/recursos-humanos/registros-de-eventos-legales)
El **registro de eventos legales** centraliza todas las acciones con impacto legal realizadas dentro de Recursos Humanos. Aquí se muestran, de forma ordenada y trazable:
* **Ediciones de fichajes**, incluyendo modificaciones manuales y ajustes de horario.
* **Eventos de correspondencias**, como su creación, apertura y lecturas verificadas.
Cada evento guarda automáticamente:
* **IP de origen**
* **User-Agent del dispositivo**
* **Huella/fingerprint del navegador**
* **Fecha y hora exacta del evento**
* **Referencia única generada por el sistema**
# Turnos sin fichar (/docs/rtg/recursos-humanos/turnos-sin-fichar)
La pantalla de **Turnos sin fichar** reúne los turnos que constan como **ausencia**: días en los que el empleado tenía turno pero no hay actividad fichada. Es la vista a la que vienes para revisar esas ausencias y ponerles un motivo.
Vive en **Recursos Humanos → Día a día → Turnos sin fichar**.
***
## Qué ves [#qué-ves]
La pantalla se divide en dos pestañas:
| Pestaña | Qué lista |
| -------------- | ---------------------------------------------------------------- |
| **Pendientes** | Los turnos en ausencia que **no tienen motivo** asignado todavía |
| **Todas** | Todos los turnos en ausencia, tengan motivo o no |
Cada pestaña es una tabla con los turnos marcados como ausencia. Un aviso en la parte superior recuerda que se consideran **pendientes** las ausencias que no tienen un motivo asociado.
***
## Qué puedes hacer [#qué-puedes-hacer]
* **Revisar** los turnos en ausencia, empezando por los pendientes.
* **Abrir** un turno desde su fila para asignarle un motivo.
* **Filtrar y ordenar** con la barra de herramientas de cada tabla.
Al asignar un motivo a un turno pendiente, deja de figurar en **Pendientes**.
Un turno queda en ausencia cuando no hay fichaje que lo cubra. Para clasificar por qué faltó el empleado, asígnale uno de los [motivos de ausencia](/docs/rtg/recursos-humanos/motivos-de-ausencia).
***
→ [Motivos de ausencia](/docs/rtg/recursos-humanos/motivos-de-ausencia)
→ [Línea de tiempo](/docs/rtg/recursos-humanos/linea-de-tiempo)
→ [Turnos](/docs/rtg/recursos-humanos/turnos)
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
# Turnos (/docs/rtg/recursos-humanos/turnos)
Un **turno** es un bloque de trabajo concreto que un empleado cubre un día determinado: la mañana del lunes, la noche del sábado, el partido del martes. Es la pieza con la que **planificas** quién trabaja, cuándo y bajo qué horario.
Los turnos se generan solos a partir del [horario](/docs/rtg/recursos-humanos/horarios) asignado a cada empleado, pero puedes añadirlos o cambiarlos a mano cuando hay horas extra, una rotación o un imprevisto. Así combinas la comodidad de una plantilla con la flexibilidad de ajustar la semana real.
***
## Turno frente a horario y jornada [#turno-frente-a-horario-y-jornada]
Es la distinción que más ayuda a entender el módulo. Son tres conceptos encadenados: la jornada define las horas, el horario las organiza en una semana, y el turno las pone en un día concreto para una persona.
| | [Jornada](/docs/rtg/recursos-humanos/horarios/jornadas) | [Horario](/docs/rtg/recursos-humanos/horarios) | Turno |
| --------------- | ------------------------------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------- |
| Qué es | La plantilla de horas (entrada, descanso, salida) | El conjunto de jornadas repartidas por días de la semana | La asignación real de un horario a un empleado en una fecha |
| Responde a | ¿Cuántas horas y cuándo? | ¿Qué días se trabaja qué jornada? | ¿Quién trabaja este día y con qué horario? |
| Es reutilizable | Sí, la usan muchos horarios | Sí, lo comparten varios empleados | No, es de un empleado y una fecha |
| Dónde vive | Configuración | Configuración | El planificador |
Regla rápida: el **horario y la jornada son la plantilla**; el **turno es la realidad de un día**. Cambiar un turno suelto no toca el horario base del empleado, solo esa fecha.
***
## Cuándo usar turnos [#cuándo-usar-turnos]
Los turnos encajan en cualquier negocio con **rotación o cobertura por franjas**: comercio, hostelería, industria, atención al público. Casos típicos:
* **Rotación mañana / tarde / noche**: el equipo va cambiando de franja semana a semana.
* **Turno partido**: mañana y tarde con descanso largo en medio.
* **Refuerzos puntuales**: un día con más carga necesita gente extra fuera de su horario habitual.
* **Cambios y sustituciones**: alguien cubre el turno de un compañero ausente.
Si tu equipo siempre hace el mismo horario fijo, te basta con asignar el [horario](/docs/rtg/recursos-humanos/horarios) y dejar que los turnos se generen solos: no tendrás que tocar el planificador salvo excepciones.
***
## El planificador [#el-planificador]
El **planificador** es la vista donde ves y montas los turnos de todo el equipo a la vez, con formato de calendario:
* **Filas**: los empleados.
* **Columnas**: los días.
* **Barras**: cada turno asignado, con su franja horaria.
Puedes verlo por **semana, quincena o mes**, según el horizonte que necesites planificar.
### Asignar y mover turnos [#asignar-y-mover-turnos]
Trabajas directamente sobre la rejilla, sin formularios:
* **Arrastra** para crear o mover un turno de un día o un empleado a otro.
* **Estira** una barra para alargar o acortar la franja.
* **Edita en masa** varios turnos de golpe cuando montas la semana.
* **Cancela** un turno indicando el motivo, para que quede el porqué del cambio.
Como los turnos parten del horario del empleado, lo normal es que la semana ya venga medio montada. En el planificador solo ajustas lo que se sale de la rutina: refuerzos, cambios y rotaciones.
***
## Rotación y sobrescritura semanal [#rotación-y-sobrescritura-semanal]
Cada empleado tiene su horario por defecto, pero el planificador te deja **sobrescribirlo por semana o por turno concreto** sin alterar la plantilla base:
* **Rotación**: una semana el empleado entra de mañana, la siguiente de tarde. Asignas el horario que toca a cada semana y el resto sigue su curso.
* **Sobrescritura puntual**: un día concreto cambia (entra antes, hace horas extra, cubre a otro). Ajustas solo ese turno.
Cuando termina la sobrescritura, el empleado vuelve solo a su horario habitual. No tienes que "deshacer" nada.
***
## Detección de conflictos [#detección-de-conflictos]
El planificador no es solo una pizarra: **vigila que la planificación tenga sentido** y te avisa marcando en rojo los problemas para que los resuelvas antes de que afecten al equipo.
| Conflicto | Qué significa |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **Sin turno** | Un empleado no tiene turno asignado en un día laborable según su horario |
| **Solapamiento** | Dos turnos del mismo empleado pisan la misma franja horaria |
| **Choque con vacaciones** | Hay un turno asignado en días en los que el empleado está de [vacaciones o ausente](/docs/rtg/recursos-humanos/vacaciones-y-ausencias) |
Revisa los avisos antes de dar la semana por cerrada. Un turno que choca con unas vacaciones aprobadas o un día sin cubrir es justo lo que el planificador te ayuda a cazar a tiempo.
***
## Cómo planificar tu semana [#cómo-planificar-tu-semana]
### Asegúrate de tener horarios definidos [#asegúrate-de-tener-horarios-definidos]
Los turnos se construyen sobre los horarios. Si aún no los tienes, créalos primero: define las jornadas y reparte los días de la semana.
→ [Cómo dar de alta horarios](/docs/rtg/recursos-humanos/procesos/alta-de-horarios)
### Asigna un horario a cada empleado [#asigna-un-horario-a-cada-empleado]
Cada empleado necesita su horario por defecto. A partir de él, Dinaup genera los turnos por su cuenta.
→ [Asignar horario a un empleado](/docs/rtg/recursos-humanos/procesos/asignar-horario-a-empleado)
### Abre el planificador y ajusta la semana [#abre-el-planificador-y-ajusta-la-semana]
Entra en el planificador y revisa cómo ha quedado la semana. Arrastra, estira o crea turnos para cubrir rotaciones, refuerzos y cambios.
### Resuelve los conflictos en rojo [#resuelve-los-conflictos-en-rojo]
Antes de cerrar, repasa los avisos: días sin turno, solapamientos y choques con vacaciones. Corrige cada uno y deja la planificación limpia.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El horario (y la jornada que lo compone) es la plantilla de horas que se repite. El turno es la asignación real de ese horario a un empleado en una fecha concreta. Cambiar un turno suelto no modifica el horario base del empleado.
No. Se generan solos a partir del horario asignado a cada empleado. Solo entras al planificador a ajustar las excepciones: horas extra, rotaciones, refuerzos y cambios.
Sobrescribes el horario por semana en el planificador: asignas a cada empleado el horario que le toca esa semana. Al terminar, vuelve por sí solo a su horario habitual.
El planificador lo marca como conflicto. Verás el choque en rojo para que reasignes el turno o lo canceles antes de cerrar la planificación.
***
→ [Horarios](/docs/rtg/recursos-humanos/horarios)
→ [Jornadas](/docs/rtg/recursos-humanos/horarios/jornadas)
→ [Vacaciones y ausencias](/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
→ [Control horario](/docs/rtg/recursos-humanos/control-horario)
# Agendas (/docs/rtg/agendas)
**Agendas** es tu calendario dentro de Dinaup. Creas agendas para separar lo que organizas (trabajo, equipo, cliente, proyecto) y dentro de cada una colocas **eventos** con fecha, hora y detalles. Todo se ve en un único calendario que pinta cada agenda de un color, así distingues a qué agenda pertenece cada evento.
Es donde planificas tu tiempo y el de tu equipo sin salir de Dinaup, al lado de tu [CRM](/docs/rtg/crm) y tus [proyectos](/docs/rtg/proyectos).
***
## Conceptos: agenda y evento [#conceptos-agenda-y-evento]
El módulo se mueve con dos piezas: la agenda y el evento.
| | Agenda | Evento |
| ----------- | --------------------------------------------------------------- | ---------------------------------------------------- |
| Qué es | Un calendario con nombre que agrupa eventos | Una cita concreta dentro de una agenda |
| Para qué | Separar contextos (un equipo, un cliente, un tipo de actividad) | Reservar un hueco con título, inicio, fin y detalles |
| Quién la ve | Tú y los usuarios con los que la compartes | Los usuarios de la agenda a la que pertenece |
| Color | Cada agenda tiene su color en el calendario | Hereda el color de su agenda |
Una agenda sin eventos no estorba: es un contenedor listo para llenarse. Un evento siempre vive dentro de una agenda.
***
## Agendas personales y compartidas [#agendas-personales-y-compartidas]
Cuando creas una agenda es **tuya**. A partir de ahí decides quién más entra:
* **Personal**: solo tú. Útil para tu planificación individual.
* **Compartida**: añades a otros usuarios de tu empresa y todos ven y trabajan sobre los mismos eventos.
Cada agenda lleva la cuenta de cuántos **usuarios** tiene asignados y cuántos **eventos** contiene, para que sepas cuáles están vivas y cuáles compartes.
Compartir una agenda comparte sus eventos. Si quieres que algo lo vea solo una parte del equipo, ponlo en una agenda aparte y comparte únicamente esa.
***
## El calendario [#el-calendario]
El calendario reúne los eventos de **todas tus agendas** en una sola pantalla. Cada evento aparece con el color de su agenda.
### Vistas [#vistas]
Cambias de vista según lo que necesites mirar:
| Vista | Para qué sirve |
| ------------------ | -------------------------------------------------------------------- |
| Mensual | La foto del mes completo. El día de hoy va resaltado. |
| Semanal | El detalle de una semana, hora a hora. |
| Diaria | El plan de un solo día. |
| Planificador anual | El año entero en una sola pantalla, para ver la carga a largo plazo. |
| Línea de tiempo | Los eventos del año dispuestos en una línea temporal. |
### Filtrar por agenda [#filtrar-por-agenda]
Si manejas varias agendas, filtra el calendario para ver solo una. Quitas el filtro y vuelves a tenerlas todas juntas. La leyenda de colores te recuerda qué color es cada agenda.
***
## Crear eventos [#crear-eventos]
Tienes dos formas de añadir un evento, y eliges según tengas el dato a mano o en un texto.
### A mano, desde el calendario [#a-mano-desde-el-calendario]
### Abre el calendario [#abre-el-calendario]
Entra en **Agendas**. Verás el calendario con tus eventos.
### Añade el evento [#añade-el-evento]
Pulsa **Nuevo Evento**, o haz clic directamente sobre el hueco del día y la hora que quieras. El inicio y el fin se rellenan con ese hueco.
### Completa y guarda [#completa-y-guarda]
Pon el título, ajusta inicio y fin, elige la agenda y añade los detalles que necesites. Al guardar, el evento aparece en el calendario con el color de su agenda.
### Desde texto, con IA [#desde-texto-con-ia]
Si tienes la información en un email, un mensaje o una nota, usa **Crear desde texto**: pegas el texto y la IA extrae el **título**, las **fechas de inicio y fin** y un **resumen de los detalles** (participantes, ubicación, notas).
La IA interpreta expresiones relativas como "mañana a las 10" o "el viernes por la tarde" tomando como referencia la fecha y hora actuales. Si el texto no indica duración, asume una hora.
Lo que extrae se vuelca en el formulario de **Nuevo Evento** para que lo revises, corrijas lo que haga falta y confirmes antes de crearlo. La IA propone; el evento no se guarda hasta que lo confirmas.
***
## Cuándo crear una agenda nueva [#cuándo-crear-una-agenda-nueva]
Crea una agenda cada vez que quieras mantener separado un contexto. Casos típicos:
* **Por equipo**: una agenda compartida para cada departamento o grupo de trabajo.
* **Por cliente o proyecto**: una agenda dedicada a las citas de un cliente o de un [proyecto](/docs/rtg/proyectos) concreto.
* **Por tipo de actividad**: separar, por ejemplo, reuniones internas de visitas comerciales.
Si solo planificas para ti y no necesitas separar nada, te basta con una única agenda personal.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La agenda es un calendario con nombre que agrupa eventos y se puede compartir. El evento es una cita concreta (título, inicio, fin y detalles) que vive dentro de una agenda y hereda su color.
Asignas a la agenda los usuarios de tu empresa que quieras. Todos los asignados ven y trabajan sobre los mismos eventos. Compartir la agenda comparte sus eventos.
Pegas un email, mensaje o nota y la IA extrae el título, las fechas y un resumen de los detalles. Esos datos se cargan en el formulario de evento para que los revises y confirmes antes de guardar.
El color identifica la agenda a la que pertenece el evento. Así, con varias agendas en el mismo calendario, distingues qué es de cada una.
Sí. Filtra el calendario por la agenda que quieras y verás únicamente sus eventos. Quita el filtro para volver a verlas todas juntas.
***
→ [CRM](/docs/rtg/crm)
→ [Proyectos](/docs/rtg/proyectos)
# Mis Agendas (/docs/rtg/agendas/mis-agendas)
**Mis Agendas** es la lista de tus calendarios. Desde aquí creas agendas nuevas, ves cuántos eventos y usuarios tiene cada una y entras a su detalle. La abres desde **Mis Agendas** en el menú lateral de Agendas.
Una agenda es un calendario con nombre que agrupa eventos; el calendario en sí y la creación de eventos se ven en la pantalla principal.
→ [Agendas](/docs/rtg/agendas)
***
## La lista [#la-lista]
Cada agenda ocupa una fila con estas columnas:
| Columna | Qué muestra |
| ------------------ | ------------------------------------- |
| **Nombre** | El nombre de la agenda. |
| **Descripción** | Su descripción. |
| **Eventos** | Cuántos eventos contiene. |
| **Usuarios** | Cuántos empleados tienen acceso. |
| **Próximo evento** | La fecha y hora del siguiente evento. |
El botón **Nueva Agenda** abre el alta: pones **Nombre** y **Descripción** y guardas. Haz clic en una fila para abrir su detalle.
***
## Detalle de la agenda [#detalle-de-la-agenda]
Al abrir una agenda ves su descripción y dos bloques.
### Eventos [#eventos]
La lista de eventos de la agenda con su título, inicio, fin y detalles. El botón **Nuevo Evento** crea uno ya asignado a esta agenda. Haz clic en un evento para editarlo.
### Usuarios con acceso [#usuarios-con-acceso]
Aquí decides quién más trabaja sobre esta agenda:
* **Asignar**: elige un empleado del desplegable y pulsa **Asignar**. Pasa a ver y trabajar los eventos de la agenda.
* **Desactivar**: quita el acceso de un empleado sin borrar la asignación.
* **Activar**: vuelve a dar acceso a un empleado desactivado.
Cada empleado aparece con su estado, **Activo** o **Inactivo**.
Dar acceso a un empleado le comparte todos los eventos de la agenda. Si quieres que algo lo vea solo una parte del equipo, ponlo en una agenda aparte y asigna únicamente esa.
El botón **Editar** del pie abre el alta de la agenda para cambiar su nombre o su descripción.
***
→ [Agendas](/docs/rtg/agendas)
→ [CRM](/docs/rtg/crm)
# Análisis (/docs/rtg/proyectos/analisis)
El **análisis** es el panel de control de tus proyectos: reúne en una sola pantalla cuántas tareas tienes abiertas, cuáles van con retraso y cuánto tiempo estimaste frente al dedicado de verdad. También señala los fallos de organización que conviene corregir. Sirve para ver el estado del trabajo sin abrir tarea por tarea.
Donde las [vistas](/docs/rtg/proyectos/vistas) te enseñan las tareas una a una para trabajarlas, el análisis te da el resumen: la foto del equipo y del proyecto para decidir dónde poner el foco.
***
## Para qué sirve [#para-qué-sirve]
Tres preguntas que el panel responde sin que tengas que contar a mano:
* **¿Vamos bien de plazos?** Las tareas vencidas y las de esta semana te dicen si el equipo llega o se está acumulando trabajo.
* **¿Cuánto cuesta de verdad cada cosa?** Comparar horas estimadas con horas realizadas revela si planificas bien o te quedas corto una y otra vez.
* **¿Dónde está el atasco?** Las tareas paradas demasiado tiempo en la misma fase marcan el cuello de botella antes de que se convierta en un problema.
Con esos datos repartes carga, ajustas fechas y planificas el siguiente periodo.
***
## El pulso del proyecto [#el-pulso-del-proyecto]
La parte superior del panel es un conjunto de indicadores. Cada vez que alguien crea, mueve o cierra una tarea, los números se actualizan.
| Indicador | Qué te dice |
| ---------------------------------- | ---------------------------------------------------------------------------------------- |
| **Tareas abiertas** | El trabajo vivo: todo lo que aún no está cerrado. Es la carga total pendiente. |
| **Vencidas** | Tareas cuya fecha de vencimiento ya pasó y siguen sin cerrar. Tu lista roja. |
| **De esta semana** | Lo que vence en los próximos días. Anticipa el pico de trabajo. |
| **De hoy** | Lo que toca cerrar hoy. El foco inmediato del equipo. |
| **Horas estimadas vs. realizadas** | Lo que pensabas que costaría frente a lo que ha costado. Mide tu precisión planificando. |
Las **horas estimadas vs. realizadas** solo tienen sentido si rellenas la estimación al crear la tarea y registras el tiempo mientras trabajas. Cuanto más completos estén esos datos, más fiable es la comparación. Aprende a estimar y cronometrar en → [Tareas](/docs/rtg/proyectos/tareas).
***
## Alertas de higiene [#alertas-de-higiene]
Además de los números, el panel señala las tareas mal cuidadas: las que les falta un dato clave o llevan demasiado tiempo sin avanzar. Son los puntos que ensucian la planificación y que conviene arreglar.
| Alerta | Por qué importa |
| --------------------------------------- | ---------------------------------------------------------------------------------------------- |
| **Sin responsable** | Una tarea sin asignar es una tarea que nadie va a hacer. |
| **Sin fecha de vencimiento** | Sin plazo no entra en "vencidas" ni "de esta semana": se queda invisible. |
| **Sin estimación** | Sin horas estimadas no puede compararse con las realizadas y queda fuera del cálculo de carga. |
| **Parada demasiado tiempo en una fase** | Lleva días en el mismo estado: probable bloqueo o tarea olvidada. |
| **Crítica sin actividad reciente** | Una tarea importante que nadie toca es un riesgo silencioso. |
Revisa estas alertas de vez en cuando y tendrás un backlog limpio: cada tarea con dueño, fecha y estimación. Eso es justo lo que hace que el resto de indicadores sean fiables.
***
## Combinar filtros [#combinar-filtros]
El panel y las [vistas](/docs/rtg/proyectos/vistas) comparten una barra de filtros que puedes **combinar** para acotar exactamente lo que quieres mirar. En lugar de elegir un solo criterio, encadenas varios y el conjunto se reduce al cruce de todos ellos.
Filtras por:
* **Responsable**: solo las tareas de una persona (o las tuyas).
* **Estado**: abiertas, en curso, bloqueadas, cerradas…
* **Tipo**: bug, mejora, feature, investigación…
* **Prioridad**: críticas, altas, normales.
* **Fecha**: vencidas, de esta semana, de un periodo concreto.
Algunos cruces típicos:
* **Mías + abiertas + alta prioridad + vencidas** → tu lista de urgencias personales.
* **Del proyecto X + del responsable Y + de este periodo** → la carga real de una persona en una etapa concreta.
* **Tipo bug + sin responsable** → fallos registrados que nadie ha cogido todavía.
Cuando un cruce de filtros te resulte útil, **guárdalo como vista favorita**. La próxima vez lo abres con un clic en lugar de volver a montarlo filtro a filtro.
***
## Cómo leer el panel en la práctica [#cómo-leer-el-panel-en-la-práctica]
Una rutina sencilla para sacarle partido:
### Mira el pulso [#mira-el-pulso]
Empieza por los indicadores de arriba. Si **vencidas** crece o las horas realizadas se disparan sobre las estimadas, hay algo que corregir.
### Limpia las alertas de higiene [#limpia-las-alertas-de-higiene]
Asigna responsable a lo que esté huérfano, pon fechas a lo que no las tenga y revisa lo que lleva parado demasiado tiempo. Cada arreglo mejora la calidad de los datos.
### Acota con filtros [#acota-con-filtros]
Filtra por responsable para ver la carga de cada persona, o por proyecto y periodo para medir un sprint. Así pasas del resumen global al detalle que te interesa.
### Decide y reparte [#decide-y-reparte]
Con la foto clara, mueve fechas, reasigna tareas o descompón las que se han hecho enormes. El panel vuelve a actualizarse y compruebas el efecto.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Porque no tiene fecha de vencimiento. Sin plazo, el panel no puede saber si llega tarde. Asígnale una fecha y entrará en los indicadores. La alerta de higiene "sin fecha de vencimiento" te ayuda a encontrar estos casos.
La estimación es lo que previste al crear la tarea; las realizadas son el tiempo que has registrado de verdad. Si difieren mucho, o estimaste corto o no se está apuntando bien el tiempo. Es justo la señal que te ayuda a planificar mejor la próxima vez.
Sí. Esa es su gracia: encadenas responsable, estado, tipo, prioridad y fecha a la vez, y el resultado es el cruce de todos. Si un cruce te sirve a menudo, guárdalo como vista favorita.
Las tareas paradas demasiado tiempo en la misma fase. Señalan trabajo bloqueado u olvidado. Combínalo con el filtro por estado "bloqueada" para ver el atasco completo.
***
→ [Tareas](/docs/rtg/proyectos/tareas)
→ [Vistas](/docs/rtg/proyectos/vistas)
→ [Proyectos](/docs/rtg/proyectos)
# Bonos de horas (/docs/rtg/proyectos/bonos-de-horas)
Un **bono de horas** es una bolsa de tiempo asociada a un cliente: las horas que le has vendido para trabajar en sus proyectos. Enlazas el proyecto al bono y el trabajo cronometrado va descontando de esa bolsa.
***
## Cómo se enlaza [#cómo-se-enlaza]
Un bono siempre pertenece a un **cliente**. Para usarlo, el proyecto tiene que apuntar a ese cliente y a su bono.
* Al [crear un proyecto](/docs/rtg/proyectos), eliges primero el **cliente**; en cuanto lo seleccionas, aparece el selector de **bono** con las bolsas de ese cliente.
* En la ventana de edición del proyecto puedes cambiar el cliente y el bono en cualquier momento, en la sección **Cliente**.
El selector de bono solo aparece cuando el proyecto tiene cliente. Sin cliente no hay bono al que imputar las horas.
***
## Ampliar un bono [#ampliar-un-bono]
Cuando un bono se agota, no creas otro: le sumas horas con una **ampliación**. La ampliación se enlaza al bono existente y aumenta el total disponible, así que el histórico de consumo se mantiene en una sola bolsa.
***
## Dónde se consume [#dónde-se-consume]
El consumo sale del **tiempo real** de las tareas del proyecto. Cada [actividad cronometrada](/docs/rtg/proyectos/funciones-avanzadas) descuenta del bono. Los importes se computan cuando la tarea está **finalizada**.
Ves el resultado en la pestaña **Bonos y horas** del [panel de análisis](/docs/rtg/proyectos/panel-analisis), con tres cortes del detalle monetario: por bono, por cliente y por proyecto.
***
## Dónde se administran [#dónde-se-administran]
Los bonos, sus tipos y estados, y las ampliaciones viven en la [configuración](/docs/rtg/proyectos/configuracion) de la app, en las pestañas **Bonos** y **Ampliaciones Bonos**. Ahí los das de alta y los editas.
***
→ [Configuración](/docs/rtg/proyectos/configuracion)
→ [Panel de análisis](/docs/rtg/proyectos/panel-analisis)
→ [Funciones avanzadas](/docs/rtg/proyectos/funciones-avanzadas)
# Colaborar en una tarea (/docs/rtg/proyectos/colaboracion)
Cada [tarea](/docs/rtg/proyectos/tareas) tiene su propio hilo de colaboración. Ahí comentas, mencionas a un compañero para avisarle, adjuntas imágenes o documentos y dejas constancia de las decisiones. Todo el contexto vive junto a la tarea.
***
## El hilo de comentarios [#el-hilo-de-comentarios]
Dentro de la tarea encuentras la zona de **comentarios**. Es el lugar donde el equipo habla sobre ese trabajo concreto: dudas, avances, validaciones o un mensaje para tu asesor.
Cada comentario se guarda con **autor y fecha**, así que siempre sabes quién dijo qué y cuándo. El editor es **enriquecido**: puedes dar formato al texto con negritas, listas y enlaces para que un mensaje largo se lea bien.
Comenta dentro de la tarea en lugar de por correo o chat externo. El día que alguien retome el trabajo, todo el contexto estará en el mismo sitio que la tarea.
***
## Mencionar a un compañero [#mencionar-a-un-compañero]
Cuando necesitas que alguien concreto lea tu comentario, **menciónalo**.
### Escribe @ en el comentario [#escribe--en-el-comentario]
Al teclear `@` aparece un buscador con los miembros del proyecto. Empieza a escribir el nombre y selecciónalo.
### Termina y publica el comentario [#termina-y-publica-el-comentario]
El nombre mencionado queda resaltado dentro del texto, enlazado a esa persona.
### El compañero recibe el aviso [#el-compañero-recibe-el-aviso]
La persona mencionada recibe una **notificación inmediata** para que sepa que la necesitas en esa tarea, sin tener que estar vigilando el tablero.
Solo puedes mencionar a miembros del proyecto. Si alguien no aparece en el buscador, primero añádelo al equipo del proyecto.
***
## Adjuntar archivos [#adjuntar-archivos]
Suma a la tarea todo lo que ayude a entenderla o resolverla: una captura del error, el PDF del contrato, el documento con las especificaciones.
* Adjunta el archivo **al comentario** (para acompañar un mensaje) o **a la propia tarea** (para que quede como material de referencia).
* Admite **imágenes, PDF y documentos**, entre otros tipos de archivo.
* Los adjuntos quedan **centralizados en la tarea**: cualquier miembro del proyecto los encuentra ahí, junto al hilo y al historial.
Si informas de un problema, adjunta una captura de lo que ves: ahorras explicaciones y evitas malentendidos.
***
## Pedir ayuda a la IA [#pedir-ayuda-a-la-ia]
El agente de IA de tu empresa es **un participante más del hilo**. Lo invocas igual que a un compañero: lo **mencionas con `@`** en un comentario y le pides lo que necesites. Tiene contexto de la tarea, sus comentarios, el proyecto y el estado, así que responde sobre ese trabajo concreto.
Cosas que le puedes pedir dentro de una tarea:
| Le pides | Para qué sirve |
| --------------------------- | ----------------------------------------------------------------------------------------- |
| **Resumir el hilo** | Te pones al día cuando hay muchos comentarios o acabas de entrar a la tarea. |
| **Qué queda pendiente** | Saca lo que aún falta por hacer a partir de la conversación, sin que tengas que releerla. |
| **Proponer subtareas** | Descompone un trabajo grande en pasos más pequeños y manejables. |
| **Buscar tareas similares** | Localiza tareas parecidas ya cerradas en el proyecto, por si la solución ya existe. |
Por defecto la IA propone y confirmas tú. No actúa por su cuenta salvo que le des permiso explícito.
→ [Casos de uso de la IA por módulo](/docs/rtg/ia/casos-por-modulo)
***
## Preguntas frecuentes [#preguntas-frecuentes]
A cualquier miembro del proyecto. Al escribir @ aparece el buscador con esos miembros. Si alguien no sale, añádelo antes al equipo del proyecto.
Sí. Cuando mencionas a alguien con @, recibe una notificación inmediata avisándole de que se le requiere en esa tarea.
Imágenes, PDF y documentos, entre otros tipos. Puedes adjuntarlos a un comentario concreto o a la tarea, y quedan centralizados junto al hilo.
Mencionas al agente con @ en un comentario, igual que a un compañero, y le pides lo que necesites: resumir el hilo, decirte qué queda pendiente, proponer subtareas o buscar tareas similares ya cerradas.
No. Por defecto sugiere y confirmas tú. Solo actúa por su cuenta si le concedes permiso explícito para ello.
***
→ [Tareas](/docs/rtg/proyectos/tareas)
→ [Proyectos](/docs/rtg/proyectos)
→ [Casos de uso de la IA por módulo](/docs/rtg/ia/casos-por-modulo)
# Configuración (/docs/rtg/proyectos/configuracion)
## Antes de empezar [#antes-de-empezar]
La configuración solo está disponible para usuarios **administradores**. La abres desde **Configuración**, al pie del menú lateral.
***
La **configuración** reúne las tablas base de la app. Cada bloque es un catálogo que puedes editar directamente, con sus categorías y sus fases. Lo que definas aquí es lo que luego eliges al crear proyectos y tareas.
La pantalla se organiza en pestañas a la izquierda; dentro de cada una, un juego de sub-pestañas separa el listado, los tipos y los estados.
***
## Proyectos [#proyectos]
El catálogo de proyectos y todo lo que los clasifica.
| Sub-pestaña | Qué contiene |
| -------------------- | ------------------------------------------------------------------------------------------------- |
| **Proyectos** | El listado completo de proyectos. Al abrir uno, se edita en su ventana. |
| **Tipo Proyectos** | Las categorías con las que agrupas proyectos. |
| **Estado Proyectos** | Las fases por las que pasa un proyecto. |
| **Flujos** | Los recorridos de estados que puede seguir una tarea. Ver → [Flujos](/docs/rtg/proyectos/flujos). |
***
## Tareas [#tareas]
El catálogo de tareas y sus clasificadores.
| Sub-pestaña | Qué contiene |
| ----------------- | ------------------------------------------- |
| **Tareas** | Todas las tareas de todos los proyectos. |
| **Tipo Tareas** | Los tipos de tarea (bug, mejora, feature…). |
| **Estado Tareas** | Los estados por los que pasa una tarea. |
***
## Actividades [#actividades]
El registro del tiempo cronometrado sobre las tareas.
| Sub-pestaña | Qué contiene |
| -------------------- | ---------------------------------------- |
| **Actividad** | El listado de actividades cronometradas. |
| **Tipo Actividad** | Las categorías de actividad. |
| **Estado Actividad** | Las fases de una actividad. |
***
## Bonos y ampliaciones [#bonos-y-ampliaciones]
Las bolsas de horas con las que facturas el trabajo a un cliente.
| Pestaña | Qué contiene |
| ---------------------- | -------------------------------------------------------------------- |
| **Bonos** | Las bolsas de horas, con sus tipos y estados. |
| **Ampliaciones Bonos** | Las horas que se suman a un bono existente, con sus tipos y estados. |
Cómo funcionan y cómo se enlazan al proyecto → [Bonos de horas](/docs/rtg/proyectos/bonos-de-horas).
***
→ [La app Tareas](/docs/rtg/proyectos/inicio)
→ [Flujos](/docs/rtg/proyectos/flujos)
→ [Bonos de horas](/docs/rtg/proyectos/bonos-de-horas)
# Espacio de trabajo del proyecto (/docs/rtg/proyectos/espacio-de-trabajo)
Al abrir un proyecto entras en su **espacio de trabajo**: la pantalla donde ves y mueves sus tareas. Todo el proyecto cabe aquí, y cambias de ángulo con los botones de vista sin salir.
***
## La cabecera [#la-cabecera]
Arriba del todo, la barra que identifica el proyecto y da acceso a sus acciones.
* **Icono**: el símbolo del proyecto. Púlsalo para cambiarlo.
* **Nombre** y **clave**: el título y el prefijo de las tareas (por ejemplo, `MKT`).
* **Avatares del equipo**: las fotos de los miembros. Si son más de ocho, el último indica cuántos faltan.
* **Nuevo tema**: crea un tema para agrupar tareas relacionadas.
* **Configuración** (icono de engranaje): abre los ajustes del proyecto.
Si no eres miembro del proyecto, la pantalla te avisa y no muestra las tareas. Pide al líder que te añada al equipo desde la configuración del proyecto.
***
## La barra de filtros [#la-barra-de-filtros]
Debajo de la cabecera tienes el **SmartFilter**: filtras por texto, por persona, por tipo o por estado, y apilas varios criterios a la vez. Los filtros viajan en la URL, así que compartes una vista filtrada con solo pasar el enlace.
Referencia completa de filtros rápidos y prefijos de búsqueda en → [Funciones avanzadas](/docs/rtg/proyectos/funciones-avanzadas).
***
## Las cuatro vistas [#las-cuatro-vistas]
A la derecha de los filtros, cuatro botones cambian cómo se dibujan las tareas. Es el mismo trabajo mirado de otra forma; el botón activo queda resaltado.
| Botón | Vista | Para qué |
| ------ | ------------ | -------------------------------------------------------------- |
| Lista | **Compacta** | Una lista plana agrupada por estado. |
| Kanban | **Kanban** | Un tablero con una columna por estado; arrastras las tarjetas. |
| Tabla | **Tabla** | La rejilla editable con todos los campos en columnas. |
| Gantt | **Gantt** | La línea temporal con fechas, dependencias y ruta crítica. |
Cada vista tiene su propia URL (`/Kanban`, `/Workitems`, `/Gantt`), de modo que un enlace abre el proyecto ya en la vista que elijas.
Para qué destaca cada vista y cuándo usarla → [Vistas](/docs/rtg/proyectos/vistas).
***
## Añadir una tarea sin salir [#añadir-una-tarea-sin-salir]
Bajo la vista tienes siempre el **alta en línea**: escribes el título y la tarea se crea en el proyecto, sin abrir una ventana. Es la vía rápida para vaciar la cabeza de pendientes; los detalles los rellenas después abriendo la tarea.
***
## Abrir una tarea [#abrir-una-tarea]
Al pulsar una tarea se abre en una **ventana flotante** que puedes mover y redimensionar. Dentro tienes su título, las instrucciones, el hilo de comentarios y una barra lateral con estado, responsable, supervisor, tipo, prioridad, fechas, esfuerzo y dependencias.
* Anatomía de los campos → [Tareas](/docs/rtg/proyectos/tareas).
* Comentarios, menciones y adjuntos → [Colaborar en una tarea](/docs/rtg/proyectos/colaboracion).
***
## Mi día [#mi-día]
**Mi día** es tu pantalla personal, fuera de un proyecto concreto. Reúne las tareas asignadas a ti de todos los proyectos y las agrupa por estado: En proceso, Pausadas, Pendientes, Completadas, Canceladas y Backlog. Cada fila muestra el título, la clave, el proyecto, la prioridad, el vencimiento y un candado si la tarea espera a otra. La abres desde el menú lateral.
***
## Ventanas [#ventanas]
Acciones del espacio de trabajo que se abren en una ventana propia:
* **Nuevo tema**: título, responsable e instrucciones con editor enriquecido para agrupar tareas bajo un objetivo.
* **Configuración del proyecto** (Ajustes): pestañas de **Equipo**, **Información** (descripción) y **Archivos**.
* **Iniciar actividad**: pide una nota corta y arranca el cronómetro de la tarea.
* **Dependencia**: busca otra tarea y define la relación (bloquea a, bloqueada por, empiezan a la vez, terminan a la vez).
* **Selector de icono**: elige el símbolo del proyecto desde la cabecera.
***
→ [La app Tareas](/docs/rtg/proyectos/inicio)
→ [Vistas](/docs/rtg/proyectos/vistas)
→ [Tareas](/docs/rtg/proyectos/tareas)
# Flujos (/docs/rtg/proyectos/flujos)
Un **flujo** define los estados por los que pasan las tareas de un proyecto y cómo transitan de uno a otro. Es el "recorrido" que sigue cada tarea desde que nace hasta que la das por terminada.
El flujo que eliges marca dos cosas:
* Las **columnas del tablero Kanban**: cada estado del flujo es una columna.
* La **lógica de transición**: qué pasos existen, en qué orden avanzan y qué tipos de tarea pueden colgar de otros (jerarquía padre-hijo).
El flujo se elige **al crear el proyecto**, junto con el título y la clave. Distintos proyectos pueden usar flujos distintos según cómo trabaje cada equipo.
***
## Elegir un flujo [#elegir-un-flujo]
Cuando das de alta un proyecto, eliges su flujo entre los tipos predefinidos. La regla rápida: a más sencillo el trabajo, más simple el flujo.
| Flujo | ¿Cuándo elegirlo? | Lo que ofrece |
| ------------- | -------------------------------- | ------------------------------------------------------------------------------------- |
| **To Do** | Listas simples de tareas | Dos pasos: `Por hacer` y `Hecho`. |
| **To Do Pro** | Seguimiento detallado del avance | `Por hacer`, porcentajes `1 %`, `25 %`, `50 %`, `75 %` y `Hecho`. Permite sub-tareas. |
| **Waterfall** | Proyectos por fases, en cascada | Las tareas avanzan en orden de una fase a la siguiente, sin solaparse. |
| **Agile** | Equipos que usan Scrum o Kanban | Epics, Stories, Tasks, Sub-tasks y registro de Bugs. |
Si dudas, empieza por **To Do**. Siempre puedes llevar un proyecto a un flujo más completo cuando tu equipo lo necesite.
***
## Cómo leer las tablas de un flujo [#cómo-leer-las-tablas-de-un-flujo]
Cada flujo se describe con una tabla de estados. Las columnas significan:
* **Tipo**: la categoría de la tarea (Task, Sub-task, Epic, Story, Bug…). Define el nivel jerárquico.
* **Estado**: el paso concreto dentro del flujo (To Do, In Progress, Done, un porcentaje…). Cada estado es una columna del Kanban.
* **Clave**: el identificador corto del estado dentro del flujo, para referirte a él sin ambigüedad.
* **Padres compatibles**: de qué estados puede colgar esa tarea. Así se construye la jerarquía: una Sub-task solo cuelga de una Task, una Story de un Epic, etc. Un `@` significa que es un elemento de primer nivel (no cuelga de nadie).
***
## To Do (flujo básico) [#to-do-flujo-básico]
El flujo más sencillo: perfecto para tomar nota de algo y marcarlo cuando se termina.
| Tipo | Estado | Clave | Padres compatibles |
| ---- | ------ | ----- | ------------------ |
| Task | To Do | T1 | @ |
| Task | Done | T2 | @ |
***
## To Do Pro (flujo extendido) [#to-do-pro-flujo-extendido]
Mismo planteamiento que el básico, pero con porcentajes de avance y la posibilidad de desglosar cada tarea en sub-tareas medibles.
| Tipo | Estado | Clave | Padres compatibles |
| ------------ | ------ | ----- | ------------------ |
| **Task** | To Do | T1 | @ |
| Task | 1 % | T2 | @ |
| Task | 25 % | T3 | @ |
| Task | 50 % | T4 | @ |
| Task | 75 % | T5 | @ |
| Task | Done | T6 | @ |
| **Sub-task** | To Do | ST1 | T1,T2,T3,T4,T5,T6 |
| Sub-task | 1 % | ST2 | T1,T2,T3,T4,T5,T6 |
| Sub-task | 25 % | ST3 | T1,T2,T3,T4,T5,T6 |
| Sub-task | 50 % | ST4 | T1,T2,T3,T4,T5,T6 |
| Sub-task | 75 % | ST5 | T1,T2,T3,T4,T5,T6 |
| Sub-task | Done | ST6 | T1,T2,T3,T4,T5,T6 |
Los porcentajes te dan una lectura del avance en el Kanban, sin abrir cada tarea.
***
## Waterfall (en cascada) [#waterfall-en-cascada]
Pensado para proyectos que avanzan **por fases consecutivas**: una etapa se cierra antes de empezar la siguiente, sin solapamientos. Las tareas recorren los estados en orden, de principio a fin, en lugar de moverse libremente entre columnas.
Es el flujo natural cuando el trabajo tiene una secuencia clara y cada paso depende de que el anterior esté terminado.
***
## Agile (flujo completo) [#agile-flujo-completo]
Flujo pensado para equipos Scrum/Kanban: los **epics** agrupan stories, las **stories** agrupan tasks y cada **task** puede desglosarse en sub-tareas. Además, tienes **bugs** independientes que se registran contra los epics.
| Tipo | Estado | Clave | Padres compatibles |
| ------------ | ----------- | ----- | -------------------- |
| **Epic** | Backlog | E1 | @ |
| Epic | To Do | E2 | @ |
| Epic | In Progress | E3 | @ |
| Epic | Done | E4 | @ |
| **Story** | Backlog | S1 | E1,E2,E3,E4 |
| Story | To Do | S2 | E1,E2,E3,E4 |
| Story | In Progress | S3 | E1,E2,E3,E4 |
| Story | Done | S4 | E1,E2,E3,E4 |
| **Task** | Backlog | T1 | S1,S2,S3,S4 |
| Task | In Progress | T3 | S1,S2,S3,S4 |
| Task | 25 % | T4 | S1,S2,S3,S4 |
| Task | 50 % | T5 | S1,S2,S3,S4 |
| Task | 75 % | T6 | S1,S2,S3,S4 |
| Task | Done | T7 | S1,S2,S3,S4 |
| **Sub-task** | Backlog | ST1 | T1,T2,T3,T4,T5,T6,T7 |
| Sub-task | To Do | ST2 | T1,T2,T3,T4,T5,T6,T7 |
| Sub-task | In Progress | ST3 | T1,T2,T3,T4,T5,T6,T7 |
| Sub-task | Done | ST4 | T1,T2,T3,T4,T5,T6,T7 |
| **Bug** | To Do | B2 | E1,E2,E3,E4 |
| Bug | In Progress | B3 | E1,E2,E3,E4 |
| Bug | Done | B4 | E1,E2,E3,E4 |
***
## Flujo y tablero Kanban [#flujo-y-tablero-kanban]
Sea cual sea el flujo, sus estados se convierten en las **columnas del Kanban**. Mover una tarjeta de una columna a otra cambia el estado de la tarea, y la jerarquía de tipos (epics, stories, tasks, sub-tasks) determina qué puede colgar de qué.
Por eso, elegir bien el flujo al crear el proyecto es lo que hace que tu tablero refleje de verdad cómo trabaja tu equipo.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Al crear el proyecto, junto con el título y la clave. Cada proyecto tiene su propio flujo, así que puedes usar uno distinto en cada equipo según cómo trabaje.
Directa: cada estado del flujo es una columna del tablero Kanban. El flujo define las columnas y la lógica de transición entre ellas.
To Do tiene solo dos pasos (Por hacer y Hecho). To Do Pro añade porcentajes de avance (1 %, 25 %, 50 %, 75 %) y permite desglosar cada tarea en sub-tareas medibles.
Indica de qué estados puede colgar una tarea, lo que construye la jerarquía del flujo. Por ejemplo, una Sub-task solo cuelga de una Task. Un `@` marca un elemento de primer nivel que no cuelga de nadie.
***
→ [Volver a Proyectos](/docs/rtg/proyectos)
# Funciones avanzadas (/docs/rtg/proyectos/funciones-avanzadas)
Cuando ya manejas [tareas](/docs/rtg/proyectos/tareas) y [vistas](/docs/rtg/proyectos/vistas), Proyectos añade herramientas para ir más allá: estimar cuánto cuesta cada tarea, medir el tiempo real que dedicas, agrupar trabajo relacionado, filtrar y atender peticiones de soporte.
***
## Esfuerzo planificado frente a tiempo real [#esfuerzo-planificado-frente-a-tiempo-real]
Cada tarea puede llevar una **estimación de esfuerzo**: cuánto crees que va a costar sacarla adelante. Lo defines en el campo **Esfuerzo plan.** dentro de la tarea, junto a la fecha de inicio y el vencimiento.
A medida que el equipo trabaja, Dinaup acumula el **tiempo real** dedicado y lo enfrenta a tu estimación. Así ves si una tarea va sobrada, ajustada o se ha disparado.
| Dato | Qué es | De dónde sale |
| -------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Esfuerzo planificado | Tu estimación de cuánto costará la tarea | Lo escribes tú al crear o editar la tarea |
| Tiempo real | Lo que de verdad se ha dedicado | Se suma desde las [actividades temporizadas](#actividades-temporizadas-el-cronometro-de-cada-tarea) |
| Tiempo adicional | Trabajo que hiciste sin cronometrar | Lo añades a mano para que el total cuadre |
La estimación no bloquea nada: una tarea sigue avanzando aunque supere su esfuerzo previsto. El valor está en **comparar**, no en imponer un límite. Si una tarea siempre se pasa de lo estimado, ahí tienes una señal para revisar cómo planificas.
El **tiempo adicional** existe para los casos en que trabajaste sin poner el cronómetro en marcha. Lo sumas a mano y el total refleja la realidad, no solo lo que quedó cronometrado.
***
## Actividades temporizadas: el cronómetro de cada tarea [#actividades-temporizadas-el-cronómetro-de-cada-tarea]
Una **actividad** es un periodo de trabajo cronometrado sobre una tarea concreta. En lugar de apuntar horas de memoria al final del día, pones en marcha un cronómetro cuando empiezas y lo paras cuando terminas. Ese tiempo se suma solo al **tiempo real** de la tarea.
### Inicia la actividad [#inicia-la-actividad]
En la tarea, pulsa el botón de **iniciar actividad**. Dinaup te pregunta *¿Qué actividad vas a comenzar?* para que dejes una nota corta de en qué estás trabajando (por ejemplo, "maquetando la portada" o "llamada con el cliente").
### Trabaja con el cronómetro en marcha [#trabaja-con-el-cronómetro-en-marcha]
Mientras la actividad está abierta, la tarea muestra que hay trabajo en curso. Puedes seguir con lo tuyo: el tiempo corre en segundo plano y se refleja al momento para todo el equipo.
### Detén la actividad [#detén-la-actividad]
Cuando terminas, pulsas **detener** y el tiempo de esa sesión queda sumado al tiempo real de la tarea. Puedes abrir y cerrar tantas actividades como necesites a lo largo del día.
Cada actividad queda **asociada a la persona** que la inició, así que el tiempo dedicado se reparte correctamente por miembro del equipo. Esto alimenta los gráficos de carga y esfuerzo del [análisis](/docs/rtg/proyectos/analisis).
Combinado con el esfuerzo planificado, el cronómetro cierra el círculo: estimas, trabajas cronometrando y al final comparas lo previsto con lo real, tarea a tarea y persona a persona.
***
## Temas: agrupar tareas relacionadas [#temas-agrupar-tareas-relacionadas]
Un **tema** agrupa un conjunto de tareas que persiguen un mismo objetivo más grande. Si una tarea es "un paso", un tema es "el trabajo completo" que reúne varios pasos relacionados: el lanzamiento de una campaña, la puesta en marcha de un cliente, una mejora del producto.
Al crear un tema le das un **título** y unas **instrucciones** con un editor de texto enriquecido, donde puedes detallar el contexto, listar lo que hay que hacer y **mencionar** a compañeros para implicarlos. A partir de ahí, el tema sirve de paraguas para las tareas que cuelguen de él.
Usa temas cuando un objetivo es demasiado grande para una sola tarea pero quieres seguirlo como una unidad. Para el trabajo del día a día, una tarea suelta es suficiente: no conviertas cada cosa en un tema o perderás la ventaja de agrupar.
Los temas conviven con las [dependencias entre tareas](/docs/rtg/proyectos/tareas): el tema dice *qué cosas van juntas* por objetivo, y las dependencias dicen *en qué orden* deben ocurrir.
***
## Filtrar tareas [#filtrar-tareas]
La barra de filtros te deja acotar la lista de tareas. Funciona de dos formas que puedes combinar: **filtros rápidos** y **búsqueda con prefijos**.
### Filtros rápidos [#filtros-rápidos]
Desde el desplegable de filtros activas presets de uso común. Cada filtro que activas aparece como una **etiqueta de color** que puedes quitar pulsando la equis.
| Filtro rápido | Qué muestra |
| ----------------------- | -------------------------------------------------- |
| Abiertas | Solo tareas que no están completadas ni canceladas |
| Mis tareas | Solo las tareas asignadas a ti |
| Sin asignar | Tareas que aún no tienen responsable |
| Vencidas | Tareas cuya fecha límite ya pasó |
| Esta semana | Tareas que vencen en la semana en curso |
| Prioridad alta | Solo prioridades Alta, Muy Alta y Urgente |
| En proceso / Pendientes | Filtra por el estado del trabajo |
| Todas | Quita todos los filtros de golpe |
### Búsqueda con prefijos [#búsqueda-con-prefijos]
En el cuadro de búsqueda puedes escribir texto libre para buscar dentro de las tareas, o usar **prefijos** para filtrar por un criterio concreto. Funcionan en **español e inglés**, y mientras escribes aparecen sugerencias.
| Escribe | Filtra por |
| --------------------- | ---------------------------------------------------------- |
| `nat:` o `nature:` | Naturaleza del estado (Pendiente, En proceso, Completado…) |
| `@usuario` | Persona asignada |
| `tipo:` o `type:` | Tipo de tarea |
| `estado:` o `status:` | Estado concreto del flujo |
| Texto suelto | Busca esa palabra dentro del contenido de las tareas |
Puedes **apilar varios filtros a la vez**: por ejemplo, "Mis tareas" + "Vencidas" + `tipo:` para ver tus tareas de un tipo que ya se te han pasado. Cada filtro que añades estrecha más la lista, y el botón de limpiar los borra todos de una vez.
Los filtros se aplican a la vista que tengas delante, así que sirven igual en una [lista, un tablero o un calendario](/docs/rtg/proyectos/vistas).
***
## Tickets de soporte [#tickets-de-soporte]
Si tu equipo atiende peticiones (de clientes, de otros departamentos o internas), los **tickets** te dan un espacio dentro de Proyectos para registrarlas y darles seguimiento sin mezclarlas con las tareas de trabajo.
Cada ticket recoge la petición y avanza por sus propios estados hasta que se resuelve. Para adaptarlos a tu operativa, los tickets se organizan en tres apartados:
* **Tickets**: el listado de peticiones, donde las creas, consultas y trabajas.
* **Tipos**: las categorías con las que clasificas los tickets (por ejemplo, incidencia, consulta o solicitud), para saber de qué va cada uno.
* **Estados**: las fases por las que pasa un ticket desde que entra hasta que se cierra, ajustadas a tu forma de atender.
Define primero tus **tipos** y **estados** y luego empieza a registrar tickets: así todos entran ya clasificados y con un recorrido claro hasta su resolución.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El esfuerzo planificado es tu estimación, la escribes tú. El tiempo real es lo que de verdad se ha dedicado, y se acumula desde las actividades cronometradas. Comparar ambos te dice si una tarea va según lo previsto.
Usa el campo de tiempo adicional dentro de la tarea para sumar a mano las horas que no quedaron cronometradas. Así el tiempo total refleja todo el trabajo, no solo lo cronometrado.
Crea un tema cuando un objetivo es demasiado grande para una sola tarea y quieres agrupar varias tareas relacionadas bajo un mismo paraguas. Para el trabajo del día a día, una tarea suelta basta.
Sí. Los filtros rápidos y los prefijos de búsqueda se apilan: cada uno que añades estrecha más la lista. El botón de limpiar los quita todos de golpe.
No. Las tareas son el trabajo que planificas; los tickets son peticiones que atiendes. Tienen sus propios tipos y estados para que el soporte no se mezcle con la operativa de proyecto.
***
→ [Tareas](/docs/rtg/proyectos/tareas)
→ [Vistas](/docs/rtg/proyectos/vistas)
→ [Colaboración](/docs/rtg/proyectos/colaboracion)
→ [Análisis](/docs/rtg/proyectos/analisis)
# Proyectos (/docs/rtg/proyectos)
Organiza el trabajo de tu equipo (proyectos y tareas) dentro del mismo ecosistema que el resto de Dinaup. Ventas, clientes, TPV, cajas, documentos y tiempo trabajan sobre la misma información, sin duplicar datos.
***
## Qué es un proyecto [#qué-es-un-proyecto]
Un **proyecto** es el contenedor donde agrupas el trabajo de un área, un cliente o un equipo. Cada proyecto tiene:
* **Título**: el nombre con el que lo identificas.
* **Icono y color**: la pista visual para reconocerlo entre los demás.
* **Clave**: un prefijo corto (por ejemplo, `MKT-`) que antecede al identificador de cada tarea, de forma que las tareas quedan numeradas y rastreables (`MKT-042`).
* **Miembros**: las personas con acceso, ya sean compañeros internos o colaboradores externos, cada una con sus permisos.
* **Flujo**: el recorrido de estados y tipos de tarea que siguen los trabajos de ese proyecto, desde que nacen hasta que se cierran.
Dentro de un proyecto creas **tareas**, las mueves entre estados, las asignas, registras el tiempo que inviertes y comentas con tu equipo. Todo queda centralizado en la ficha del proyecto.
La **clave** es la espina dorsal de la trazabilidad: cualquiera puede referirse a una tarea por su identificador (`MKT-042`) en un comentario, un email o una factura, y todo el mundo sabe de qué se habla.
***
## Qué puedes hacer [#qué-puedes-hacer]
* **Crear y configurar proyectos** con título, icono, clave, flujo y descripción rica para fijar alcance y objetivos.
* **Gestionar el equipo**: añade compañeros o colaboradores externos con permisos de ver o editar.
* **Dar de alta tareas** con resumen, instrucciones, fechas, estado, tipo, prioridad, estimación y responsable.
* **Trabajar con la vista que prefieras**: Mi Día, Kanban, Gantt, Lista o Compacta.
* **Asignar desde la propia tarjeta**, sin abrir la tarea completa.
* **Actualizar progreso y prioridad** desde menús rápidos, con plantillas de fecha (hoy, mañana, próximo lunes…).
* **Registrar tiempo** con un cronómetro que sigue activo aunque cambies de aplicación.
* **Colaborar** comentando, mencionando compañeros y adjuntando archivos en el hilo de cada tarea.
* **Analizar la salud del trabajo** con un panel de pulso y alertas de higiene del backlog.
* **Conectar con el resto de Dinaup**: vincula tareas con presupuestos, pedidos y ventas, y deja que las acciones de un módulo alimenten a otro.
***
## Explora la documentación [#explora-la-documentación]
Cada pieza de Proyectos tiene su propia página:
Da de alta tareas, rellena sus campos, gestiona dependencias y entiende los campos calculados.
Mi Día, Kanban, Gantt, Lista y Compacta: elige cómo ver tu trabajo según cómo trabajes.
Comentarios, menciones, adjuntos y línea de tiempo de actividad dentro de cada tarea.
Estados y tipos de tarea: To Do, To Do Pro y Agile, listos para usar o a tu medida.
Panel de pulso del proyecto y alertas de higiene del backlog para detectar lo que se atasca.
***
## Crear un proyecto [#crear-un-proyecto]
Desde el menú lateral de **Proyectos** creas proyectos y cambias entre ellos. Al crear uno defines:
* **Título**, **icono** y **color** para identificarlo.
* **Clave**: el prefijo de los identificadores de tarea (por ejemplo `MKT-`).
* **Flujo**: el recorrido de estados y tipos de tarea. Si dudas, empieza por uno sencillo y cámbialo después; ver → [Flujos](/docs/rtg/proyectos/flujos).
* **Descripción** para que el equipo comparta el mismo contexto.
* **Miembros**: compañeros internos o colaboradores externos, cada uno con permisos de ver o editar.
***
## La tarea, sin abrirla [#la-tarea-sin-abrirla]
Buena parte del trabajo diario se resuelve desde la propia tarjeta, sin entrar en la ficha completa:
* **Asignación rápida**: busca un usuario y cambia el responsable.
* **Progreso**: fija el avance (1 %, 25 %, 50 %, 75 % o completada); el tablero se refresca al momento.
* **Prioridad y vencimiento**: desde el menú contextual, con plantillas de fecha (hoy, mañana, próximo lunes, mes próximo…).
Referencia completa de campos y dependencias en → [Tareas](/docs/rtg/proyectos/tareas) y → [Vistas](/docs/rtg/proyectos/vistas).
***
## Registrar el tiempo [#registrar-el-tiempo]
Proyectos controla el tiempo dedicado a cada tarea para planificar mejor y conocer el coste real del trabajo.
* Arrancas una actividad desde la tarea; Dinaup la relaciona con el proyecto y la tarea.
* El **cronómetro** sigue activo aunque cambies de aplicación (TPV, Pymes, RRHH…).
* Cada tarea muestra el tiempo total invertido sin abrirla; el cronómetro suma solo tus propias actividades.
***
## Colaborar dentro de la tarea [#colaborar-dentro-de-la-tarea]
Cada tarea tiene un hilo para comentar, mencionar compañeros y compartir archivos sin salir de Dinaup. Cada cambio queda registrado en su línea de tiempo.
→ [Comentarios, menciones y adjuntos](/docs/rtg/proyectos/colaboracion)
***
## Conectado con el resto de Dinaup [#conectado-con-el-resto-de-dinaup]
Las tareas se vinculan con lo que ya gestionas en otros módulos:
| Módulo | Cómo se conecta |
| --------- | ------------------------------------------------------------------------------------------------------------ |
| **Pymes** | Vincula tareas con presupuestos, pedidos y ventas; el trabajo registrado puede reflejarse en la facturación. |
| **CRM** | Las oportunidades pueden generar tareas asociadas, y el avance de las tareas acompaña al proceso comercial. |
| **RRHH** | Las tareas asignadas a una persona y el tiempo registrado quedan ligados a su actividad. |
| **TPV** | El cronómetro sigue activo mientras trabajas en el punto de venta, sin perder el seguimiento. |
***
## Preguntas frecuentes [#preguntas-frecuentes]
La clave es el prefijo que antecede al identificador de cada tarea (por ejemplo, MKT-042). Sirve para numerar y referenciar tareas de forma única, de modo que puedas citarlas en comentarios, emails o documentos y todo el equipo sepa de cuál hablas.
Sí. Puedes añadir colaboradores externos además de tus compañeros internos, y a cada miembro le asignas permisos de ver o editar el proyecto.
No. Desde la propia tarjeta asignas responsable, actualizas el porcentaje de progreso, fijas vencimiento y cambias la prioridad, sin entrar en la ficha completa.
No. El cronómetro permanece activo aunque navegues a TPV, Pymes o RRHH, y el tiempo queda vinculado al proyecto y a la tarea.
***
→ [Tareas](/docs/rtg/proyectos/tareas)
→ [Vistas](/docs/rtg/proyectos/vistas)
→ [Colaboración](/docs/rtg/proyectos/colaboracion)
→ [Flujos](/docs/rtg/proyectos/flujos)
→ [Análisis](/docs/rtg/proyectos/analisis)
# La app Tareas (/docs/rtg/proyectos/inicio)
La app **Tareas** abre en una pantalla de inicio cuando aún no has elegido proyecto. Desde ahí saltas a tu día, al análisis o al Drive, y en el menú lateral cambias entre proyectos.
***
## El menú lateral [#el-menú-lateral]
La columna izquierda es la misma en toda la app. De arriba abajo:
| Elemento | Qué hace |
| ---------------------- | ----------------------------------------------------------------------- |
| **Buscar** | Filtra la lista de proyectos por nombre mientras escribes. |
| **Mi día** | Abre tus tareas agrupadas por estado. Un contador marca cuántas tienes. |
| **Todo** | Abre el informe con todas las tareas, sin filtro de proyecto. |
| **Análisis** | Abre el panel de indicadores. Lleva la etiqueta **Preview**. |
| **Lista de proyectos** | Un proyecto por fila, con su icono y el número de tareas activas. |
| **Drive** | El almacén de documentos compartido de la app. |
| **Proyecto** | Crea un proyecto nuevo. |
| **Configuración** | Abre los catálogos de la app (solo administradores). |
***
## La pantalla de inicio [#la-pantalla-de-inicio]
Cuando entras sin proyecto seleccionado, ves la portada de Tareas con tres bloques.
**Accesos rápidos**: tres tarjetas que abren **Mi día**, **Análisis** y **Drive** sin pasar por el menú.
**Qué puedes hacer con Tareas**: un resumen de las capacidades de la app, las cuatro vistas del mismo trabajo, las dependencias, Mi día, el filtro rápido, el cronómetro por tarea y el análisis.
**Modo guía**: un botón que abre una ventana con las funcionalidades estrella de la app. Lo tienes arriba a la derecha y también en la tarjeta de bienvenida.
Para empezar a trabajar necesitas un proyecto. Crea uno desde el botón **Proyecto** del menú lateral; en cuanto lo tengas, la pantalla de inicio deja paso al [espacio de trabajo del proyecto](/docs/rtg/proyectos/espacio-de-trabajo).
***
## Dónde sigue cada cosa [#dónde-sigue-cada-cosa]
La pantalla de un proyecto: cabecera, filtros, las cuatro vistas y el alta rápida de tareas.
Las cinco pestañas del análisis: resumen, equipo, backlog, velocidad y bonos.
Los catálogos que alimentan la app: proyectos, tareas, actividades y bonos.
Qué es un proyecto y cómo se conecta con el resto de Dinaup.
# Panel de análisis (/docs/rtg/proyectos/panel-analisis)
El **panel de análisis** reúne los indicadores de todos tus proyectos en cinco pestañas. Lo abres desde **Análisis** en el menú lateral. Lleva la etiqueta **Preview**: está en desarrollo y puede cambiar.
Para el significado de cada indicador y cómo actuar sobre él, ver → [Análisis](/docs/rtg/proyectos/analisis). Aquí tienes qué muestra cada pestaña.
***
## El selector de fechas [#el-selector-de-fechas]
Arriba a la derecha eliges el **rango de fechas** del panel. Arranca en los últimos 30 días. El rango afecta a las pestañas de **Velocidad** y **Bonos y horas**; el pulso y las alertas de la pestaña Resumen son siempre una foto del momento actual, sin filtro de fechas.
***
## Resumen [#resumen]
Dos bloques que responden a "¿cómo vamos ahora mismo?".
* **Pulso del equipo**: tarjetas con las tareas abiertas, vencidas, las que vencen esta semana y hoy, las horas estimadas pendientes y las cerradas históricas.
* **Alertas de gestión**: la higiene del backlog, tareas sin responsable, sin fecha de vencimiento, sin esfuerzo estimado y sin proyecto asociado. Cuanto más bajos, mejor.
***
## Equipo [#equipo]
**Carga del equipo**: quién acumula más trabajo y dónde se concentra el retraso. Cuatro gráficas que agrupan las tareas por responsable y por supervisor: tareas abiertas por responsable, esfuerzo planificado por responsable, vencidas por responsable y tareas abiertas por supervisor.
***
## Backlog [#backlog]
Cómo se reparte el trabajo abierto, en dos bloques.
* **Salud del backlog**: tareas por estado, por prioridad, por tipo y por estado de flujo.
* **Focos de esfuerzo**: los proyectos con más tareas abiertas, con más horas estimadas y con más retraso, y las horas pendientes por tipo.
***
## Velocidad [#velocidad]
El ritmo del equipo dentro del rango de fechas: qué trabajo entra y sale del sistema.
* **Velocidad del equipo**: tareas creadas en el periodo, horas planificadas creadas y esfuerzo medio por tarea, con gráficas de entradas por responsable, por proyecto, por tipo y por prioridad.
* **Tiempo registrado**: los registros de actividad cronometrada del periodo, por empleado y por proyecto.
***
## Bonos y horas [#bonos-y-horas]
El cierre económico del periodo, apoyado en los bonos de horas.
* **Conclusiones del periodo**: tareas finalizadas en el rango, por responsable, proyecto, tipo y prioridad, con las horas planificadas completadas.
* **Informes de bonos**: el detalle monetario de esas conclusiones, en tres cortes: **por Bono**, **por Cliente** y **por Proyecto**. Los importes se computan cuando la tarea está finalizada.
* **Horas de actividad**: los registros cronometrados del periodo, por empleado y por proyecto.
Esta pestaña solo tiene datos si usas [bonos de horas](/docs/rtg/proyectos/bonos-de-horas) y registras el tiempo de tus tareas.
***
→ [Análisis](/docs/rtg/proyectos/analisis)
→ [Bonos de horas](/docs/rtg/proyectos/bonos-de-horas)
→ [Funciones avanzadas](/docs/rtg/proyectos/funciones-avanzadas)
# Tareas (/docs/rtg/proyectos/tareas)
Una **tarea** es la unidad mínima de trabajo dentro de un proyecto: algo concreto que alguien tiene que hacer, con un responsable, una fecha y un estado. Es la pieza que mueves por el tablero, que comentas con tu equipo y que Dinaup vigila para avisarte si se retrasa.
Cada tarea vive dentro de un [proyecto](/docs/rtg/proyectos) y sigue el [flujo de trabajo](/docs/rtg/proyectos/flujos) que le hayas asignado. Aquí tienes su anatomía completa: qué campos la describen, cómo se relaciona con otras tareas y qué datos calcula Dinaup por ti.
***
## Anatomía de una tarea [#anatomía-de-una-tarea]
Estos son los campos que describen una tarea. No todos son obligatorios: con un resumen y un proyecto ya tienes una tarea válida; el resto la enriquece y permite planificar y medir.
| Campo | Para qué sirve |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Resumen** | Título corto y claro. Lo que se lee en el tablero y en los listados. |
| **Instrucciones** | Descripción larga con editor enriquecido: negritas, listas, enlaces y capturas pegadas directamente. El sitio donde explicas el qué y el cómo. |
| **Clave** | Identificador único autogenerado a partir del prefijo del proyecto (por ejemplo, `MKT-042`). Sirve para referenciar la tarea en conversaciones, comentarios y documentos. |
| **Fecha de inicio planificada** | Cuándo debería empezar la tarea. Alimenta el calendario y la línea de tiempo. |
| **Vencimiento** | Fecha límite. Es la base del cálculo de tareas vencidas y en riesgo. |
| **Estado** | En qué punto del flujo está (Abierta, En curso, Bloqueada, Cerrada…). Define la columna del Kanban. |
| **Tipo** | Naturaleza de la tarea: Bug, Feature, Mejora, Investigación… según los tipos que tenga tu proyecto. |
| **Prioridad** | Qué urgencia tiene: Indefinido, Normal, Alta o Crítica. Se muestra como una etiqueta de color. |
| **Story points / estimación** | Esfuerzo previsto, en horas o en puntos. Sirve para planificar la carga y para detectar tareas en riesgo. |
| **Asignado** | El empleado responsable de sacarla adelante. Aparece en su lista de trabajo. |
| **Equipo** | Personas adicionales que colaboran en la tarea cuando no basta con un único responsable. |
La **clave** se genera sola en cuanto creas la tarea, usando el prefijo que definiste al [crear el proyecto](/docs/rtg/proyectos) (por ejemplo, `MKT-`). No la escribes tú: Dinaup la asigna y la mantiene única.
***
## Crear una tarea [#crear-una-tarea]
### Abre tu proyecto [#abre-tu-proyecto]
Ve a **Proyectos** y entra en el proyecto donde vive el trabajo. Todas las tareas pertenecen a un proyecto, que les da la clave, el equipo y el flujo de estados.
### Añade la tarea [#añade-la-tarea]
Crea una tarea nueva y ponle un **resumen** claro: una frase que cualquiera entienda. Con eso ya tienes una tarea válida; Dinaup le asigna su **clave**.
### Describe el trabajo [#describe-el-trabajo]
En **Instrucciones**, explica el qué y el cómo con el editor enriquecido. Pega capturas, añade listas o enlaza a otras tareas. Cuanto más claro esté aquí, menos preguntas recibirás luego.
### Clasifica y asigna [#clasifica-y-asigna]
Elige **tipo** y **prioridad**, marca el **estado** inicial y asigna un **responsable** (y un **equipo** si colaboran varios). Así la tarea aparece donde tiene que aparecer y la persona correcta sabe que es suya.
***
## Planificar una tarea [#planificar-una-tarea]
Planificar es ponerle fechas y esfuerzo para que Dinaup pueda avisarte cuando algo se tuerza.
* **Fechas planificadas**: pon una **fecha de inicio** y un **vencimiento**. Con ellas, la tarea se coloca en la línea de tiempo y entra en el cálculo de retrasos.
* **Estimación**: indica las **horas o story points** que crees que costará. Es la referencia contra la que Dinaup mide si la tarea va sobrada o apurada de tiempo.
Sin **vencimiento** ni **estimación**, una tarea no puede marcarse como vencida ni en riesgo: Dinaup no tiene contra qué compararla. Si quieres que el sistema vigile los plazos, rellena al menos la fecha de vencimiento.
→ [Vistas: Mi Día, Kanban, Gantt y Lista](/docs/rtg/proyectos/vistas)
***
## Dependencias [#dependencias]
Las tareas rara vez son islas: unas tienen que terminarse antes que otras. Las **dependencias** describen esas relaciones y son lo que permite a Dinaup calcular la ruta crítica del proyecto.
Desde una tarea puedes añadir tres tipos de relación:
| Relación | Qué significa |
| ------------------- | --------------------------------------------------------------------------------------- |
| **Bloquea a** | Esta tarea tiene que cerrarse **antes** de que la otra pueda avanzar. |
| **Bloqueada por** | Lo inverso: esta tarea **espera** a que otra se cierre. Es la otra cara de "bloquea a". |
| **Relacionada con** | Enlace puramente informativo: dos tareas conectadas, sin orden obligatorio entre ellas. |
### La ruta crítica [#la-ruta-crítica]
Cuando encadenas tareas con "bloquea a" y "bloqueada por", formas cadenas de trabajo que deben hacerse en orden. La **ruta crítica** es la cadena más larga de tareas dependientes: la secuencia que determina cuándo puede terminar el proyecto entero.
Su importancia es práctica: **si una tarea de la ruta crítica se retrasa, todo el proyecto se retrasa con ella**. Las tareas fuera de la ruta crítica tienen algo de holgura; las que están dentro, no. Por eso son las que conviene vigilar primero.
Dinaup calcula la ruta crítica a partir de las dependencias y las fechas planificadas, y la resalta en la [vista Gantt](/docs/rtg/proyectos/vistas) para que veas qué tareas mueven la aguja del calendario.
Para que la ruta crítica tenga sentido, las tareas encadenadas necesitan **fechas planificadas**. Las dependencias dicen el orden; las fechas dicen cuánto dura cada paso. Con ambas cosas, el Gantt puede dibujar la cadena completa.
***
## Campos calculados automáticos [#campos-calculados-automáticos]
Además de los campos que rellenas tú, Dinaup mantiene tres indicadores que se actualizan solos. No los editas: salen de comparar las fechas y la estimación con la realidad. Te sirven para detectar problemas sin revisar tarea por tarea.
| Indicador | Cómo se calcula | Para qué te sirve |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| **Vencida** | Se marca cuando la fecha de hoy ha pasado el **vencimiento** y la tarea **no está cerrada**. | Localizar lo que ya debería estar hecho y no lo está. |
| **En riesgo** | Salta cuando el tiempo **restante** hasta el vencimiento es menor que la **estimación** con un margen de seguridad. | Anticiparte: la tarea aún no está vencida, pero al ritmo actual no llegará a tiempo. |
| **Tiempo en estado actual** | Cuenta cuánto lleva la tarea **sin cambiar de estado**. | Detectar tareas atascadas, sobre todo las que llevan demasiado tiempo en "Bloqueada" o "En curso". |
Estos indicadores dependen de que la tarea tenga fechas y estimación. Una tarea sin **vencimiento** nunca aparecerá como vencida ni en riesgo, aunque lleve meses abierta. Planifica para que la vigilancia funcione.
### Fechas reales y progreso [#fechas-reales-y-progreso]
Además de las fechas que planificas, la tarea registra sola las fechas de lo que de verdad ocurrió, a partir de sus cambios de estado:
| Campo | Cuándo se rellena solo |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fecha de inicio confirmada** | Al pasar la tarea a un estado de tipo **En proceso** por primera vez. Si la devuelves al backlog o a pendiente, se borra: aún no había empezado de verdad. |
| **Fecha de fin confirmada** | Al llegar el progreso al **100 %**. Si el progreso baja, se borra. |
| **Progreso al 100 %** | Al mover la tarea a un estado de tipo **Completado** o **Cancelado**, el progreso se fija solo. |
Las fechas planificadas cuentan tu intención; las confirmadas, la realidad. La diferencia entre ambas es la desviación del plan, sin que nadie apunte fechas a mano.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La asigna Dinaup al crear la tarea, combinando el prefijo del proyecto (por ejemplo, MKT-) con un número correlativo. No la escribes tú y siempre es única dentro del proyecto.
Son las dos caras de la misma relación. Si la tarea A "bloquea a" la tarea B, entonces B está "bloqueada por" A: B no puede avanzar hasta que A se cierre. Defines la relación desde cualquiera de las dos y Dinaup mantiene el reflejo en la otra.
Porque le falta la fecha de vencimiento, o porque ya está cerrada. El indicador de vencida solo se activa cuando hoy ha superado la fecha límite y la tarea sigue abierta. Sin fecha límite, no hay nada que comparar.
Sí. La ruta crítica se recalcula a partir de las dependencias y las fechas planificadas. Al encadenar o soltar tareas, la cadena más larga puede cambiar, y con ella las tareas que el Gantt resalta como críticas.
***
→ [Proyectos](/docs/rtg/proyectos)
→ [Flujos de trabajo](/docs/rtg/proyectos/flujos)
→ [Vistas: Mi Día, Kanban, Gantt y Lista](/docs/rtg/proyectos/vistas)
→ [Colaboración en tareas](/docs/rtg/proyectos/colaboracion)
# Vistas (/docs/rtg/proyectos/vistas)
Una **vista** es una forma de mirar las mismas tareas. No cambias los datos: cambias cómo se ordenan y se muestran según lo que necesites en cada momento. Empiezas la jornada en una vista, planificas en otra y revisas el avance en una tercera, todo sobre el mismo proyecto.
Dinaup te da cinco vistas. Cambias entre ellas sin perder filtros ni selección.
***
## Qué vista usar [#qué-vista-usar]
Elige según lo que necesites hacer en ese momento:
| Vista | Para qué sirve |
| ----------------- | ----------------------------------------------------------------------- |
| **Mi Día** | Empezar la jornada: ver qué toca hoy y marcarlo hecho. |
| **Kanban** | Ver el flujo de trabajo y mover tareas de un estado a otro arrastrando. |
| **Gantt** | Planificar en el tiempo: fechas, dependencias y ruta crítica. |
| **Lista / Tabla** | Editar muchos campos y hacer cambios masivos. |
| **Compacta** | Una lista mínima para el móvil o un panel externo. |
La vista no afecta a los datos. Una tarea que cierras en Mi Día aparece cerrada en Kanban, en Gantt y en la Lista. Es la misma tarea vista de otra manera.
***
## Mi Día [#mi-día]
Tu punto de arranque cada mañana. **Se arma sola** a partir de la fecha de vencimiento y el estado de cada tarea: no organizas nada a mano, Dinaup reparte tus tareas en grupos.
* **Hoy**: lo que vence hoy.
* **Próximas**: lo que vence más adelante.
* **Bloqueadas**: tareas que esperan a que otra se cierre.
* **Completadas**: lo que ya has terminado.
Marcas una tarea como completada sin abrirla. Es la vista para decidir por dónde empiezas y no perder de vista lo urgente.
***
## Kanban [#kanban]
Un tablero con **una columna por estado**. Cada tarea es una tarjeta que se mueve entre columnas conforme avanza el trabajo. Las columnas son los estados del [flujo](/docs/rtg/proyectos/flujos) del proyecto, así que el tablero refleja tu propio proceso.
Cada tarjeta muestra:
* La **clave** de la tarea (su identificador).
* El **resumen** (título corto).
* Los **avatares** de las personas asignadas.
* La **prioridad**, con color.
* Un **icono de comentarios** si la tarea tiene conversación.
Para cambiar el estado de una tarea, **arrástrala** de una columna a otra. El cambio se guarda solo.
El tablero respeta los permisos. Si tu rol no te deja cerrar tareas, el sistema no te permitirá soltar una tarjeta en la columna de cierre.
Es la vista que mejor responde a "¿cómo va el proyecto?": ves qué hay en cada fase y dónde se acumula el trabajo.
***
## Gantt [#gantt]
Una **línea temporal**: cada tarea es una barra colocada según sus fechas planificadas (inicio y vencimiento). Sirve para planificar y ver cómo encajan las tareas en el calendario.
En la Gantt ves:
* **Barras** de color según el estado de cada tarea.
* **Flechas** entre tareas que representan sus **dependencias** (qué bloquea a qué).
* La **ruta crítica** resaltada: la cadena de tareas que, si se retrasan, retrasan todo el proyecto.
* **Zoom** por días, semanas o meses, para mirar de cerca o tener una visión general.
La ruta crítica se calcula a partir de las dependencias que defines en cada tarea. Por eso esta vista solo brilla cuando las tareas tienen fechas y dependencias bien puestas.
Para que la Gantt tenga sentido, asigna a tus tareas fecha de inicio planificada y vencimiento, y define las dependencias entre ellas. Sin fechas no hay barras; sin dependencias no hay ruta crítica.
***
## Lista / Tabla [#lista--tabla]
Una **tabla editable** con todas tus tareas en filas y sus campos en columnas. Puedes **ordenar**, **filtrar** y **editar en línea** sin abrir cada tarea.
Es la vista para trabajar en bloque: cambiar el responsable de varias tareas, ajustar fechas en serie o revisar muchos campos a la vez. Cuando necesitas precisión y velocidad sobre muchos registros, esta es tu vista.
***
## Compacta [#compacta]
Una **lista plana mínima**: solo título, clave y proyecto por tarea. Sin tarjetas, sin columnas, sin adornos.
Está pensada para espacios estrechos: la pantalla del móvil o un panel externo donde solo quieres leer qué hay, sin gestionar. Es la versión más ligera de todas.
***
## La misma tarea, distintas vistas [#la-misma-tarea-distintas-vistas]
Conviene entender que las cinco vistas leen los **mismos campos** de la tarea, solo que cada una destaca los que le importan:
* **Mi Día** mira la **fecha de vencimiento** y el **estado** para agruparte el día.
* **Kanban** mira el **estado** para colocarte la tarjeta en su columna.
* **Gantt** mira las **fechas planificadas** y las **dependencias** para dibujar la línea temporal.
* **Lista** lo enseña **todo** y te deja editarlo.
* **Compacta** se queda con lo mínimo para identificar la tarea.
Por eso el trabajo previo (poner fechas, estados, prioridades y dependencias a tus [tareas](/docs/rtg/proyectos/tareas)) es lo que hace que cada vista sea útil. Cuanto mejor descritas estén, más te dan las vistas.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Una vista solo cambia cómo se ordenan y se muestran las tareas. Los datos son los mismos: lo que haces en una vista (cerrar una tarea, cambiar su estado) se ve en todas las demás.
La Gantt dibuja barras a partir de las fechas planificadas y la ruta crítica a partir de las dependencias. Si tus tareas no tienen fechas, no hay barras; si no tienen dependencias entre ellas, no hay ruta crítica que resaltar.
El tablero respeta los permisos de tu rol. Si no tienes permiso para llevar una tarea a ese estado (por ejemplo, cerrarla), el sistema no te dejará soltar la tarjeta ahí.
Mi Día se arma sola combinando la fecha de vencimiento y el estado de cada tarea. En "Hoy" entra lo que vence hoy; lo que vence más adelante va a "Próximas", lo que espera a otra tarea va a "Bloqueadas" y lo terminado a "Completadas".
***
→ [Tareas](/docs/rtg/proyectos/tareas)
→ [Flujos](/docs/rtg/proyectos/flujos)
# ¿Qué significa tener un Partner asociado? (/docs/cuenta/partners/que-significa-tener-un-partner)
Dinaup trabaja con una [red de Partners](/docs/cuenta/partners/partners) que ayudan a los clientes a configurar, personalizar y aprovechar la plataforma. Si ves el mensaje:
> **Tu cuenta está gestionada por el Partner: \[Nombre del Partner]**
Significa que esta empresa o profesional creó o activó tu licencia de Dinaup. Actualmente colabora contigo en la gestión de la herramienta y el soporte técnico.
***
### ¿Qué hace un Partner? [#qué-hace-un-partner]
Los Partners pueden:
* Ayudarte a poner en marcha Dinaup.
* Configurar y personalizar el sistema según tus necesidades.
* Ofrecerte soporte técnico o consultoría especializada.
* Actuar como tu punto de contacto habitual con Dinaup, si así lo prefieres.
***
### ¿Por qué tengo uno? [#por-qué-tengo-uno]
Puede que tu empresa haya contratado directamente a un Partner, o que alguien del equipo haya activado la cuenta a través de uno.
> Importante: aunque tengas un Partner asociado, **tú sigues siendo el propietario de tus datos**.
***
### ¿Puedo cambiar o quitar el Partner? [#puedo-cambiar-o-quitar-el-partner]
Si prefieres gestionar la cuenta directamente o trabajar con otro Partner, puedes solicitarlo.
[Iniciar una disputa o solicitar el cambio de Partner](/docs/cuenta/partners/que-significa-tener-un-partner/iniciar-una-disputa-con-un-partner)
***
### Contactar con Dinaup [#contactar-con-dinaup]
Puedes escribirnos desde el soporte de Dinaup o enviar un correo a [partners@dinaup.com](mailto:partners@dinaup.com).
# Iniciar una disputa con un Partner (/docs/cuenta/partners/que-significa-tener-un-partner/iniciar-una-disputa-con-un-partner)
Si tienes una licencia gestionada por un Partner y quieres **revisar, aclarar o finalizar** esa relación, puedes solicitarlo a Dinaup.
### ¿Cuándo iniciar una disputa? [#cuándo-iniciar-una-disputa]
Puedes escribirnos si:
* No puedes acceder a tu cuenta o datos.
* Sientes que el Partner está actuando de forma contraria a tus intereses.
* Quieres cambiar de Partner o gestionar directamente tu cuenta.
* Tienes dudas sobre quién es el titular de los datos o de la cuenta.
### ¿Cómo iniciar una disputa? [#cómo-iniciar-una-disputa]
Envíanos un correo a **[partners@dinaup.com](mailto:partners@dinaup.com)**
Incluye la siguiente información para poder ayudarte con agilidad:
***
#### Plantilla recomendada [#plantilla-recomendada]
> **Asunto:** Solicitud de revisión de cuenta gestionada por Partner
>
> **Hola Dinaup,**\
> Soy \[Tu nombre completo] de la empresa \[Nombre de tu empresa], con teléfono \[Número de Teléfono]. Actualmente usamos Dinaup a través del Partner \[Nombre del Partner, si lo conoces].
>
> Me gustaría revisar la relación con este Partner por los siguientes motivos:
>
> * \[Especifica brevemente el motivo o situación: falta de acceso, desacuerdo, dudas sobre titularidad, etc.]
>
> Datos que pueden ayudar a identificar la cuenta:
>
> * Nombre o CIF de la empresa
>
> * Email vinculado a la cuenta
>
> * Cualquier otro dato que pueda servir de referencia
***
### ¿Qué hará Dinaup? [#qué-hará-dinaup]
* Verificaremos tu identidad y la titularidad de los datos.
* Nos pondremos en contacto contigo y, si es necesario, también con el Partner.
* Si todo está claro, te ayudaremos a recuperar el control de tu cuenta o datos.
# Listado de Partners (/docs/cuenta/partners/partners)
Estas empresas te ayudan a implantar Dinaup, resolver incidencias y adaptar la plataforma a tu negocio.
***
## Partners Gold [#partners-gold]
**Digital Dexe es partner oficial de Dinaup.**\
Con más de **10 años colaborando con Dinaup**, **Digital Dexe** aporta experiencia en la implantación y acompañamiento de soluciones adaptadas a cada empresa.
***
## Partners [#partners]
[info@digitaldexe.com](mailto:info@digitaldexe.com)
Empresa especializada en soluciones informáticas, desarrollo web y marketing digital. Más de 15 años de experiencia en estrategias para empresas de diversos sectores: gestión de redes sociales, SEO y SEM.
Empresa europea de servicios de cloud computing y alojamiento web.
Consultoría administrativa y financiera especializada en estrategia y operaciones. Trabaja para mejorar la productividad y la rentabilidad de sus clientes.
# Blazor Server Guidelines (/docs/desarrollo/dotnet/c-code-style-guidelines/blazor-server-guidelines)
## Application Startup Convention [#application-startup-convention]
### Prerequisites [#prerequisites]
```xml
```
***
### 1. Startup Banner [#1-startup-banner]
Identifies if a startup failure is caused by Docker or the application itself.
```csharp
Console.WriteLine("══════════════════════════════════════════════════════════════");
Console.WriteLine(" [APP_NAME] - Starting application");
Console.WriteLine($" Date/Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine("══════════════════════════════════════════════════════════════");
```
***
### 2. Network Connectivity Check [#2-network-connectivity-check]
Prevents firewall or network issues from causing errors in other services that are harder to diagnose.
```csharp
while (await Dinaup.Extensions.CheckNetworkConnectivityAsync() == false)
{
Console.WriteLine("[ERROR] No internet connection. Retrying in 1 second...");
await Task.Delay(1000);
}
```
***
### 3. Debug Port [#3-debug-port]
Prevents port conflicts with other apps during development. In production, ports are configured via environment variables.
```csharp
const int DEBUG_PORT = 6114;
// Only applies when debugging
if (Debugger.IsAttached)
builder.WebHost.UseUrls("http://*:" + DEBUG_PORT.ToString());
```
***
### 4. Version Endpoint [#4-version-endpoint]
```csharp
app.MapGet("/Version", () => Results.Ok(new
{
version = Assembly.GetExecutingAssembly().GetName().Version.ToString()
}));
```
***
### 5. Fatal Error Handling [#5-fatal-error-handling]
```csharp
retryinitialization:
try
{
var builder = WebApplication.CreateBuilder(args);
if (Debugger.IsAttached)
builder.WebHost.UseUrls("http://*:" + DEBUG_PORT.ToString());
// ... initialization ...
app.Run();
}
catch (Exception ex)
{
Console.WriteLine("══════════════════════════════════════════════════════════════");
Console.WriteLine(" [ERROR] Fatal error during initialization");
Console.WriteLine($" Message: {ex.Message}");
Console.WriteLine($" Type: {ex.GetType().Name}");
Console.WriteLine($" Date/Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine("══════════════════════════════════════════════════════════════");
Console.WriteLine(ex.ToString());
try { Dinaup.Logs.Write_Flag("INI", ex); } catch { }
var builderRecovery = WebApplication.CreateBuilder(args);
if (Debugger.IsAttached)
builderRecovery.WebHost.UseUrls("http://*:" + DEBUG_PORT.ToString());
var appRecovery = builderRecovery.Build();
appRecovery.UseMiddleware();
Console.WriteLine("[LOG] Recovery mode. Retrying in 10 seconds...");
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await appRecovery.RunAsync(cts.Token);
goto retryinitialization;
}
finally
{
Dinaup.Logs.CloseAndFlush();
}
```
# C# con Dinaup (/docs/desarrollo/dotnet/c-code-style-guidelines/c-with-dinaup-guidlines)
## Usa el sufijo ReportData [#usa-el-sufijo-reportdata]
Nombra las variables que contienen un informe MyDinaup con el sufijo `ReportData`. Así distingues la consulta de la lista de filas que extraes de ella.
```csharp
var motivosHorasExtrasReportData = new APIMotivosDeHorasExtrasC();
await motivosHorasExtrasReportData.ExecuteQueryAsync(...);
dto.MotivosHorasExtra = motivosHorasExtrasReportData.RowsDic;
```
# C# Code Style Guidelines (/docs/desarrollo/dotnet/c-code-style-guidelines)
## Project Configuration [#project-configuration]
```xml
net10.0disableenable
```
## Culture-Invariant by Design [#culture-invariant-by-design]
Dinaup projects completely ignore the current system culture. This is intentional and prevents an entire class of data conversion errors.
All threads and processes are set to `en-US` culture to ensure consistent, predictable behavior across all environments. Decimal separators, date formats, and number parsing work identically whether running on a Spanish, German, or American system.
This eliminates bugs caused by culture-dependent conversions and makes data exchange reliable.
\
**DateTime is always UTC.** No local times, no timezone conversions, no ambiguity. All dates and times are stored, processed, and transmitted in UTC. This eliminates timezone-related bugs and makes temporal data unambiguous across different geographical locations.
## Preferred Practices [#preferred-practices]
### Don't Use Nullable Types [#dont-use-nullable-types]
Avoid nullable types (e.g., `DateTime?`, `decimal?`) unless absolutely necessary. Use default values to represent "empty" states, which provides consistency and eliminates null-checking overhead.
**Default values:**
* Empty DateTime → `DateTime.MinValue`
* Empty decimal → `0`
* Empty Guid → `Guid.Empty`
This approach is semantic: "Maximum 0" clearly means no maximum limit.
***
### Don't Return Anonymous Objects [#dont-return-anonymous-objects]
Never return anonymous objects with `new { ... }` in controllers or services. Anonymous objects are untyped, inconsistent, and break API contracts.
```csharp
// Different types returned in different branches
if (ok)
return Ok(new { version = "2", revision = "2" });
else
return Ok(new { version = 2, revision = "2" }); // int vs string
```
```csharp
public class AppInfoDTO
{
public string Version { get; set; } = "";
public string Revision { get; set; } = "";
public string Status { get; set; } = "";
}
return Ok(new AppInfoDTO
{
Version = "2",
Revision = "2",
Status = "OK"
});
```
***
### Don't Use ! (Negation Operator) [#dont-use--negation-operator]
The negation operator reduces clarity, especially in long or nested conditions. Direct checks or explicit comparisons are clearer and more expressive.
```csharp
// Correct
if (user.Enabled == false)
return;
// Incorrect
if (!user.Enabled)
return;
```
***
### Collections - Use Extension Methods [#collections---use-extension-methods]
Prefer semantic extension methods over verbose null-conditional operators.
```csharp
// Correct
if (_items.IsNotEmpty())
ProcessItems();
// Incorrect
if (_items?.Count > 0)
ProcessItems();
```
***
### Guid Comparison [#guid-comparison]
Use semantic extension methods instead of direct comparison with `Guid.Empty`.
```csharp
// Correct
if (f.NextRowId.IsEmpty())
return;
if (prevId.IsNotEmpty())
Process(prevId);
// Incorrect
if (f.NextRowId == Guid.Empty)
return;
if (prevId != Guid.Empty)
Process(prevId);
```
***
### Use Decimal for Numeric Types [#use-decimal-for-numeric-types]
Always use `decimal` for financial and logical operations. Float and double introduce binary rounding errors that cause precision issues.
```csharp
// Correct
decimal price = 19.99m;
decimal total = price * quantity;
// Incorrect
float price = 19.99f;
double total = price * quantity;
```
***
### Extension Methods Reference [#extension-methods-reference]
#### Type Conversion [#type-conversion]
* **`.STR()`** - String conversion with better defaults than `.ToString()`
```csharp
// Decimal - always US format (dot as decimal separator)
12.5m.STR() // "12.5"
1234.56m.STR() // "1234.56"
// Guid - empty guid returns empty string
Guid.Empty.STR() // ""
Guid.NewGuid().STR() // "a1b2c3d4-e5f6-..."
// DateTime - ISO format
DateTime.Now.STR() // "2024-01-15 14:30:00"
DateOnly.Today.STR() // "2024-01-15"
// Boolean - numeric representation
true.STR() // "1"
false.STR() // "0"
```
* **`.INT([default])`** - Integer conversion
```csharp
"123".INT() // 123
"abc".INT() // Exception
"abc".INT(99) // 99
```
* **`.DEC([default])`** - Decimal conversion
```csharp
"12.5".DEC() // 12.5
"abc".DEC() // Exception
"abc".DEC(9.9m) // 9.9
```
* **`.BOOL()`** - Boolean conversion
```csharp
"1".BOOL() // true
"si".BOOL() // true
"sí".BOOL() // true
"on".BOOL() // true
"yes".BOOL() // true
"true".BOOL() // true
"0".BOOL() // false
"false".BOOL() // false
// Any other value → false
```
***
### Validation [#validation]
* **`.IsNotNull()`** - Checks if reference is not null
* **`.IsNull()`** - Checks if reference is null
* **`.IsEmpty()`** - Checks if value is empty:
* `Guid.Empty`
* `""` (empty string)
* `DateTime.MinValue`
* `0` for numeric types
* Collections with zero elements
* **`.IsNotEmpty()`** - Opposite of `.IsEmpty()`. For collections: returns true if at least one element exists.
These methods include built-in null checks and syntax highlighting.
#### String Comparison [#string-comparison]
* **`.EqualsIgnoreCase()`** - Case-insensitive string comparison
* **`.LikeM()`** - LIKE-style wildcard pattern matching (case-sensitive)
* **`.LikeMIgnoreCase()`** - LIKE-style wildcard pattern matching (case-insensitive)
#### Dictionary Operations [#dictionary-operations]
* **`.GetM(key [, defaultValue])`** - Safe dictionary getter that never throws:
```csharp
MyDictionary.GetM("key") // null if not found
MyDictionary.GetM("key", "default") // "default" if not found
```
Use `.GetM()` whenever it reduces lines of code.
## Blazor [#blazor]
### Component Properties [#component-properties]
Only use quotes for string literals. Use `@` for expressions to ensure type safety.
```csharp
// Correct
// Incorrect
```
# Patrones de uso (/docs/desarrollo/dotnet/dinazen/patrones)
Recetas que copias y adaptas, no referencia de props. Cada una resuelve un problema real de montar una app Blazor sobre el [SDK .NET](/docs/desarrollo/dotnet/sdk): traer datos con el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente) y pintarlos con DinaZen sin reinventar la UI.
El reparto es siempre el mismo: el **cliente** trae el dato, **DinaZen** lo pinta. Si una receta te pide un `DinaupClientC`, viene de [crear y conectar el cliente](/docs/desarrollo/dotnet/sdk/cliente).
***
## De un informe a una tabla [#de-un-informe-a-una-tabla]
Tienes un [informe de Dinaup Flex](/docs/desarrollo/flex/informes) (su GUID) y quieres pintar sus filas en una tabla con paginación, búsqueda, filtros y exportación a CSV. Sin escribir ni una columna a mano. `DnzReportView` ejecuta el informe contra la API con tu cliente y genera el `DataGrid` a partir de la definición del informe.
### Crea y conecta el cliente [#crea-y-conecta-el-cliente]
```razor
@code {
private DinaupClientC _client;
protected override async Task OnInitializedAsync()
{
_client = new DinaupClientC(endpoint, apiKey, secretKey, "*");
await _client.InitializeAsync(3000);
}
}
```
### Pinta el informe inline [#pinta-el-informe-inline]
Pásale el cliente y el GUID del informe. Las columnas, los tipos y los formatos los deduce solo de la definición del informe.
```razor
@if (_client.IsNotNull())
{
}
```
### Reacciona al clic en una fila [#reacciona-al-clic-en-una-fila]
Por defecto, al pulsar una fila el componente abre la ficha del registro. Si quieres tu propio comportamiento, captura `OnItemSelect`.
```razor
@code {
private async Task AbrirDetalleAsync(DinaupDynamicRowDTO row)
{
// row.ID y row.SectionId vienen rellenos
await HacerAlgoCon(row.ID);
}
}
```
No necesitas leer las filas tú mismo: `DnzReportView` llama a `Client.Report_GetAsync` por dentro, gestiona la carga, los errores y la paginación del lado servidor. Tú solo pones cliente y GUID.
¿Lo quieres en un diálogo o en una ventana flotante en lugar de inline? El componente expone dos helpers estáticos.
```razor
@inject DialogService DialogService
@code {
private async Task AbrirInformeAsync()
{
await DnzReportView.OpenAsync(DialogService, _client, "guid-del-informe", title: "Ventas del mes");
}
}
```
```razor
@inject DnzWindowManagerService WindowManager
@code {
private void AbrirInformeEnVentana()
{
DnzReportView.OpenAsWindow(WindowManager, _client, "guid-del-informe", title: "Ventas");
}
}
```
**Firmas de los helpers estáticos:**
```csharp
Task DnzReportView.OpenAsync(DialogService ds, DinaupClientC client, string reportId, Dictionary vars = null, string title = "Informe", string width = "90%", string height = "80%")
string DnzReportView.OpenAsWindow(DnzWindowManagerService wm, DinaupClientC client, string reportId, Dictionary vars = null, string title = "Informe", string icon = "analytics")
```
### DnzReportView [#dnzreportview]
Ejecuta un informe de Flex y lo pinta como tabla con búsqueda, filtros, paginación servidor y exportación a CSV.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | ------------------------------------ | ----------- | ----------------------------------------------------------------------------- |
| `Client` | `DinaupClientC` | — | **Obligatorio.** Cliente del SDK ya inicializado. |
| `ReportId` | `string` | `""` | **Obligatorio.** GUID del informe a ejecutar. |
| `VariablesValues` | `Dictionary` | `null` | Valores para las variables del informe. |
| `QuerySearch` | `string` | `""` | Búsqueda textual inicial. |
| `AdvancedFilter` | `List` | `null` | Filtros avanzados aplicados de entrada. |
| `Limit` | `int` | `50` | Filas por página. |
| `Orden` | `Dictionary` | `null` | Orden inicial (clave = columna, valor = ascendente). |
| `ShowTitle` | `bool` | `true` | Muestra la cabecera con título e icono de la sección. |
| `Title` | `string` | `""` | Sobrescribe el título; si está vacío, usa el del informe. |
| `ShowSearch` | `bool` | `true` | Muestra la caja de búsqueda. |
| `Filtrable` | `bool` | `true` | Permite filtrar las columnas. |
| `ShowAdd` | `bool` | `true` | Muestra el botón de añadir registro. |
| `AdminMode` | `bool` | `false` | Ejecuta el informe en modo administrador. |
| `ToolBarTemplate` | `RenderFragment` | `null` | Contenido extra en la barra de herramientas. |
| `OnItemSelect` | `EventCallback` | — | Se dispara al seleccionar una fila (sustituye al comportamiento por defecto). |
| `OnDataChanged` | `EventCallback` | — | Se dispara cuando los datos se recargan. |
### DnzReportProvider [#dnzreportprovider]
Variante "headless": ejecuta el informe y expone las filas como **CascadingValue**, pero **no** pinta ninguna tabla. Úsalo cuando quieras los datos del informe pero con tu propio render (tarjetas, KPIs, una vista a medida). El `ChildContent` recibe el contexto con las filas ya cargadas.
```razor
@* Aquí pintas las filas a tu manera, leyéndolas del CascadingValue *@
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | ---------------------------- | ----------- | ----------------------------------------------------- |
| `Client` | `DinaupClientC` | — | **Obligatorio.** Cliente del SDK ya inicializado. |
| `ReportId` | `string` | `""` | **Obligatorio.** GUID del informe a ejecutar. |
| `VariablesValues` | `Dictionary` | `null` | Valores para las variables del informe. |
| `QuerySearch` | `string` | `""` | Búsqueda textual inicial. |
| `AdvancedFilter` | `List` | `null` | Filtros avanzados aplicados de entrada. |
| `Limite` | `int` | `500` | Máximo de filas a traer. |
| `Orden` | `Dictionary` | `null` | Orden inicial (clave = columna, valor = ascendente). |
| `AdminMode` | `bool` | `false` | Ejecuta el informe en modo administrador. |
| `ChildContent` | `RenderFragment` | `null` | Tu render, que lee las filas del contexto en cascada. |
| `OnDataLoaded` | `EventCallback` | — | Se dispara cuando las filas terminan de cargar. |
***
## Mostrar datos tipados [#mostrar-datos-tipados]
Tienes una fila con un importe, una fecha, unos minutos... y quieres pintarlos con el formato correcto (moneda local, fecha amigable, color según el signo) **sin formatear a mano**. La familia de **Spans** lo hace: cada uno sabe formatear su tipo según la región del cliente.
```razor
```
**El truco de `AutoColor`.** En `DnzSpanMoney`, `AutoColor=true` pinta el importe en verde si es positivo y en rojo si es negativo. Si solo quieres una de las dos reglas, usa `AutoColorGreen` o `AutoColorRed` por separado.
### DnzSpanMoney [#dnzspanmoney]
Pinta un importe con el formato de moneda de la región del cliente. Opcionalmente con etiqueta, icono y color por signo.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ---------------- | ---------- | ----------- | ------------------------------------------------- |
| `Amount` | `decimal?` | `0` | Importe a mostrar. Si es nulo, no pinta nada. |
| `Label` | `string` | `""` | Etiqueta encima del importe. |
| `Icon` | `string` | `""` | Icono Material a la izquierda (requiere `Label`). |
| `AutoColor` | `bool` | `false` | Verde si positivo, rojo si negativo. |
| `AutoColorGreen` | `bool` | `false` | Solo verde cuando es positivo. |
| `AutoColorRed` | `bool` | `false` | Solo rojo cuando es negativo. |
| `IsVisible` | `bool` | `true` | Oculta el componente si es `false`. |
| `CssClass` | `string` | `""` | Clases CSS extra en el `span` del importe. |
| `FontSize` | `string` | `"16px"` | Tamaño de fuente del importe. |
### DnzSpanDate [#dnzspandate]
Pinta una fecha con el formato amigable de la región, con tooltip de la fecha exacta y un badge de estado opcional ("Hoy", "Mañana", "Ayer", "Pasado", "Futuro").
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------- | ----------- | ------------ | ----------------------------------------------------- |
| `Value` | `DateOnly?` | `null` | Fecha a mostrar. Si es nula, no pinta nada. |
| `FriendlyMode` | `bool` | `true` | Usa el formato amigable de la región. |
| `ShowBadge` | `bool` | `false` | Pinta la fecha dentro de un badge. |
| `ShowStatus` | `bool` | `false` | Añade un badge de color con el estado relativo a hoy. |
| `Class` | `string` | `""` | Clases CSS extra en el contenedor. |
| `FontSize` | `string` | `"0.875rem"` | Tamaño de fuente. |
Hay un Span por cada tipo de dato: `DnzSpanDateTime`, `DnzSpanDecimal`, `DnzSpanInteger`, `DnzSpanPercent`, `DnzSpanMinutes`, `DnzSpanGrams`, `DnzSpanBytes`, `DnzSpanGigaBytes`, `DnzSpanKV`. Todos siguen el mismo patrón: les pasas el valor crudo y ellos formatean.
***
## Elegir el selector correcto [#elegir-el-selector-correcto]
Necesitas un desplegable para que el usuario elija un valor. DinaZen tiene tres, y cada uno resuelve un caso distinto. La regla de los tres segundos:
* **¿Es un `enum`?** → `DnzEnumDropDown`. Saca las opciones del propio tipo.
* **¿La lista ya está en memoria?** (la cargaste antes, son pocas) → `DnzDataGridDropDown`. Desplegable con búsqueda y columnas.
* **¿Hay que buscar/crear una ficha remota?** (clientes, productos, miles de registros) → `DnzRowSelector`. Busca contra un informe en el servidor mientras escribes.
El binding es `@bind-Value` sobre tu enum. Las opciones salen solas del tipo.
```razor
@code {
private EstadoPedidoE _estado;
}
```
El binding es `@bind-Value` sobre un objeto que implemente `IDinaupRow`. Le pasas la lista por `Data` y le dices qué propiedad mostrar con `TextProperty`.
```razor
@code {
private ClienteRow _cliente;
private List _clientes = new();
}
```
El binding es `@bind-SelectedRow`. Le pasas el cliente y el GUID del informe contra el que busca; el desplegable consulta el servidor según escribes.
```razor
@code {
private IDinaupRow _clienteSel;
}
```
### DnzEnumDropDown [#dnzenumdropdown]
Desplegable cuyas opciones salen de un `enum`. La etiqueta de cada opción se toma del atributo `[Display(Name = ...)]` si existe; si no, del nombre del valor.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ------------- | -------- | --------------- | -------------------------------------- |
| `Value` | `TEnum` | — | Valor seleccionado. Usa `@bind-Value`. |
| `Name` | `string` | `""` | Nombre del campo (para formularios). |
| `Style` | `string` | `"width:200px"` | Estilo CSS del desplegable. |
| `Placeholder` | `string` | `""` | Texto cuando no hay selección. |
| `Disabled` | `bool` | `false` | Desactiva el control. |
Acepta además atributos extra que se pasan tal cual al elemento raíz.
### DnzDataGridDropDown [#dnzdatagriddropdown]
Desplegable con búsqueda y columnas para una lista que ya tienes en memoria. El tipo `T` debe implementar `IDinaupRow`.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| --------------- | ------------------------- | ----------- | ------------------------------------------------- |
| `Value` | `T` | — | Elemento seleccionado. Usa `@bind-Value`. |
| `Data` | `IEnumerable` | lista vacía | Origen de datos en memoria. |
| `TextProperty` | `string` | `null` | **Requerido.** Propiedad a mostrar como texto. |
| `ColorProperty` | `string` | `null` | Propiedad que da color de badge a cada opción. |
| `IconoProperty` | `string` | `null` | Propiedad que aporta el icono de cada opción. |
| `Label` | `string` | `null` | Etiqueta del campo. |
| `Icon` | `string` | `null` | Icono a la izquierda del campo. |
| `Width` | `string` | `"280px"` | Ancho del control. |
| `Style` | `string` | `null` | Estilo CSS extra. |
| `Visible` | `bool` | `true` | Muestra u oculta el control. |
| `IsRequired` | `bool` | `false` | Marca el campo como obligatorio. |
| `Disabled` | `bool` | `false` | Desactiva el control. |
| `OpenInWindow` | `bool` | `true` | El botón de abrir lanza la ficha en una ventana. |
| `Client` | `DinaupClientC` | `null` | Cliente, necesario para abrir la ficha del valor. |
| `Columns` | `RenderFragment` | `null` | Columnas personalizadas del desplegable. |
| `ValueTemplate` | `RenderFragment` | `null` | Plantilla del valor seleccionado. |
| `IconTemplate` | `RenderFragment` | `null` | Plantilla del icono por elemento. |
| `ColumnWidth` | `string` | `""` | Ancho de las columnas. |
| `OnAdd` | `EventCallback` | — | Clic en el botón de añadir. |
| `OnRemove` | `EventCallback` | — | Clic en limpiar la selección. |
| `OnOpen` | `EventCallback` | — | Clic en abrir la ficha del valor. |
Acepta además atributos extra que se pasan tal cual al elemento raíz.
### DnzRowSelector [#dnzrowselector]
Selector que busca contra un informe remoto mientras escribes. Para fichas que viven en el servidor (clientes, productos) y son demasiadas para tener en memoria.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ------------------ | --------------------------- | ------------ | ------------------------------------------------- |
| `Client` | `DinaupClientC` | — | **Obligatorio.** Cliente del SDK ya inicializado. |
| `ReportId` | `string` | `null` | GUID del informe contra el que busca. |
| `SelectedRow` | `IDinaupRow` | `null` | Fila seleccionada. Usa `@bind-SelectedRow`. |
| `Label` | `string` | `null` | Etiqueta del campo. |
| `Icon` | `string` | `null` | Icono a la izquierda. |
| `Placeholder` | `string` | `null` | Texto cuando no hay selección. |
| `Width` | `string` | `"280px"` | Ancho del control. |
| `Style` | `string` | `"flex:1"` | Estilo CSS extra. |
| `Class` | `string` | `""` | Clases CSS extra. |
| `IsRequired` | `bool` | `false` | Marca el campo como obligatorio. |
| `Disabled` | `bool` | `false` | Desactiva el control. |
| `AdminMode` | `bool` | `false` | Busca en modo administrador. |
| `AdvancedFilter` | `List` | `null` | Filtros aplicados a la búsqueda. |
| `OpenInWindow` | `bool` | `true` | El botón de abrir lanza la ficha en una ventana. |
| `DefaultID` | `Guid` | `Guid.Empty` | Preselecciona una fila por su ID al cargar. |
| `KeyboardShortcut` | `string` | `null` | Atajo de teclado para abrir el selector. |
| `OnAdd` | `EventCallback` | — | Clic en el botón de añadir. |
| `OnOpenRecord` | `EventCallback` | — | Clic en abrir la ficha de la fila. |
Acepta además atributos extra que se pasan tal cual al elemento raíz.
***
## Esqueleto de diálogo [#esqueleto-de-diálogo]
Quieres un diálogo con la estructura y los botones de Play: título arriba, contenido en medio, botones al pie con la convención de la casa (cancelar discreto a la izquierda, confirmar destacado a la derecha). `DnzDialogLayout` te da los tres huecos.
```razor
@inject DialogService DialogService
@code {
private string _nombre = "";
private bool _guardando;
private void CancelarAsync() => DialogService.Close();
private async Task GuardarAsync()
{
_guardando = true;
await PersistirAsync();
DialogService.Close(true);
}
}
```
**La convención del pie:** Cancelar en `Danger` + `Text` (discreto), Aceptar en `Success` sólido. Marca el botón de confirmar con `IsBusy=@_guardando` mientras procesa: el botón muestra el spinner y bloquea el doble clic.
### DnzDialogLayout [#dnzdialoglayout]
Estructura de diálogo con cabecera, cuerpo desplazable y pie. Si omites `TitleContent`, genera la cabecera con `Title` + `Icon` + botón de cerrar; si omites `FooterContent`, muestra un botón "Cerrar" por defecto.
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| --------------- | ---------------- | ----------- | -------------------------------------------------- |
| `Title` | `string` | `null` | Título de la cabecera (si no usas `TitleContent`). |
| `Icon` | `string` | `null` | Icono Material de la cabecera. |
| `TitleContent` | `RenderFragment` | `null` | Cabecera personalizada completa. |
| `BodyContent` | `RenderFragment` | `null` | Contenido del cuerpo (desplazable). |
| `FooterContent` | `RenderFragment` | `null` | Pie personalizado (botones de acción). |
| `ContentStyle` | `string` | `null` | Estilo CSS del cuerpo. |
| `HeaderStyle` | `string` | `null` | Estilo CSS de la cabecera. |
| `Flat` | `bool` | `false` | Diálogo plano sin degradados ni fondo gris. |
### DnzConfirmDialog [#dnzconfirmdialog]
Para una acción destructiva (eliminar, vaciar), no montes un diálogo entero: abre la confirmación con el helper estático `OpenAsync`, que devuelve `true` si el usuario confirma.
```razor
@code {
private async Task EliminarAsync()
{
var ok = await DnzConfirmDialog.OpenAsync(DialogService, "Esta acción no se puede deshacer. ¿Eliminar el pedido?", title: "Eliminar pedido", severity: DnzConfirmSeverity.Danger, okText: "Eliminar");
if (ok == false) return;
await BorrarPedidoAsync();
}
}
```
**Firma del helper estático:**
```csharp
Task DnzConfirmDialog.OpenAsync(DialogService dialogService, string message, string title = "Confirmar", DnzConfirmSeverity severity = DnzConfirmSeverity.Warning, string okText = "Confirmar", string cancelText = "Cancelar")
```
El `severity` (`Info`, `Warning`, `Danger`, `Success`) cambia el icono, el color de acento y el estilo del botón de confirmar. Para algo irreversible, usa `DnzConfirmSeverity.Danger`.
***
## Estados de carga [#estados-de-carga]
Mostrar que algo está pasando es parte de la UX. DinaZen tiene tres piezas y cada una resuelve un momento distinto:
* **`DnzLoader`**: estoy ejecutando una acción (guardar, calcular, llamar a la API). Spinner.
* **`DnzSkeleton`**: la interfaz aún no está lista; muestro su silueta gris en su lugar.
* **`DnzDeferredContent`**: quiero renderizar contenido pesado un poco más tarde, mostrando un esqueleto mientras tanto.
```razor
@if (_procesando)
{
}
```
```razor
@if (_cargando)
{
}
```
```razor
```
### DnzLoader [#dnzloader]
Spinner de "estoy procesando". Centrado por defecto; horizontal si lo necesitas en línea.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ------------ | ------ | ----------- | ----------------------------------------- |
| `Horizontal` | `bool` | `false` | Variante horizontal en lugar de centrada. |
### DnzSkeleton [#dnzskeleton]
Silueta gris animada que ocupa el sitio del contenido mientras carga.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ---------- | -------- | ----------- | ----------------------------------------- |
| `Lines` | `int` | `1` | Número de líneas (rectángulos) a mostrar. |
| `Height` | `string` | `"1rem"` | Altura de cada línea. |
| `Radius` | `string` | `"0.25rem"` | Radio de las esquinas. |
| `MaxWidth` | `string` | `"100%"` | Ancho máximo del bloque. |
### DnzDeferredContent [#dnzdeferredcontent]
Retrasa el render del contenido pesado un instante y muestra un esqueleto mientras tanto. Útil para que las subpáginas pesadas no bloqueen la primera pintura.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ---------------- | ---------------- | ----------- | ----------------------------------------------------------------- |
| `DelayMs` | `int` | `500` | Milisegundos antes de mostrar el contenido. |
| `ChildContent` | `RenderFragment` | — | Contenido que se renderiza tras el retardo. |
| `LoadingContent` | `RenderFragment` | `null` | Contenido de carga personalizado (por defecto, un `DnzSkeleton`). |
| `Class` | `string` | `""` | Clases CSS del contenedor de carga. |
***
## Relacionado [#relacionado]
* [DinaZen](/docs/desarrollo/dotnet/dinazen): introducción, instalación y convenciones de la librería.
* [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente): crear el `DinaupClientC` que alimenta estas recetas.
* [SDK .NET](/docs/desarrollo/dotnet/sdk): conexión, lectura y escritura de datos.
* [Informes de Dinaup Flex](/docs/desarrollo/flex/informes): de dónde sale el GUID que pasas a `DnzReportView`.
# Almacenamiento S3 (/docs/desarrollo/dotnet/sdk/almacenamiento-s3)
El módulo S3 del paquete `Dinaup` habla con cualquier almacén compatible con S3 (AWS S3, MinIO) sobre el cliente de Minio. Ofrece dos clientes: uno para un bucket (`DinaS3ClientC`) y otro que replica y repara sobre varios (`DinaS3MultiClientC`).
```csharp
using Dinaup;
```
## Un bucket: DinaS3ClientC [#un-bucket-dinas3clientc]
### Conectar [#conectar]
```csharp
var s3 = new DinaS3ClientC(
_s3Token: "ACCESS_KEY",
_s3Secret: "SECRET_KEY",
_s3EndPoint: "s3.tu-dominio.com",
_Bucket: "mi-bucket",
_BaseDir: "app/"); // prefijo opcional dentro del bucket
// También por cadena de conexión o diccionario de parámetros:
var s3b = new DinaS3ClientC("s3://ACCESS:SECRET@s3.tu-dominio.com/mi-bucket");
```
### Operar con objetos [#operar-con-objetos]
Las rutas son relativas al bucket (y al `_BaseDir` si lo fijaste).
```csharp
// Subir bytes
await s3.BytesUploadAsync("informes/2026-07.json", contenidoBytes);
// Descargar bytes
byte[] datos = await s3.BytesReadAsync("informes/2026-07.json");
// Comprobar si existe
bool hay = await s3.FileExistAsync("informes/2026-07.json");
// Subir y descargar archivos de disco
await s3.FileUploadAsync("informes/2026-07.pdf", @"C:\temp\informe.pdf");
await s3.FileDownloadAsync("informes/2026-07.pdf", @"C:\temp\bajado.pdf");
// Sube solo si el contenido difiere del que ya hay
await s3.FileUploadIfIsDifferentAsync("logo.png", @"C:\assets\logo.png");
// Listar
var items = await s3.FileList("informes/", recursive: true);
// Borrar
await s3.FileRemoveAsync("informes/2026-07.json");
```
### URLs firmadas [#urls-firmadas]
Genera URLs temporales de lectura o de subida sin exponer las claves.
```csharp
// Lectura: expira en 600 s por defecto
string urlLectura = s3.SignGet("informes/2026-07.pdf", expirationSeconds: 600);
// Escritura directa desde el navegador
string urlSubida = s3.SignPut("subidas/nuevo.pdf", expirationSeconds: 600);
```
### Salud [#salud]
```csharp
bool ok = await s3.HealthCheckAsync();
```
`DinaS3ClientC` también implementa `IHealthCheck` de `Microsoft.Extensions.Diagnostics.HealthChecks`, así que se registra directamente en el health-check de ASP.NET Core.
## Varios buckets: DinaS3MultiClientC [#varios-buckets-dinas3multiclientc]
Envuelve una lista de `DinaS3ClientC` y opera sobre todos: escribe en todos, lee del primero que responde y, si detecta que a un bucket le falta un objeto, lo repara desde otro.
```csharp
var multi = new DinaS3MultiClientC(
new List { s3Primario, s3Secundario },
_autoRepair: true);
// Escribe en todos los buckets
var res = await multi.WriteBytesAsync("informes/2026-07.json", datos);
// Lee del primero disponible
byte[] leido = await multi.ReadBytesAsync("informes/2026-07.json");
// Objetos serializados en JSON
await multi.WriteObjectAsync("config/app.json", miConfig);
var config = await multi.ReadObjectAsync("config/app.json");
// Existencia, listado, archivos y borrado, igual que el cliente simple
bool hay = await multi.ExistsAsync("informes/2026-07.json");
var items = await multi.ListAsync("informes/", recursive: true);
```
### Reparación y deriva [#reparación-y-deriva]
```csharp
// Reparar un objeto concreto: lo copia a los buckets que no lo tengan
await multi.RepairAsync("informes/2026-07.json");
// Salud global
bool ok = await multi.HealthCheckAsync();
// Detectar deriva entre buckets sobre una muestra
var drift = await multi.CheckDriftAsync("informes/", sampleCount: 50);
if (drift.HasDrift)
Console.WriteLine($"{drift.Drifted.Count} objetos difieren entre buckets");
```
`CheckDriftAsync` devuelve un `DriftReport` con `TotalChecked`, `InSync`, `Drifted` (rutas que difieren) y `Missing` (por bucket, qué falta). Igual que el cliente simple, `DinaS3MultiClientC` implementa `IHealthCheck`.
La replicación no es transaccional: `WriteBytesAsync` intenta escribir en todos los buckets y te informa del resultado por bucket. La reparación automática cierra los huecos cuando una lectura detecta que a un bucket le falta el objeto.
# Apps multi-tenant (/docs/desarrollo/dotnet/sdk/apps-multi-tenant)
Una app multi-tenant es una sola aplicación tuya que da servicio a muchas empresas, cada una con sus usuarios y sus datos. Tú escribes la interfaz y la lógica de tu producto; Dinaup pone el login, el aislamiento entre empresas y la base de datos. No montas backend.
## Las tres piezas [#las-tres-piezas]
| Pieza | Qué es | Ciclo de vida |
| --------------------------- | ----------------------------------------------------------------------------- | ----------------------- |
| `DinaupExternalAppSettings` | La identidad de tu aplicación: `AppId` + `AppToken`. | Singleton |
| `DinaupAuthClient` | Autentica usuarios por email y contraseña. Devuelve a qué empresa pertenecen. | Singleton |
| `MyAppClient` | El cliente de datos de un usuario concreto, atado a su empresa. | Uno por sesión (Scoped) |
`MyAppClient` hereda de `DinaupClientC`: informes, escritura, archivos y anotaciones funcionan igual que en el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente). La diferencia es a qué datos llega: cada instancia opera solo sobre la empresa del usuario autenticado.
## Montar la app [#montar-la-app]
### Carga la identidad de la app [#carga-la-identidad-de-la-app]
Las credenciales viven en el [Vault](/docs/desarrollo/dotnet/sdk/vault) con dos parámetros obligatorios: `DINAUP_APPID` (un GUID) y `DINAUP_APPTOKEN`.
```csharp
var vault = new Dinaup.Vault.VaultData(vaultUrl, vaultPassword);
vault.Initialize();
var appConfig = new Dinaup.Models.DinaupExternalAppSettings(vault);
```
Si prefieres pasarlas directas: `new DinaupExternalAppSettings(appId, appToken)`.
### Registra los servicios [#registra-los-servicios]
```csharp
// Compartidos por todos los usuarios
builder.Services.AddSingleton(appConfig);
builder.Services.AddSingleton(new Dinaup.Auth.DinaupAuthClient());
builder.Services.AddSingleton();
// Uno por usuario/circuito
builder.Services.AddScoped();
builder.Services.AddHealthChecks().AddCheck("MyAppKVClient");
```
El `MyAppClient` y cualquier servicio que lo use van en `Scoped`. Un singleton compartiría la sesión de una empresa con los usuarios de otra.
### Autentica al usuario [#autentica-al-usuario]
`LoginAsync` valida las credenciales contra Dinaup y devuelve un `AuthResponse` con el `TenantConnectionKeyword`: la clave que identifica la empresa del usuario. Con ella construyes su `MyAppClient`.
```csharp
var authResponse = await _authClient.LoginAsync(email, password);
if (authResponse == null) throw new Exception("Credenciales inválidas");
DinaupClient = new Dinaup.MyAppClient(_appSettings, authResponse);
```
Para que la sesión sobreviva a recargas, el navegador guarda solo una cookie `HttpOnly` con un id de sesión. El estado (keyword y email) se guarda en el [almacén clave-valor](#almacenamiento-clave-valor-de-la-app) bajo ese id, y al volver se recupera y se reconstruye el cliente:
```csharp
// Al hacer login: estado al KV, solo el id a la cookie
var sessionId = Guid.NewGuid().ToString();
await _kvClient.SetKVAsync($"session:{sessionId}",
$"{authResponse.TenantConnectionKeyword}|{authResponse.UserEmail}");
httpContext.Response.Cookies.Append("dinaup_sessionid", sessionId, cookieOptions);
// Al volver (InitializeAsync): recuperar el estado y reconstruir
var sessionId = httpContext.Request.Cookies["dinaup_sessionid"];
if (!string.IsNullOrEmpty(sessionId))
{
var estado = await _kvClient.GetKVAsync($"session:{sessionId}");
if (!string.IsNullOrEmpty(estado))
{
var partes = estado.Split('|');
DinaupClient = new Dinaup.MyAppClient(_appSettings, partes[0], partes[1]);
}
}
```
Con el estado de sesión fuera del proceso, la app es stateless: puedes desplegar el mismo contenedor en varios nodos detrás de un balanceador y la cookie vale en cualquiera. Un nodo caído no cierra la sesión de nadie.
### Opera con los datos de su empresa [#opera-con-los-datos-de-su-empresa]
El cliente ya está atado al tenant. Un servicio de dominio típico recibe el contexto de sesión y usa su cliente:
```csharp
public class PaisesService
{
private readonly SessionUserContext _session;
public PaisesService(SessionUserContext session) => _session = session;
public async Task> GetAllAsync()
{
var rpt = new APIPaisesC();
await rpt.ExecuteQueryAsync(_session.DinaupClient, 1, 1000);
return rpt.Rows;
}
}
```
Informes, `WriteOperation`, archivos y anotaciones: todo lo del [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente) aplica sin cambios.
## Cuentas de usuario [#cuentas-de-usuario]
`MyAppClient` hereda las operaciones de cuenta de `DinaupClientC`. Tu app puede dar de alta usuarios, activarlos y gestionar contraseñas sin pantallas de Dinaup. Todas reciben el `userAgent` y la IP del usuario final.
| Método | Qué hace |
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `Session_RegisterAccountAsync(model, userAgent, ip)` | Crea la cuenta temporal y genera el código de activación. |
| `Session_ConfirmAccountRegistrationAsync(model, userAgent, ip)` | Activa la cuenta con el código recibido. Segundo paso del registro. |
| `Session_SignInAsync(email, password, userAgent, ip)` | Inicia sesión y devuelve el estado (correcta, 2FA pendiente, rechazada). |
| `Session_CheckTwoFactor(sessionId, code, userAgent, ip)` | Verifica el código 2FA de una sesión pendiente. |
| `Session_CreatePasswordRecoveryCodeAsync(model, userAgent, ip)` | Genera un código de recuperación de contraseña. |
| `Session_ChangePasswordWithCodeAsync(code, newPassword, userAgent, ip)` | Cambia la contraseña con el código de recuperación. |
| `Session_ChangePasswordAsync(sessionId, newPassword, confirm, userAgent, ip)` | Cambia la contraseña de una sesión activa. |
Los modelos de entrada (`AccountCreationModel`, `AccountActivationModel`, `PasswordRecoveryModel`) validan sus campos antes de llamar al servidor.
## Almacenamiento clave-valor de la app [#almacenamiento-clave-valor-de-la-app]
`MyAppKVClient` guarda pares clave-valor propios de tu aplicación: configuración, flags y las sesiones de tus usuarios (el patrón del paso 3). Es el estado compartido entre nodos que hace la app stateless.
```csharp
await _kvClient.SetKVAsync("clave", "valor"); // devuelve bool
var valor = await _kvClient.GetKVAsync("clave");
```
* El valor es texto plano, hasta 10 MB por clave.
* El espacio de claves es único por aplicación, no por empresa. Si un valor pertenece a un tenant o a una sesión, prefíjalo: `session:{id}`, `config:{empresa}`.
* `GetKVAsync` devuelve cadena vacía si la clave no existe.
Registrado como health check (`AddCheck`), el endpoint `/HealthCheck` verifica la conectividad con Dinaup en cada sonda.
## Ejecutar como un usuario concreto [#ejecutar-como-un-usuario-concreto]
En procesos donde no hay sesión interactiva (importaciones, tareas programadas), envuelve la operación con `DinaupContext.WithUser` para atribuirla a un usuario: afecta al autor del alta, al histórico y a las anotaciones.
```csharp
using (DinaupContext.WithUser(userId, ip, userAgent)) // ip y userAgent opcionales
{
await client.RunWriteOperationAsync(sectionId, op, false);
}
```
Para el detalle de informes, filtros y escritura, ver el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
# ASP.NET Core (/docs/desarrollo/dotnet/sdk/aspnet)
El módulo `dinaup.aspnet` del paquete `Dinaup` aporta middleware y extensiones para integrar la plataforma en una aplicación ASP.NET Core: propagación de correlación entre servicios, endpoints de estado y un gate de mantenimiento cuando la conexión con Dinaup no está disponible.
```csharp
using Dinaup;
```
## Correlación de logs entre servicios [#correlación-de-logs-entre-servicios]
`CorrelationIdMiddleware` propaga un identificador de correlación por petición. Lee el header `X-Correlation-Id`; si no viene, genera uno. Lo empuja al `LogContext` de Serilog como propiedad `correlation_id` (así todos los logs de esa petición lo llevan) y lo devuelve en el header de respuesta para que el cliente o el siguiente servicio lo reutilicen.
```csharp
app.UseCorrelationId();
```
Constantes públicas: `CorrelationIdMiddleware.HeaderName` (`X-Correlation-Id`) y `CorrelationIdMiddleware.PropertyName` (`correlation_id`). El id generado es un hex de 16 caracteres.
Combínalo con [Dinaup.Logs](/docs/desarrollo/dotnet/sdk/dinaup.logs): con la correlación en el `LogContext`, cada línea de log de la petición se puede rastrear de punta a punta entre servicios.
## Endpoints de entorno y versión [#endpoints-de-entorno-y-versión]
`MapDinaupEnv` registra dos endpoints GET de solo lectura para monitorización y despliegue:
```csharp
app.MapDinaupEnv();
```
| Ruta | Respuesta |
| -------------- | ----------------------------------------------- |
| `GET /Version` | `{ "version": "10.15.0.8" }` |
| `GET /Env` | `{ "app", "version", "env", "host", "loglvl" }` |
`/Env` devuelve el nombre de la app, la versión, el entorno (`dev`/`staging`/`prod`), el hostname y el nivel de log activo. Útil para comprobar de un servicio en marcha qué versión y en qué entorno corre.
## Gate de mantenimiento [#gate-de-mantenimiento]
`DinaupWebMiddleware` corta el tráfico cuando el cliente Dinaup no está conectado. Si no hay conexión (o no hay sesión por defecto), responde `503 Service Unavailable` con una página de mantenimiento que se recarga sola. Si hay conexión, refresca la sesión web y continúa la tubería.
```csharp
app.UseMiddleware();
```
Regístralo después de tener el cliente Dinaup en el contenedor de servicios: el middleware recibe el `DinaupClientC` y la sesión web por inyección al invocarse.
## Otras piezas [#otras-piezas]
* **`SingleExecutionControllerAttribute`**: atributo para acciones de controlador que impide su ejecución concurrente. Devuelve `429 Too Many Requests` si la acción ya está en curso o si no ha pasado el intervalo mínimo (`new SingleExecutionControllerAttribute(minIntervalSeconds)`).
* **`TurnstileValidator`**: validación de Cloudflare Turnstile para proteger formularios públicos.
* **Helpers de `HttpRequest`/`HttpContext`**: `ReadGet`, `ReadPost`, `ReadGetOrPost`, `GetUserIP`, `GetUserAgent`, `GetHost`, `GetUserCountry` para leer parámetros y datos de la petición detrás de proxies y Cloudflare.
# Dinaup.Database (/docs/desarrollo/dotnet/sdk/dinaup.database)
`Dinaup.Database` es el módulo de acceso a PostgreSQL incluido dentro del paquete `Dinaup`. Ofrece una interfaz directa para trabajar con la base de datos sin lidiar con `DataReader` ni boilerplate de ADO.NET. Cubre:
* Conexión a PostgreSQL con SSL y cadenas en formato estándar.
* Lecturas tipadas (listas, diccionarios, modelos).
* Inserción, actualización y **upsert** (insertar o actualizar según exista el registro).
* Lectura por lotes de grandes volúmenes de datos.
* Mapeo automático a clases de negocio mediante interfaces simples.
* Acceso multihilo seguro y reutilización de conexión.
### Instalación [#instalación]
`Dinaup.Database` forma parte del paquete principal de Dinaup: al instalar `Dinaup` ya tienes `PGClient` y todas las utilidades de base de datos.
```bash
dotnet add package Dinaup
```
```csharp
using Dinaup.Database;
```
En versiones anteriores `Dinaup.Database` era un NuGet aparte (`dotnet add package Dinaup.Database`). Si actualizas un proyecto antiguo, basta con eliminar esa referencia: el namespace y la API son los mismos.
### Clase principal: PGClient [#clase-principal-pgclient]
La clase `PGClient` proporciona métodos para:
* Conexión y reconexión a PostgreSQL (con SSL si se requiere).
* Ejecución de sentencias SQL.
* Lectura de resultados (listas, diccionarios, modelos).
* Inserción, actualización, y operaciones de upsert.
* Lectura de datos en lotes.
#### Propiedades principales [#propiedades-principales]
* `IsConnected` (bool): indica si la conexión está abierta.
* `Host`, `Port`, `DatabaseName`, `CurrentSchema`: metadatos de la conexión, fijados en `Connect`.
* `Description` (string): nombre de aplicación reportado a PostgreSQL (alias de `Options.ApplicationName`).
* `Options` (`PGClientOptions`): opciones con las que se creó el cliente. Inmutables tras el constructor.
`PGClient` es seguro entre hilos una vez conectado: varios hilos pueden llamar a cualquier método `Read`/`Execute` a la vez. Las conexiones se multiplexan por el pool de Npgsql.
#### Establecer conexión [#establecer-conexión]
Conexión con parámetros separados:
```csharp
var client = new PGClient();
client.Connect("localhost", 5432, "myuser", "mypassword", "mydatabase");
if (client.IsConnected)
{
Console.WriteLine("Conexión establecida correctamente.");
}
```
Con cadena de conexión (formato `key=value` o URI `postgresql://`):
```csharp
client.Connect("postgresql://user:password@host:5432/dbname?sslmode=require");
```
De forma asíncrona:
```csharp
await client.ConnectAsync("localhost", 5432, "user", "password", "mydb");
// o, creando y conectando en un paso:
var ready = await PGClient.CreateAsync("localhost", 5432, "user", "password", "mydb");
```
SSL está activo por defecto (`PGClientOptions.UseSsl = true`), así que `Connect(host, port, …)` ya negocia TLS. Con cadena de conexión, controla el modo con `sslmode` (`require`, `verify-full`, `disable`).
#### Opciones de conexión: PGClientOptions [#opciones-de-conexión-pgclientoptions]
Pasa un `PGClientOptions` al constructor para ajustar pool, timeouts y reintentos. Todas las propiedades tienen valor por defecto:
| Propiedad | Defecto | Qué controla |
| ----------------------- | ------- | ------------------------------------------ |
| `MaxPoolSize` | 10 | Conexiones máximas del pool. |
| `MinPoolSize` | 1 | Conexiones mínimas del pool. |
| `CommandTimeoutSeconds` | 30 | Tiempo máximo por comando. |
| `ConnectTimeoutSeconds` | 15 | Tiempo máximo para abrir la conexión. |
| `MaxRetries` | 3 | Reintentos ante fallo transitorio. |
| `RetryBaseDelayMs` | 500 | Espera base entre reintentos. |
| `RetryMaxDelayMs` | 8000 | Espera máxima entre reintentos. |
| `ApplicationName` | `""` | Nombre visible en `pg_stat_activity`. |
| `Schema` | `""` | Esquema por defecto (`search_path`). |
| `UseSsl` | `true` | Negocia TLS en la conexión por parámetros. |
```csharp
var options = new PGClientOptions
{
ApplicationName = "importador-nocturno",
ConnectTimeoutSeconds = 30,
MaxPoolSize = 20
};
var client = new PGClient(options);
client.Connect("localhost", 5432, "user", "password", "mydb");
```
#### Lectura de datos [#lectura-de-datos]
* `ReadValue(string SQL)`: retorna un único valor (cadena).
* `ReadList(string SQL)`: retorna una lista de cadenas (asumiendo una sola columna).
* `ReadKVDictionary(string SQL)`: retorna un `Dictionary` a partir de dos columnas (clave, valor).
* `ReadDictionaryList(string SQL)`: retorna una secuencia de diccionarios (una fila por diccionario).
* `ReadObjectList(string SQL)` (donde T: BaseModelConverter): retorna una secuencia de objetos T mapeados desde la BD.
Cada método de lectura tiene su variante asíncrona con sufijo `Async` (`ReadValueAsync`, `ReadListAsync`, `ReadDictionaryListAsync`, `ReadObjectListAsync`, …).
Ejemplos:
```csharp
// Leer un valor único
var countStr = client.ReadValue("SELECT COUNT(*) FROM test_table;");
int totalRegistros = int.Parse(countStr);
// Leer una lista (una columna)
var nombres = client.ReadList("SELECT name FROM test_table ORDER BY id;");
foreach (var nombre in nombres)
{
Console.WriteLine(nombre);
}
// Leer una lista de diccionarios
var registros = client.ReadDictionaryList("SELECT id, name, value FROM test_table WHERE id < 10;");
foreach (var reg in registros)
{
Console.WriteLine($"ID: {reg["id"]}, Name: {reg["name"]}, Value: {reg["value"]}");
}
```
#### Lectura de modelos [#lectura-de-modelos]
Si se dispone de clases que heredan de `BaseModelConverter`, puede mapearse directamente:
```csharp
public class TestModel : BaseModelConverter
{
public int Id { get; set; }
public string Name { get; set; }
public int Value { get; set; }
public override void FromDic(Dictionary dic)
{
this.Id = dic.GetM("id").INT(0);
this.Name = dic.GetM("name");
this.Value = dic.GetM("value").INT(0);
}
public override string Table => "test_table";
public override string[] Fields => new[] { "id", "name", "value" };
public override string LastModifiedFieldDatetimeUTC => ""; // No usado en este ejemplo
}
// Ejemplo de uso
var modelos = client.ReadObjectList("SELECT * FROM test_table ORDER BY id;");
foreach (var m in modelos)
{
Console.WriteLine($"{m.Id} - {m.Name} - {m.Value}");
}
```
#### Inserción, actualización y upsert [#inserción-actualización-y-upsert]
* `InsertRecord(tableName, record)`: Inserta un diccionario como registro.
* `InsertRecords(tableName, records)`: Inserta múltiples registros a la vez.
* `UpdateRecord(tableName, dataDict, idField, idValue)`: Actualiza el registro cuyo campo `idField` coincide con `idValue`.
* `InsertOrIgnoreRecord(tableName, dataDict)`: Inserta el registro si no hay conflicto.
* `InsertOrUpdateRecord(tableName, dataDict, idField)`: Inserta o actualiza según exista el registro.
* `InsertOrUpdateRecords(tableName, dataDicts, idField)`: Inserta o actualiza múltiples registros.
Ejemplo: Insertar un registro
```csharp
var nuevoRegistro = new Dictionary
{
{"name", "NuevoNombre"},
{"value", "123"}
};
int rowsAffected = client.InsertRecord("test_table", nuevoRegistro);
Console.WriteLine("Filas insertadas: " + rowsAffected);
```
Ejemplo: Actualizar un registro
```csharp
var datosActualizar = new Dictionary
{
{"value", "999"}
};
int filasActualizadas = client.UpdateRecord("test_table", datosActualizar, "id", "1");
Console.WriteLine("Filas actualizadas: " + filasActualizadas);
```
Ejemplo: Upsert (insertar o actualizar)
```csharp
var registroUpsert = new Dictionary
{
{"id", "100"},
{"name", "Registro100"},
{"value", "1000"}
};
int affected = client.InsertOrUpdateRecord("test_table", registroUpsert, "id");
Console.WriteLine("Filas modificadas: " + affected);
```
#### Lectura en lotes (batch reading) [#lectura-en-lotes-batch-reading]
Para grandes cantidades de datos:
* `BatchReadDictionaries(description, countSQL, dataSQL, batchSize)`: Iterador que produce lotes de diccionarios.
* `BatchReadObjects(description, countSQL, dataSQL, batchSize)`: Igual que el anterior pero para objetos de tipo T.
Ejemplo:
```csharp
var batches = client.BatchReadDictionaries(
"Lectura en lotes",
"SELECT COUNT(*) FROM test_table",
"SELECT id, name, value FROM test_table ORDER BY id",
1000
);
foreach (var batch in batches)
{
Console.WriteLine("Lote de " + batch.Count + " registros");
foreach (var reg in batch)
{
Console.WriteLine($"{reg["id"]} - {reg["name"]} - {reg["value"]}");
}
}
```
#### Clonar conexiones [#clonar-conexiones]
`DuplicateConnection()` crea una nueva instancia `PGClient` con la misma configuración y abre la conexión.
```csharp
var repoClonado = client.DuplicateConnection();
if (repoClonado.IsConnected)
{
Console.WriteLine("Conexión clonada y funcionando.");
}
```
#### Manejo de errores [#manejo-de-errores]
Se pueden capturar excepciones con `try...catch`.
```csharp
try
{
client.ExecuteNonQuery("INSERT INTO test_table (name, value) VALUES ('Test', 1)");
}
catch (Exception ex)
{
Console.WriteLine("Error en la inserción: " + ex.Message);
}
```
#### Liberación de recursos [#liberación-de-recursos]
`PGClient` implementa `IDisposable`, por lo que es recomendable usar `using`:
```csharp
using (var client = new PGClient())
{
client.Connect("localhost", 5432, "user", "pass", "db");
// ... Operaciones ...
}
// Aquí se libera la conexión automáticamente
```
### Ejemplos completos [#ejemplos-completos]
#### Ejemplo 1: leer todos los registros (c#) [#ejemplo-1-leer-todos-los-registros-c]
```csharp
var client = new PGClient();
client.Connect("localhost", 5432, "user", "password", "mydb");
var listaNombres = client.ReadList("SELECT name FROM test_table ORDER BY id;");
foreach (var nombre in listaNombres)
{
Console.WriteLine(nombre);
}
```
#### Ejemplo 2: insertar y luego leer modelos (c#) [#ejemplo-2-insertar-y-luego-leer-modelos-c]
```csharp
var client = new PGClient();
client.ConnectWithSSL("postgres://user:pass@host:port/mydb?sslmode=require");
// Insertar un registro
var nuevo = new Dictionary
{
{"name", "NuevoRegistro"},
{"value", "100"}
};
client.InsertRecord("test_table", nuevo);
// Leer como objetos
var objetos = client.ReadObjectList("SELECT * FROM test_table WHERE name='NuevoRegistro'");
foreach (var obj in objetos)
{
Console.WriteLine($"{obj.Id}: {obj.Name} - {obj.Value}");
}
```
#### Ejemplo 3: actualizar o ignorar si existe (c#) [#ejemplo-3-actualizar-o-ignorar-si-existe-c]
```csharp
var client = new PGClient();
client.Connect("localhost", 5432, "user", "password", "mydb");
var registro = new Dictionary
{
{"id", "1"},
{"name", "Test1"},
{"value", "999"}
};
// InsertOrUpdate
int afectadas = client.InsertOrUpdateRecord("test_table", registro, "id");
Console.WriteLine("Filas afectadas: " + afectadas);
```
# Dinaup.Logs (/docs/desarrollo/dotnet/sdk/dinaup.logs)
Dinaup.Logs es el módulo de observabilidad de la librería Dinaup. Está construido sobre **Serilog** y unifica logs, contexto y medición de tiempos en tus aplicaciones .NET. Incluye:
* Logs estructurados con contexto (Component, Action).
* Correlación distribuida (CorrelationId) para rastrear un flujo entre servicios.
* Medición de duración de operaciones (`BeginMeasure`) con umbral configurable.
* Envío opcional y centralizado a **Grafana Loki** y, si lo activas, notificaciones push por **ntfy**.
* Helpers para envolver código con medición de tiempo, manejo de errores y logs coherentes.
## Requisitos [#requisitos]
### Dinaup .NET [#dinaup-net]
Antes de empezar, instala el paquete Dinaup.
[https://www.nuget.org/packages/Dinaup](https://www.nuget.org/packages/Dinaup)
### Grafana Loki (opcional) [#grafana-loki-opcional]
Por defecto los logs se escriben a archivo y consola, sin infraestructura adicional. Para **centralizar y consultar** tus logs recomendamos enviarlos a [Grafana Loki](https://grafana.com/oss/loki/) (autoalojado o Grafana Cloud).
* Solo necesitas el endpoint de *push* de Loki y, si tu instancia lo requiere, usuario y contraseña (basic auth).
* La activación es opcional: si no pasas `LokiConfig`, el log sigue funcionando en local.
## Inicio [#inicio]
`Logs` es una clase estática: no se instancia ni necesita una sesión ni el cliente de la API. Llama a `Initialize` una vez al arrancar la aplicación.
```csharp
using Dinaup;
using Serilog.Events;
// Inicialización mínima: escribe a logs\log.txt y consola.
// El nombre y la versión de la app se detectan del ensamblado de entrada.
Logs.Initialize();
Logs.SetLoggingLevel(LogEventLevel.Information);
```
```csharp
using Dinaup;
using Serilog.Events;
// (Opcional) Promueve propiedades extra a labels de Loki.
// IMPORTANTE: configúralas ANTES de Initialize.
Logs.propertiesAsLabels.Add("Environment");
var loki = new Logs.LokiConfig
{
Endpoint = "https://loki.tu-dominio.com/loki/api/v1/push",
Username = "usuario", // opcional (basic auth)
Password = "password" // opcional
};
Logs.Initialize(loki);
Logs.SetLoggingLevel(LogEventLevel.Information);
```
Las labels base siempre presentes en Loki son **service\_name**, **MachineName**, **Version** y **Environment**. Con `Logs.propertiesAsLabels` añades labels propias a partir de las propiedades estructuradas de tus logs.
Añade solo labels de **baja cardinalidad** (región, entorno, tier). Nunca `UserId`, `CorrelationId`, `SessionId` ni GUIDs: multiplican las series y saturan Loki. `Initialize` emite un `Warning` si detecta nombres sospechosos.
En Docker, `MachineName` toma el ID del contenedor si no fijas el hostname, y ese ID cambia en cada redeploy. Fija la variable de entorno `HOST_NAME` (o `hostname:` en el compose) para tener una label estable.
```csharp
using Dinaup;
using Dinaup.Ntfy;
using Serilog.Events;
var loki = new Logs.LokiConfig
{
Endpoint = "https://loki.tu-dominio.com/loki/api/v1/push"
};
// Cliente ntfy: servidor + (opcional) token de acceso.
var ntfy = new NtfyClientC("https://ntfy.tu-dominio.com", "tk_tu-token");
// El tercer y cuarto argumento activan el push: cliente + topic.
Logs.Initialize(loki, ntfy, "mi-app-alertas");
Logs.SetLoggingLevel(LogEventLevel.Information);
```
Con ntfy configurado, cada `Warning`, `Error` y `Fatal` publica una notificación en segundo plano. El nivel decide el topic de destino (`mi-app-alertas-warning`, `-error`, `-fatal`) y la prioridad ntfy. El envío está limitado a 60 notificaciones cada 20 segundos para no saturar el canal.
Antes de detener la aplicación llama a `CloseAndFlush` para enviar los datos pendientes.
```csharp
Logs.CloseAndFlush();
```
### Nivel de log [#nivel-de-log]
El nivel mínimo se ajusta en caliente con `SetLoggingLevel`, o mediante la variable de entorno `DINALOG_LEVEL` (`VERBOSE`, `DEBUG`, `INFORMATION`, `WARNING`, `ERROR`, `FATAL`). Por defecto es `Information`.
```csharp
Logs.SetLoggingLevel(LogEventLevel.Debug);
```
## Logs básicos y estructurados [#logs-básicos-y-estructurados]
Cada nivel (`Verbose`, `Debug`, `Information`, `Warning`, `Error`, `Fatal`) admite texto plano, plantilla estructurada con `{Propiedad}` y, además, una sobrecarga con la excepción como **primer** argumento.
```csharp
Logs.Information("Usuario {UserId} inició sesión", userId);
Logs.Warning("Intentos de acceso fallidos {Count} para {User}", attempts, userEmail);
// Con excepción: la excepción va SIEMPRE como primer argumento.
Logs.Error(ex, "Error al procesar pedido {OrderId}", orderId);
```
```csharp
public sealed class StripeService
{
public async Task CreateInvoice(Guid orderId)
{
using (Logs.BeginContext(nameof(StripeService), nameof(CreateInvoice)))
{
Logs.Debug("Generando factura para {OrderId}", orderId);
await Task.Delay(10); // tu lógica real aquí
var invoiceId = $"inv_{Guid.NewGuid():N}";
Logs.Information("Factura {InvoiceId} creada para {OrderId}", invoiceId, orderId);
return invoiceId;
}
}
}
```
```csharp
public sealed class JobWorker
{
public async Task RunAsync(IEnumerable orderIds)
{
var correlationId = $"corr-{Guid.NewGuid():N}";
using (Logs.BeginCorrelationContext(nameof(JobWorker), nameof(RunAsync), correlationId))
{
Logs.Information("Procesando {Count} pedidos", orderIds.Count());
foreach (var orderId in orderIds)
{
Logs.Debug("Pedido {OrderId}", orderId);
await Task.Delay(5); // tu lógica real aquí
}
Logs.Information("Lote completado");
}
}
}
```
`Warning`, `Error` y `Fatal` disparan además una notificación **ntfy** en segundo plano si inicializaste el logging con ntfy configurado. Para el detalle del cliente y las notificaciones manuales, ver [Notificaciones ntfy](/docs/desarrollo/dotnet/sdk/notificaciones-ntfy).
## Medición de operaciones [#medición-de-operaciones]
`BeginMeasure` mide la duración de un bloque de código y la registra al salir del `using`. Solo se registra si la operación supera el umbral (`thresholdMs`, por defecto **10 ms**), para no inundar el log con operaciones triviales.
```csharp
using (Logs.BeginMeasure("ImportarPedidos"))
{
await ImportarPedidosAsync();
}
// Al salir del using se registra la duración (si superó 10 ms).
```
```csharp
var metadata = new Dictionary
{
{ "tenant", tenantId },
{ "origen", "cron" }
};
using (Logs.BeginMeasure("SincronizarStock", labelKey: "Operation", metadata: metadata, thresholdMs: 50))
{
await SincronizarStockAsync();
}
```
```csharp
public async Task ProcesarAsync()
{
// Sin argumentos: el nombre de la operación se toma del método (CallerMemberName).
using (Logs.BeginMeasure())
{
await TrabajoPesadoAsync();
}
}
```
## Helpers de ejecución [#helpers-de-ejecución]
`HandleAction` y `HandleActionAsync` envuelven tu código con medición de tiempo y try/catch, registran la excepción si la hay y devuelven un `HandleActionResult` con:
* `IsOk`: indica éxito.
* `MessageException`: detalle del error si falló.
* `handledException`: la excepción capturada (o `null` si todo fue bien).
```csharp
var result = Logs.HandleAction(
component: nameof(PagosService),
action: nameof(PagosService.Cobrar),
body: () =>
{
// Tu lógica
ProcesarCobro(pedidoId);
},
details: new { PedidoId = pedidoId }
);
if (result.IsOk == false)
{
// El error ya se registró dentro de HandleAction.
Logs.Error("No se pudo cobrar pedido {PedidoId}: {Error}", pedidoId, result.MessageException);
}
```
```csharp
var result = await Logs.HandleActionAsync(
component: nameof(ServicioAsync),
action: nameof(ServicioAsync.ProcesarAsync),
body: async () =>
{
await Task.Delay(10);
await ProcesarAsync();
},
details: new { Correlation = correlationId }
);
if (result.IsOk == false)
{
Logs.Error("Proceso async falló: {Error}", result.MessageException);
}
```
`HandleActionAsync` admite un parámetro opcional adicional `minReportMs` (por defecto `0`) para registrar solo cuando la operación supere ese tiempo.
## Middleware de correlación (idea) [#middleware-de-correlación-idea]
```csharp
app.Use(async (context, next) =>
{
var componentName = "HttpRequest";
var actionName = context.Request.Path.Value ?? "/";
var correlationId = context.Request.Headers["X-Correlation-Id"].FirstOrDefault()
?? $"corr-{Guid.NewGuid():N}";
using (Logs.BeginCorrelationContext(componentName, actionName, correlationId))
{
await next();
}
});
```
# Dinaup.Validations (/docs/desarrollo/dotnet/sdk/dinaup.validations)
Cuando estás construyendo lógica fiscal, es clave asegurarte de que los datos que recibes del usuario son coherentes. Dinaup ofrece validaciones listas para usar, divididas en dos áreas principales.
## Validaciones de geolocalización [#validaciones-de-geolocalización]
***
### `IsSpanishPostalCode(string postalCode)` [#isspanishpostalcodestring-postalcode]
Verifica si un código postal pertenece al sistema de códigos postales español. Acepta exactamente 5 dígitos válidos.
```csharp
Console.WriteLine(ValidationUtils.IsSpanishPostalCode("03201")); // True
Console.WriteLine(ValidationUtils.IsSpanishPostalCode("99999")); // False
```
***
### `GetSpainProvinceFromPostalCode(string postalCode)` [#getspainprovincefrompostalcodestring-postalcode]
Devuelve el nombre de la provincia asociada a un código postal español. Si no se reconoce, devuelve una cadena vacía.
```csharp
Console.WriteLine(ValidationUtils.GetSpainProvinceFromPostalCode("28013")); // Madrid
```
***
### `NormalizeLocationName(string name)` [#normalizelocationnamestring-name]
Convierte nombres de ciudades regionales o en lenguas cooficiales al nombre estándar español.
```csharp
Console.WriteLine(ValidationUtils.NormalizeLocationName("elx")); // Elche
Console.WriteLine(ValidationUtils.NormalizeLocationName("Bilbo")); // Bilbao
```
***
### `SearchCountry(string query)` [#searchcountrystring-query]
Busca países por nombre (en inglés o español), ISO2. Devuelve una lista de coincidencias parciales.
```csharp
var results = ValidationUtils.SearchCountry("ES");
foreach (var c in results)
{
Console.WriteLine($"{c.ISO2} - {c.ESName} / {c.ENName}");
}
// ES - España / Spain
```
***
### `GetCountry(string countryNameOrCode)` [#getcountrystring-countrynameorcode]
Obtiene un país concreto por ISO o nombre. Útil cuando ya se tiene el identificador o el país escrito completo.
```csharp
var spain1 = ValidationUtils.GetCountry("ES");
Console.WriteLine($"{spain1.ISO2} - {spain1.ENName}"); // ES - Spain
var spain2 = ValidationUtils.GetCountry("España");
Console.WriteLine($"{spain2.ISO2} - {spain2.ENName}"); // ES - Spain
```
***
### `IsEuCountryCode(string isoCode)` [#iseucountrycodestring-isocode]
Devuelve `true` si el código ISO de país pertenece a la Unión Europea. La comparación no distingue mayúsculas.
```csharp
Console.WriteLine(ValidationUtils.IsEuCountryCode("DE")); // True
Console.WriteLine(ValidationUtils.IsEuCountryCode("US")); // False
```
***
## Validaciones de NIF / VAT [#validaciones-de-nif--vat]
***
### `IsVIESVatFormat(string vatID)` [#isviesvatformatstring-vatid]
Valida si el NIF está en un formato aceptado por el sistema VIES. **Solo valida estructura**, no existencia.
```csharp
Console.WriteLine(ValidationUtils.IsVIESVatFormat("ES123456789")); // True
Console.WriteLine(ValidationUtils.IsVIESVatFormat("US123456789")); // False
```
***
### `IsSpanishBusinessNIFFormat(string vatID)` [#isspanishbusinessnifformatstring-vatid]
Valida si un NIF tiene formato de empresa española. Es una validación débil pensada para autocompletado o sugerencias.
```csharp
Console.WriteLine(ValidationUtils.IsSpanishBusinessNIFFormat("B12345678")); // True
Console.WriteLine(ValidationUtils.IsSpanishBusinessNIFFormat("X1234567")); // False
```
***
### `CheckVATViesAsync(vatID)` *(async)* [#checkvatviesasyncvatid-async]
Consulta a VIES si un NIF está dado de alta como operador intracomunitario. Se invoca sobre un cliente Dinaup conectado. Devuelve un `bool?` con tres estados: `true` (alta confirmada), `false` (no es operador, formato inválido o país no comunitario) y `null` (VIES no concluyente).
```csharp
bool? esIntracomunitario = await dinaupClient.CheckVATViesAsync("ESB09689647");
Console.WriteLine(esIntracomunitario); // True
```
***
### `CheckVATAEATAsync(vatID, name)` *(async)* [#checkvataeatasyncvatid-name-async]
Consulta a la AEAT si el NIF y el nombre coinciden. Útil para validación de facturas en España. Se invoca sobre un cliente Dinaup conectado y devuelve un `CheckVATAEATResponse` con `Identificado`, `Nif`, `Nombre` y `Resultado`.
```csharp
var result = await dinaupClient.CheckVATAEATAsync("74381925V", "Angel Albaladejo Belmonte");
Console.WriteLine(result.Identificado); // True
```
***
### `ClassifyVatTerritoriality(vatID, countryCode, postalCode, isVies)` [#classifyvatterritorialityvatid-countrycode-postalcode-isvies]
Clasifica la operación fiscal según el lugar de tributación del IVA: nacional, exportación, intracomunitaria, etc.
```csharp
var tipo = ValidationUtils.ClassifyVatTerritoriality("B12345678", "ES", "03201", false);
Console.WriteLine(tipo); // National
var tipo2 = ValidationUtils.ClassifyVatTerritoriality("DE267602842", "DE", "81549", true);
Console.WriteLine(tipo2); // IntraCommunity
```
Tipos posibles:
* Unknown
* Simplified
* National
* OutOfVatTerritory
* IntraCommunity
* OneStopShop
* Export
# IAQuery: consultas dinámicas sin informe (/docs/desarrollo/dotnet/sdk/iaquery)
`IAQuery` ejecuta una consulta definida en la propia llamada: eliges campos, filtros, agrupación y orden, el servidor genera el SQL y lo ejecuta en la base de datos. No necesitas crear un informe en Flex.
```csharp
// Total facturado desde enero, calculado en el servidor
var req = new IAQueryRequestParameters(VentasIngresosD._SectionID, 1);
req.AddField(VentasIngresosD.VentasIngresosES.ImporteTotal, "sum", "total");
req.AddWhere(VentasIngresosD.VentasIngresosES.FechaOperacion, ">=", "2026-01-01");
var res = await dinaupClient.IAQuery_GetAsync(req);
var total = res.Data[0]["total"];
```
La agregación corre en la base de datos: sumar 800.000 facturas devuelve una fila, no 800.000. Las constantes de sección y campo (`VentasIngresosD`) salen de tu paquete [MyDinaup](/docs/desarrollo/dotnet/mydinaup); también puedes pasar el GUID de la sección y las claves de campo en crudo.
## Cuándo usar IAQuery [#cuándo-usar-iaquery]
| Necesidad | Herramienta |
| ----------------------------------------------------- | ---------------------------------------------------------------------------- |
| Listado estable, con columnas cuidadas y reutilizable | [Informe de Flex](/docs/desarrollo/flex/informes) |
| Agregado o consulta puntual definida en código | IAQuery |
| Volcar un informe entero para exportar o sincronizar | [LoadAllRowsAsync](/docs/desarrollo/dotnet/sdk/listados-de-alto-rendimiento) |
| Leer datos desde otro lenguaje, por REST | [Informes por API](/docs/desarrollo/flex/informes/informes-api) |
IAQuery no está en la API REST pública: hoy se usa desde el SDK .NET o desde el playground de play (abajo).
¿Un panel o una gráfica? DinaZen trae [`DnzDynamicStat`](/docs/guias/dinazen): recibe el resultado de una consulta y elige KPI, gráfico o tabla según la forma del dato.
## Construir la consulta [#construir-la-consulta]
`IAQueryRequestParameters` se monta con métodos encadenables:
| Método | Qué añade |
| ------------------------------------- | --------------------------------------------------------- |
| `AddField(campo, funcion, alias)` | Columna del SELECT. `funcion` y `alias` son opcionales |
| `AddWhere(campo, op, valor, logico)` | Condición de filtro. `logico`: `and` (por defecto) u `or` |
| `AddGroupBy(campo, funcion)` | Agrupación, con función de fecha opcional |
| `AddOrderBy(campo, direccion)` | Orden `asc` o `desc` |
| `AddHaving(campo, op, valor, logico)` | Filtro sobre los agregados, misma sintaxis que el WHERE |
`Limite` y `Pagina` completan la petición. Ejemplo completo, ventas de 2026 por mes:
```csharp
using static DemoUp.MyDinaup.SectionsD; // constantes de tu MyDinaup
var req = new IAQueryRequestParameters(VentasIngresosD._SectionID, 12);
req.AddField(VentasIngresosD.VentasIngresosES.FechaOperacion, "monthyear", "mes");
req.AddField(VentasIngresosD.VentasIngresosES.ImporteTotal, "sum", "total");
req.AddGroupBy(VentasIngresosD.VentasIngresosES.FechaOperacion, "monthyear");
req.AddWhere(VentasIngresosD.VentasIngresosES.FechaOperacion, ">=", "2026-01-01");
req.AddWhere(VentasIngresosD.VentasIngresosES.FechaOperacion, "<=", "2026-12-31");
req.AddOrderBy(VentasIngresosD.VentasIngresosES.FechaOperacion, "asc");
var res = await dinaupClient.IAQuery_GetAsync(req);
foreach (var fila in res.Data)
Console.WriteLine($"{fila["mes"]}: {fila["total"]}");
```
Todo campo tiene además un alias por defecto: el último tramo de su ruta. Para claves internas (`pr_...`) conviene declarar un alias legible, como `"total"`.
## Funciones de campo [#funciones-de-campo]
Se aplican en `AddField` y, las de fecha, también en `AddGroupBy`.
**Agregación:**
| Función | Devuelve |
| --------------- | --------------------------- |
| `sum` | Suma (0 si no hay filas) |
| `count` | Cuenta de valores del campo |
| `count*` | Cuenta de filas |
| `countdistinct` | Cuenta de valores distintos |
| `avg` | Media (0 si no hay filas) |
| `min` / `max` | Mínimo y máximo |
**Fecha** (transforman un campo de fecha en texto, útiles para agrupar):
| Función | Ejemplo de salida |
| ------------- | --------------------- |
| `date` | `2026-07-09` |
| `month` | `07` |
| `year` | `2026` |
| `monthyear` | `07/2026` |
| `quarter` | `3T` |
| `quarteryear` | `3T - 2026` |
| `dayofweek` | `1` a `7` (1 = lunes) |
| `dayofmonth` | `09` |
| `hour` | `00` a `23` |
Cualquier otra función se rechaza con un error que lista las admitidas.
## Filtros [#filtros]
Operadores admitidos en `AddWhere` y `AddHaving` (en minúsculas):
| Operador | Nota |
| -------------------------- | -------------------------------------- |
| `=` `<>` `>` `<` `>=` `<=` | Comparación directa |
| `like` / `not like` | Incluye tú los comodines: `%texto%` |
| `in` / `not in` | Valores separados por comas: `"a,b,c"` |
| `is null` / `is not null` | Sin valor |
Los valores viajan como texto: fechas en ISO (`2026-01-31`), números con punto decimal, booleanos como `1` y `0`. Cada campo se valida contra el esquema y los operadores van con lista blanca; los valores se escapan en el servidor.
Los registros eliminados quedan fuera de toda consulta: el servidor añade `eliminado = 0` por ti. Si quieres verlos, incluye tu propia condición sobre el campo `eliminado`.
## Ordenar y paginar [#ordenar-y-paginar]
* `AddOrderBy` solo acepta campos que estén en el SELECT, con un máximo de 5 criterios, dirección `asc` o `desc` y sin repetir campo.
* Sin `AddOrderBy`, las consultas no agregadas llegan por fecha descendente. Las agregadas llegan sin orden garantizado: pide el tuyo.
* `Limite` admite de 1 a 30.000 filas por página (100 si no lo indicas). Para leer más filas, pagina.
* `Pagina` empieza en 1, no en 0.
* El `Total` de la respuesta son las filas devueltas en esa página, no las que existen en la sección.
El SDK valida la petición antes de enviarla, así que estos errores no gastan una llamada al servidor:
| Qué haces mal | Qué te lanza |
| ----------------------------------------------------------------------------------------------- | ----------------------------- |
| `Limite` fuera de 1..30.000 | `ArgumentOutOfRangeException` |
| `Pagina` menor que 1 | `ArgumentOutOfRangeException` |
| Sección, campo u operador vacíos | `ArgumentException` |
| `logico` distinto de `and`/`or`, dirección distinta de `asc`/`desc`, campo repetido en el orden | `ArgumentException` |
| Más de 5 criterios de orden | `InvalidOperationException` |
| Ejecutar sin ningún `AddField`, u ordenar por un campo que no está en el SELECT | `InvalidOperationException` |
## Campos de secciones relacionadas [#campos-de-secciones-relacionadas]
Un campo de referencia guarda el GUID del registro relacionado. Para leer un campo de la sección relacionada (su nombre, por ejemplo), usa una ruta de cuatro tramos:
```
seccionID.campoReferencia.seccionRelacionadaID.campo
```
Con ella puedes agrupar ventas por nombre de cliente sin resolver GUIDs a mano. El playground de play construye estas rutas por ti al elegir el campo relacionado.
## La respuesta [#la-respuesta]
`IAQuery_GetAsync` devuelve un `IAQueryResponse`:
| Campo | Contenido |
| ------------------------------ | ----------------------------------------------------------------------- |
| `Ok` | `true` si la consulta se ejecutó |
| `Columns` | Alias de las columnas, en el orden del SELECT |
| `Data` | Filas como `List>`: clave alias, valor texto |
| `Total` | Filas devueltas en esta página |
| `Page` / `Limit` | Página y límite aplicados |
| `TimeMs` | Milisegundos de ejecución en el servidor |
| `SQL` | El SQL exacto que se ejecutó |
| `ErrorNotices` / `Description` | Detalle del error cuando `Ok` es `false` |
Todos los valores llegan como texto: conviértelos a su tipo al leerlos. El campo `SQL` te deja verificar la consulta generada mientras desarrollas.
## Atajos: QuickQuery [#atajos-quickquery]
Para las preguntas de siempre (contar, sumar, agrupar) no hace falta construir la petición. El cliente expone `QuickQuery`, que devuelve el valor ya convertido:
```csharp
// Suma (decimal) y cuenta (int), sin leer Data ni convertir a mano
var total = await dinaupClient.QuickQuery.SumAsync(VentasIngresosD._SectionID, VentasIngresosD.VentasIngresosES.ImporteTotal);
var n = await dinaupClient.QuickQuery.CountAsync(VentasIngresosD._SectionID);
```
Los seis métodos, sus filtros y el formato del resultado, en [QuickQuery](/docs/desarrollo/dotnet/sdk/quickquery).
## Permisos y validación [#permisos-y-validación]
* La consulta hereda los permisos del usuario de la sesión: se validan contra el informe principal de la sección. Sin permiso de consulta, la llamada se rechaza.
* Las secciones base no se consultan directamente; consulta la sección concreta.
* Campos nativos disponibles en toda sección: `id`, `nombre`, `fecha`, `eliminado`.
## Pruébalo sin código [#pruébalo-sin-código]
En play, la app **Desarrolladores** incluye el playground de IAQuery (**Consulta con IA**, en Herramientas). Eliges sección, campos, filtros, agrupación y orden en un editor visual, y ves las filas, el tiempo y el SQL generado. Lo que montas ahí se traduce línea a línea a los métodos de esta página.
Para el resto de la API del cliente (informes, escrituras, sesión), ver el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
# SDK .NET (/docs/desarrollo/dotnet/sdk)
El SDK .NET de Dinaup es la familia de módulos para construir aplicaciones .NET sobre la plataforma. Todo viaja dentro del paquete principal `Dinaup`: cada módulo cubre un aspecto y se usa de forma independiente.
## Instalación [#instalación]
```bash
dotnet add package Dinaup
```
Para trabajar tipado contra tu modelo de datos (secciones, informes, documentos), añade tu biblioteca [MyDinaup](/docs/desarrollo/dotnet/mydinaup).
## Módulos [#módulos]
Conexión, sesiones, informes, archivos, anotaciones, documentos dinámicos, WriteOperations y fichajes contra la API.
Vuelca un informe entero con
`LoadAllRowsAsync`
: paginación por keyset, coste constante, sin duplicados.
Acceso a PostgreSQL con
`PGClient`
: lecturas tipadas, upsert, lectura por lotes y opciones de pool.
Logging estructurado con Serilog, correlación distribuida, medición de tiempos y envío a Loki.
Push a un topic ntfy con
`NtfyClientC`
, suelto o enganchado a los logs de error.
NIF/VAT, VIES, AEAT, códigos postales, provincias y países.
Primitivas de concurrencia y limitación, conversiones de tipos y familias de extensiones.
Sube, descarga y firma objetos en S3/MinIO, con cliente simple y multi-bucket.
Middleware de mantenimiento y correlación, y endpoints de entorno y versión.
Configuración secreta cifrada con
`VaultData`
: solo la URL y la contraseña en el entorno.
## Módulos auxiliares [#módulos-auxiliares]
Piezas más pequeñas que también entran con el paquete `Dinaup`.
### Login de empleados (authclient) [#login-de-empleados-authclient]
`DinaupAuthClient` autentica credenciales de empleado contra `auth.dinaup.com` (login tipo SecureLink). Una sola llamada:
```csharp
using Dinaup.Auth;
var auth = new DinaupAuthClient();
var res = await auth.LoginAsync(email, password);
if (res != null)
{
// res trae la keyword de conexión del tenant y los datos del usuario
}
```
Aplica límite de intentos (4 por minuto y correo). Devuelve `null` si las credenciales fallan.
### Integración de apps externas (myapps) [#integración-de-apps-externas-myapps]
Para apps externas que operan sobre un tenant:
* **`MyAppClient`**: hereda de `DinaupClientC` (acceso completo a la API) y ejecuta informes con `ExecuteReport`, resolviendo la sesión desde la configuración de la app externa.
* **`MyAppKVClient`**: almacén clave-valor distribuido (`SetKVAsync`/`GetKVAsync`, hasta 10 MB por valor). Implementa `IHealthCheck`.
### Excepciones (exceptions) [#excepciones-exceptions]
El SDK lanza excepciones tipadas del namespace `Dinaup.Exceptions`: `ClientNotInitializedException`, `APIConnectionException`, `InvalidAPIResponseException`, `TimeoutException`, `APIOperationException`, `RetryLimitExceeded`, `APIRequestException`. Cáptualas para distinguir un fallo de conexión de una respuesta inválida o un timeout.
### Cultura y zona horaria (cultureservice) [#cultura-y-zona-horaria-cultureservice]
`CultureService` (interfaz `ICultureService`) formatea fechas, importes y decimales según la cultura y la zona horaria del usuario, y convierte entre UTC y hora local (`ToLocal`, `ToUtc`, `ToStringMoney`, `ToLocalFriendlyDate`). Detecta la cultura del header `Accept-Language`; los valores por defecto (`es-ES`, `Europe/Madrid`) se ajustan con `CultureServiceOptions`.
## MyDinaup [#mydinaup]
Dinaup es flexible: cada empresa tiene su propio modelo de datos. Para trabajarlo tipado necesitas tu biblioteca MyDinaup, con los nombres reales de tus secciones, informes y documentos.
```bash
# Modelo genérico Ready to Go (compatible entre empresas)
dotnet add package ReadyToGo.MyDinaup
```
Qué contiene, cómo se genera y cómo se usa, en [MyDinaup](/docs/desarrollo/dotnet/mydinaup).
# Listados de alto rendimiento (/docs/desarrollo/dotnet/sdk/listados-de-alto-rendimiento)
Cuando necesitas **todas** las filas de un informe (exportar, reprocesar, sincronizar), la forma de paginar decide el rendimiento y la corrección. `LoadAllRowsAsync`, en `DinaupReportBase`, recorre el informe completo por keyset sobre el id, sin `OFFSET`.
## El problema de OFFSET [#el-problema-de-offset]
La forma clásica de recorrer un informe página a página usa `LIMIT`/`OFFSET`:
```csharp
await report.ExecuteQueryAsync(dinaupClient, 1, pageSize);
var filas = report.Rows.ToList();
while (await report.ExecuteQuery_NextPageAsync())
filas.AddRange(report.Rows);
```
En volúmenes grandes tiene dos problemas:
* **Corrección.** `OFFSET` sin un orden total y sin desempate no es determinista: el servidor puede devolver la misma fila en dos páginas o saltarse una. Si luego indexas por id (`ToDictionary(r => r.Id)`), obtienes una excepción de clave duplicada o, peor, filas que faltan sin avisar.
* **Rendimiento.** `OFFSET 18000` hace que el servidor recorra y descarte 18.000 filas en cada página. Cuanto más avanzas, más lento va: coste `O(offset)` por página.
## La solución: keyset (cursor) [#la-solución-keyset-cursor]
En vez de pedir "la página N", pides "las filas **después** del último id que vi":
```sql
WHERE id > :last_seen_id
ORDER BY id ASC
LIMIT :page_size
```
Cada página es un **recorrido por rango de índice** sobre la columna id: coste constante sin importar la profundidad y, como el id es único, nunca una fila repetida ni un hueco.
## Cómo se usa [#cómo-se-usa]
```csharp
// Vuelca el informe entero, rápido y sin duplicados.
var todas = await report.LoadAllRowsAsync(dinaupClient, pageSize: 10000, adminMode: true);
```
Eso es todo. El método:
* Ordena por la columna **id** del informe internamente. No llames a `AddOrder`: lanza excepción si ya hay un orden definido.
* Añade un único filtro `id > cursor` y lo avanza tras cada página, así que tus filtros (rangos de fecha, referencias…) se conservan y se combinan con `AND`.
* Para cuando una página vuelve más corta que `pageSize`, con guarda contra cursores estancados.
* Si llega a `maxRows` con filas aún pendientes, **lanza excepción** en vez de devolver una lista truncada en silencio: reduce el informe con un filtro o sube `maxRows`.
Firma y valores por defecto:
```csharp
Task> LoadAllRowsAsync(
DinaupClientC dinaupClient,
int pageSize = 10000,
int maxRows = 50000000,
bool adminMode = false)
```
### ¿Necesitas otro orden? [#necesitas-otro-orden]
El keyset **debe** ordenar por id para funcionar, así que aplica el orden de presentación **en memoria** después:
```csharp
var porFecha = todas.OrderBy(r => r.Fecha).ToList();
```
## Límites y excepciones [#límites-y-excepciones]
`LoadAllRowsAsync` lanza excepción cuando no puede garantizar un recorrido correcto:
| Condición | Excepción |
| ----------------------------------------- | --------------------------- |
| `pageSize` o `maxRows` no positivos | `ArgumentException` |
| El informe no expone columna `ID` | `InvalidOperationException` |
| Ya se llamó a `AddOrder` | `InvalidOperationException` |
| Ya hay un filtro sobre la columna `ID` | `InvalidOperationException` |
| Las filas no implementan `IDinaupRow` | `InvalidOperationException` |
| Se alcanza `maxRows` con filas pendientes | `InvalidOperationException` |
## Cuándo usar cada uno [#cuándo-usar-cada-uno]
| | `ExecuteQuery_NextPageAsync` (OFFSET) | `LoadAllRowsAsync` (keyset) |
| ------------------------------------------- | ----------------------------------------- | ----------------------------- |
| Una página visible | ✅ mejor opción | excesivo |
| Volcar el informe entero | riesgo de duplicados/huecos, se ralentiza | ✅ rápido y correcto |
| Orden de presentación durante la paginación | ✅ en el servidor | ordena en memoria tras cargar |
El id se compara **como texto** en el servidor. El keyset solo es correcto si el servidor ordena el id y compara `id > x` con el mismo criterio textual y el mismo formato (minúsculas, con guiones). Es el comportamiento de las estructuras Dinaup estándar.
Para el resto de la API de informes (filtros, paginación clásica, tiempos del servidor), ver el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
# Notificaciones ntfy (/docs/desarrollo/dotnet/sdk/notificaciones-ntfy)
El módulo `dinaup.ntfy` del paquete `Dinaup` publica notificaciones push a un topic de [ntfy](https://ntfy.sh) desde cualquier app. Se usa suelto, para mandar avisos concretos, o enganchado a [Dinaup.Logs](/docs/desarrollo/dotnet/sdk/dinaup.logs) para que cada `Warning`/`Error`/`Fatal` dispare una notificación.
```csharp
using Dinaup.Ntfy;
```
## Cliente ntfy [#cliente-ntfy]
### Crear el cliente [#crear-el-cliente]
```csharp
// Servidor público o autoalojado
var ntfy = new NtfyClientC("https://ntfy.tu-dominio.com");
// Con token de acceso para topics protegidos
var ntfyAuth = new NtfyClientC("https://ntfy.tu-dominio.com", "tk_tu-token");
```
También acepta un `NtfyClientOptions` con más ajustes:
```csharp
var ntfy = new NtfyClientC(new NtfyClientOptions
{
ServerUrl = "https://ntfy.tu-dominio.com",
AccessToken = "tk_tu-token",
DefaultTopic = "mi-app",
DefaultPriority = NtfyPriority.Default,
Timeout = TimeSpan.FromSeconds(30)
});
```
### Enviar [#enviar]
```csharp
// Mensaje simple
await ntfy.SendAsync("mi-app", "Backup completado");
// Con título y prioridad
await ntfy.SendAsync("mi-app", "Stock por debajo del mínimo", "Aviso de inventario", NtfyPriority.High);
```
Las prioridades son `Minimum`, `Low`, `Default`, `High` y `Urgent`. Cada `SendAsync` devuelve un `NtfyResult` con `IsSuccess`, `ErrorMessage` y `MessageId`.
Hay variantes para casos más ricos:
* `SendMarkdownAsync`: cuerpo en Markdown.
* `SendWithClickUrlAsync`: la notificación abre una URL al tocarla.
* `SendWithActionsAsync`: botones de acción (`NtfyAction`).
* `SendWithAttachmentUrlAsync` / `SendWithAttachmentAsync`: adjunta un archivo por URL o por bytes.
* `SendAppStartupAsync`, `SendAppShutdownAsync`, `SendAppErrorAsync`: avisos de ciclo de vida de la app.
## Enganche al pipeline de logs [#enganche-al-pipeline-de-logs]
Pasa el cliente ntfy y un topic a `Logs.Initialize` para que el logging publique avisos solo:
```csharp
using Dinaup;
using Dinaup.Ntfy;
var loki = new Logs.LokiConfig { Endpoint = "https://loki.tu-dominio.com/loki/api/v1/push" };
var ntfy = new NtfyClientC("https://ntfy.tu-dominio.com", "tk_tu-token");
Logs.Initialize(loki, ntfy, "mi-app-alertas");
```
A partir de ahí, cada `Logs.Warning`, `Logs.Error` y `Logs.Fatal` publica una notificación en segundo plano. El nivel decide el topic de destino y la prioridad:
| Nivel de log | Topic | Prioridad ntfy |
| ------------ | ------------------------ | -------------- |
| `Warning` | `mi-app-alertas-warning` | Default |
| `Error` | `mi-app-alertas-error` | High |
| `Fatal` | `mi-app-alertas-fatal` | Urgent |
El envío desde logs está limitado a 60 notificaciones cada 20 segundos: un pico de errores no inunda tu teléfono. Los avisos que superan el límite se descartan, pero el log se registra igual.
### Notificaciones manuales desde Logs [#notificaciones-manuales-desde-logs]
Con el logging ya inicializado con ntfy, puedes mandar avisos sin pasar por un nivel de log:
```csharp
await Logs.SendNotificationAsync("Cierre de caja pendiente", "Recordatorio", NtfyPriority.Default);
```
`Logs.IsNtfyConfigured` indica si el enganche está activo. `Logs.SendErrorNotificationAsync(exception, context)` y `Logs.SendShutdownNotificationAsync(reason)` cubren los avisos de error y apagado.
# QuickQuery: contar, sumar y agrupar en una línea (/docs/desarrollo/dotnet/sdk/quickquery)
`QuickQuery` responde las preguntas de siempre (cuántos hay, cuánto suman, cuáles son) sin construir un `IAQueryRequestParameters`. Vive en el propio cliente y devuelve el valor convertido a su tipo:
```csharp
using static DemoUp.MyDinaup.SectionsD; // constantes de tu MyDinaup
// ¿Cuánto he facturado este mes? Un decimal
var facturado = await dinaupClient.QuickQuery.SumAsync(
VentasIngresosD._SectionID,
VentasIngresosD.VentasIngresosES.ImporteTotal,
[QuickQueryFilter.GreaterThanOrEqual(VentasIngresosD.VentasIngresosES.FechaOperacion, "2026-07-01")]);
// ¿Cuántas facturas llevo? Un int
var cuantas = await dinaupClient.QuickQuery.CountAsync(
VentasIngresosD._SectionID,
[QuickQueryFilter.GreaterThanOrEqual(VentasIngresosD.VentasIngresosES.FechaOperacion, "2026-07-01")]);
```
Cada llamada es una consulta [IAQuery](/docs/desarrollo/dotnet/sdk/iaquery) por debajo: la agregación corre en la base de datos y heredas sus permisos y límites tal cual.
## Seis métodos, seis preguntas [#seis-métodos-seis-preguntas]
| Método | Responde a | Devuelve |
| ---------------------------------------------------------------------------- | -------------------------- | ------------------------------------- |
| `CountAsync(seccion, filtros?)` | cuántas filas cumplen | `int` |
| `SumAsync(seccion, campo, filtros?)` | cuánto suma un campo | `decimal` |
| `ValuesAsync(seccion, campo, filtros?, orden?, limite?)` | los valores de una columna | `List` |
| `FirstAsync(seccion, campos, filtros?, orden?)` | la primera fila que cumple | `Dictionary` o `null` |
| `QueryAsync(seccion, campos, filtros?, orden?, limite?, pagina?)` | las filas completas | `QuickQueryResult` |
| `GroupByAsync(seccion, campoGrupo, agregaciones, filtros?, orden?, limite?)` | totales por grupo | `QuickQueryResult` |
Todos los parámetros con `?` son opcionales. `orden` es un texto tipo `"campo desc"` (sin dirección: `asc` en consultas, `desc` en agrupadas) y solo admite campos presentes en el SELECT. `limite` va de 1 a 30.000 filas (100 si no lo indicas) y `pagina` empieza en 1: fuera de rango, el SDK lanza la excepción antes de llamar al servidor (mismas validaciones que [IAQuery](/docs/desarrollo/dotnet/sdk/iaquery#ordenar-y-paginar)).
Los campos aceptan las mismas rutas que IAQuery, incluidas las de [secciones relacionadas](/docs/desarrollo/dotnet/sdk/iaquery#campos-de-secciones-relacionadas) de cuatro tramos.
## Filtros que se leen como frases [#filtros-que-se-leen-como-frases]
`QuickQueryFilter` trae un constructor estático por operador: `Equal`, `NotEqual`, `GreaterThan`, `GreaterThanOrEqual`, `LessThan`, `LessThanOrEqual`, `Like`, `In`. Un rango son dos filtros:
```csharp
QuickQueryFilter[] julio =
[
QuickQueryFilter.GreaterThanOrEqual(VentasIngresosD.VentasIngresosES.FechaOperacion, "2026-07-01"),
QuickQueryFilter.LessThanOrEqual(VentasIngresosD.VentasIngresosES.FechaOperacion, "2026-07-31")
];
```
* Los filtros se combinan con `and`; `.Or()` cambia el conector de ese filtro: `QuickQueryFilter.Equal(campo, "1").Or()`.
* `Like` no añade comodines: inclúyelos tú (`%texto%`). `In` recibe los valores separados por comas (`"a,b,c"`).
* Para otro operador (`is null`, `not in`...), construye el objeto a mano: `new QuickQueryFilter { Field = campo, Op = "is null" }`. Los operadores admitidos son [los de IAQuery](/docs/desarrollo/dotnet/sdk/iaquery#filtros).
* Los valores viajan como texto: fechas en ISO (`2026-07-31`), números con punto decimal, booleanos como `1` y `0`.
## Agrupar con GroupByAsync [#agrupar-con-groupbyasync]
`GroupByAsync` agrupa por un campo y calcula una o varias agregaciones, definidas con `QuickQueryAggField.Sum`, `.Count`, `.Avg`, `.Max` o `.Min`:
```csharp
// Diez clientes con más facturación
var res = await dinaupClient.QuickQuery.GroupByAsync(
VentasIngresosD._SectionID,
VentasIngresosD.VentasIngresosES.ReferenciaCliente,
[QuickQueryAggField.Sum(VentasIngresosD.VentasIngresosES.ImporteTotal)],
orderBy: VentasIngresosD.VentasIngresosES.ImporteTotal + " desc",
limit: 10);
foreach (var fila in res.Rows)
Console.WriteLine($"{fila[res.Columns[0]]}: {fila[res.Columns[1]]}");
```
La primera columna es el valor del grupo; después, una por agregación. Para agrupar por una función de fecha (`monthyear`, `quarter`...), baja a [IAQuery](/docs/desarrollo/dotnet/sdk/iaquery#funciones-de-campo): QuickQuery agrupa solo por el valor directo del campo.
## Leer el resultado [#leer-el-resultado]
`QueryAsync` y `GroupByAsync` devuelven un `QuickQueryResult`:
| Campo | Contenido |
| --------- | --------------------------------------------- |
| `Ok` | `true` si la consulta se ejecutó |
| `Error` | detalle del fallo cuando `Ok` es `false` |
| `Rows` | filas como `List>` |
| `Columns` | alias de las columnas, en el orden del SELECT |
| `Total` | filas devueltas en esta página |
| `TimeMs` | milisegundos de ejecución en el servidor |
Las claves de `Rows` son los alias por defecto de IAQuery: el último tramo de la ruta de cada campo. Con claves internas (`pr_...`) o rutas relacionadas, lee por posición con `Columns`, como en el ejemplo de arriba.
QuickQuery no lanza excepciones: el error llega en `Ok` y `Error`. `CountAsync` y `SumAsync` devuelven `0` tanto si el resultado es cero como si la consulta falló; si necesitas distinguirlo, usa `QueryAsync` y comprueba `Ok`.
## Lo que hereda de IAQuery [#lo-que-hereda-de-iaquery]
* Los permisos del usuario de la sesión: sin permiso de consulta sobre la sección, la llamada se rechaza.
* El filtro `eliminado = 0`, añadido por el servidor en toda consulta.
* Los operadores, las validaciones de campo y el tope de 30.000 filas por página.
* Todos los valores llegan como texto: conviértelos a su tipo al leerlos.
## Cuándo bajar a IAQuery [#cuándo-bajar-a-iaquery]
QuickQuery cubre el caso frecuente; el constructor completo sigue ahí para el resto:
* Agrupar por funciones de fecha (`month`, `quarter`, `monthyear`...).
* Filtrar sobre los agregados con `AddHaving`.
* `count*`, `countdistinct` o alias propios por columna.
* Ver el SQL generado (`IAQueryResponse.SQL`) mientras desarrollas.
La referencia completa del motor, con sus operadores, funciones y límites, en [IAQuery](/docs/desarrollo/dotnet/sdk/iaquery).
# Utilidades (/docs/desarrollo/dotnet/sdk/utilidades)
El paquete `Dinaup` incluye un módulo de utilidades con primitivas de concurrencia y limitación, conversiones de tipos y métodos de extensión. Todo vive en el paquete principal: no hay nada que instalar aparte.
```csharp
using Dinaup;
```
## Primitivas de concurrencia y limitación [#primitivas-de-concurrencia-y-limitación]
Piezas pequeñas y probadas para los problemas típicos de ritmo, caché y ejecución en background. Úsalas antes de resolverlo a mano.
### Debouncer [#debouncer]
Retrasa una acción asíncrona y cancela las llamadas anteriores si llega otra dentro de la ventana. Para operaciones caras disparadas por eventos rápidos (teclas, scroll, redibujados).
```csharp
var debouncer = new Debouncer(async () => await GuardarBorradorAsync(), 500);
// Cada pulsación reinicia el contador; solo se guarda 500 ms tras la última.
debouncer.Debounce();
```
### ExpirableValue / ExpirableValueAsync [#expirablevalue--expirablevalueasync]
Envuelve un valor con expiración (TTL). Al leerlo, si ha caducado, llama a la función de refresco. Hay versión síncrona y asíncrona, genéricas sobre `T`.
```csharp
// Refresca desde una fábrica cada 60 s.
var token = new ExpirableValueAsync(
async () => await PedirTokenAsync(),
expirationInSeconds: 60);
string actual = await token.GetValueAsync();
// Versión síncrona con valor inicial o con actualizador.
var config = new ExpirableValue(() => LeerConfig(), expirationInSeconds: 30);
int n = config.GetValue();
```
### RateLimiter [#ratelimiter]
Limita intentos por clave. `TryAttempt` incrementa el contador de esa clave y devuelve `false` si supera el máximo. Se reinicia sola al vencer el intervalo.
```csharp
var limiter = new RateLimiter(maxAttempts: 5, clearInterval: TimeSpan.FromMinutes(1));
if (limiter.TryAttempt(userEmail) == false)
throw new Exception("Demasiados intentos, prueba en un minuto.");
```
### TokenBucket [#tokenbucket]
Cubo de tokens clásico. Se rellena a `refillPerSecond` tokens por segundo. `TryConsume` devuelve `true` si hay tokens y `false` si no.
```csharp
var bucket = new TokenBucket(maxTokens: 100, refillPerSecond: 10);
if (bucket.TryConsume())
await LlamarApiExternaAsync();
```
### SlidingCounter [#slidingcounter]
Limitador por ventana deslizante. `TryAdd` devuelve `true` mientras el número de eventos dentro de la ventana no supere el máximo; poda los eventos antiguos sola.
```csharp
var counter = new SlidingCounter(maxEvents: 1000, window: TimeSpan.FromSeconds(10));
if (counter.TryAdd() == false)
return; // pico de actividad: descarta o encola
```
### SerialQueue [#serialqueue]
Cola FIFO segura entre hilos para ejecutar tareas de una en una. Cada `Enqueue` devuelve un `Task` que completa cuando el trabajo termina. Evita ejecuciones concurrentes sin bloquear.
```csharp
var queue = new SerialQueue();
// Se ejecutan en orden, nunca a la vez.
await queue.Enqueue(async () => await EscribirEnArchivoAsync(a));
var total = await queue.Enqueue(() => Calcular());
```
### IBackgroundTaskQueue [#ibackgroundtaskqueue]
Cola de trabajo asíncrono con descripción por tarea. `Enqueue` añade trabajo; `DequeueAsync` bloquea hasta que hay una tarea. `QueuedHostedService` (un `BackgroundService`) las consume y ejecuta.
```csharp
IBackgroundTaskQueue queue = new BackgroundTaskQueue();
queue.Enqueue(async ct => await ProcesarPedidoAsync(pedidoId, ct), "procesar-pedido");
int pendientes = queue.Count();
var resumen = queue.ResumenCola(); // descripción -> cuántas pendientes
```
## Conversiones de tipos [#conversiones-de-tipos]
Métodos de extensión para convertir entre tipos sin `TryParse` a mano ni excepciones inesperadas. Convierten desde `String`, `Object`, valores anulables y otros.
| Familia | Convierte a | Ejemplos de uso |
| ------------------ | -------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `STR` | `String` | `precio.STR()`, `id.STR()`, `fecha.STR()`. Formatea decimales y fechas de forma coherente, tolera nulos. |
| `INT` | `Integer` | `texto.INT(0)` (con defecto), `texto.INT(min, max, siFalla)` (con límites). |
| `ToDate` y familia | `Date` / `DateOnly` / `TimeOnly` | `s.ToDate()`, `s.ToDateOnly()`, `s.ToDateDesdeMySQL_utc()`, variantes `_Nullable` y de zona horaria. |
| `ToSQL` y familia | Literal SQL | `nombre.ToSQL()`, `fecha.ToSQL_Date()`, `importe.ToSQL_Decimal()`, para concatenar en sentencias. |
| `ToSHA1` | Hash hex | `ToSHA1(bytes)`, `ToSHA1(texto)`, `ToSHA1(stream)`. |
```csharp
int cantidad = Request["cantidad"].INT(0); // 0 si no es número
string fecha = DateTime.UtcNow.ToSQL_Date(); // literal para SQL
string hash = Dinaup.extensions.ToSHA1(bytes); // SHA-1 en hex
```
`ToSQL` produce literales para **concatenar**, no parámetros. Escapa comillas y barras al estilo MySQL, así que solo es seguro contra PostgreSQL con `standard_conforming_strings=off`, el contrato que `PGClient` ya fija. Fuera de ese contexto, usa consultas parametrizadas.
## Familias de extensiones [#familias-de-extensiones]
El módulo añade cientos de métodos de extensión. Estas son las familias que más se usan.
### Vacío y nulos [#vacío-y-nulos]
Un test de vacío/nulo unificado para strings, colecciones, fechas, GUIDs y tipos propios.
* `IsEmpty()`, `IsNotEmpty()`, `HasContent()`: sobre `String`, `List`, `Dictionary`, `IEnumerable`, `Guid`, fechas anulables.
* `IsNull()`, `IsNotNull()`, `NotEmpty()`: sobre `Guid` y `Object`.
* `OrEmpty()`: devuelve una secuencia vacía si el origen es `null` (para iterar sin comprobar).
* `IfIsEmpty(valor)`: coalescencia a un valor por defecto para números y fechas.
```csharp
if (report.Rows.IsNotEmpty()) { /* ... */ }
foreach (var x in lista.OrEmpty()) { /* nunca NullReference */ }
```
### Predicados de string [#predicados-de-string]
Validación y coincidencia sobre texto.
* `IsEmail()`, `IsGUID()`, `IsNumeric()`, `IsInteger()`, `IsJson()`, `IsDateOnly()`.
* `ContainsWord()`, `ContainsIgnoreCase()`, `EqualsIgnoreCase()`, `StartsWithIgnoreCase()`, `EndsWithIgnoreCase()`.
* `MatchAllWords()`, `MatchPercentage()`, `ContainsWebSearchMode()`: búsqueda por palabras al estilo buscador.
### LikeM (comparación múltiple) [#likem-comparación-múltiple]
Atajo para "¿el valor es igual a alguno de estos?". Elimina los OR anidados. Hay sobrecargas para `Integer`, `Decimal`, `Guid`, `Char` y `String`.
```csharp
if (estado.LikeM(1, 2, 5)) { /* 1, 2 o 5 */ }
if (letra.LikeMIgnoreCase("A", "B", "C")) { /* ... */ }
```
### Guardas de argumentos (ThrowIf\_) [#guardas-de-argumentos-throwif_]
Cláusulas de guarda que lanzan una excepción descriptiva si el argumento no cumple.
* `ThrowIf_IsNull()`, `ThrowIf_IsEmpty()`: sobre `String`, colecciones, `Guid`, números, fechas.
* `ThrowIf_IsNotGuid()`, `ThrowIf_IsNotEmail()`, `ThrowIf_IsNotUrl()`, `ThrowIf_IsZero()`.
```csharp
email.ThrowIf_IsNotEmail(nameof(email));
sectionId.ThrowIf_IsEmpty(nameof(sectionId));
```
### Colecciones [#colecciones]
* `GetM(i)`: indexado seguro, devuelve el valor por defecto si el índice se sale, en vez de lanzar.
* `HasElements()`, `HasContent()`: presencia sobre arrays, listas y diccionarios.
* `GetRandom()`, `MoveItemUp()`, `MoveItemDown()`, `AddRange()` sobre `HashSet`.
### Transformación y numéricas [#transformación-y-numéricas]
* String: `RemoveAccents()`, `RemoveSpecialCharacters()`, `UppercaseFirst()`, `ParseBetween()`, `Trim_PN()` (trim seguro con nulos), `FormatJson()`.
* Numéricas: `Between(min, max)`, `IsMultipleOf()`, `RoundMoney(decimales)`, `Half()`, `HasDecimalPlaces()`.
Estas listas son representativas, no exhaustivas: el módulo trae muchas más. Los nombres citados existen en el código; explora por IntelliSense sobre el tipo que estés usando.
# Vault (/docs/desarrollo/dotnet/sdk/vault)
`VaultData`, en el paquete `Dinaup`, resuelve el problema de dónde guardar secretos (credenciales, endpoints, claves). El único dato en el entorno es la **URL** del almacén cifrado y la **contraseña** que lo descifra. Todo lo demás viaja cifrado y se lee en memoria.
```csharp
using Dinaup;
```
## Cómo funciona [#cómo-funciona]
`VaultData` descarga un JSON cifrado (AES-CBC) de una URL, lo descifra con la contraseña y expone cada clave con `Read`. La URL y la contraseña se pasan como valores directos o como **nombres de variables de entorno**: el constructor las resuelve buscando en el entorno (máquina, proceso y usuario, con fallback al prefijo `dup_`).
```csharp
// Los nombres de las variables de entorno con la URL y la contraseña.
var vault = new VaultData("VAULT_URL", "VAULT_PASSWORD");
vault.Initialize();
// A partir de aquí, todo sale del vault descifrado.
string endpoint = vault.Read("dinaup.endpoint");
string publicKey = vault.Read("dinaup.publickey");
string secretKey = vault.Read("dinaup.secretkey");
```
`Read` devuelve una cadena vacía si la clave no existe. El diccionario `Parameters` ignora mayúsculas y minúsculas.
## Conectar Dinaup desde el vault [#conectar-dinaup-desde-el-vault]
El caso típico: arrancar el cliente Dinaup sin credenciales en el código.
```csharp
var vault = new VaultData(
Environment.GetEnvironmentVariable("VAULT_URL"),
Environment.GetEnvironmentVariable("VAULT_PASSWORD")
);
vault.Initialize();
var client = await DinaupClientC.ConnectAsync(
endPoint: vault.Read("dinaup.endpoint"),
publicKey: vault.Read("dinaup.publickey"),
secretKey: vault.Read("dinaup.secretkey")
);
```
## Otras entradas [#otras-entradas]
* **`Initialize(url, pass)`**: inicializa con la URL y la contraseña ya resueltas, sin pasar por variables de entorno.
* **`Initialize()` desde archivo local**: si construyes con `new VaultData(args)` y uno de los argumentos es la ruta de un `.json`, `Initialize()` lo lee. El archivo debe traer `endpoint` (empieza por `http`) y `pass` (mínimo 4 caracteres); con eso descarga y descifra el vault remoto.
* **`EnableEnvironmentVariableForConsole(nombre)`**: en apps de consola, pide la ruta del JSON por terminal y la guarda en la variable de entorno indicada si no estaba.
* **`HealthCheck()`**: descarga y descifra el vault y devuelve `true` si trae al menos una clave. Para un health-check de arranque.
El vault es de solo lectura desde el SDK: se descarga y descifra, no se escribe. Generar y publicar el blob cifrado es un paso previo fuera de esta librería.
# Buenas prácticas de DinaScript (/docs/desarrollo/flex/dinascript/buenas-practicas)
Cómo escribir DinaScript legible y rápido: nombres, condiciones, carga de datos y diseño de algoritmos. La referencia completa de cada función está en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Nombres y comentarios [#nombres-y-comentarios]
* **El nombre de la variable cuenta qué contiene.** `txt nombreCliente` se entiende solo; `txt x` obliga a leer el resto del script para saber qué es.
* **El comentario `@` cuenta por qué.** Documenta la regla de negocio, no lo que ya dice la línea. Un `@ suma 1` no aporta; un `@ los pedidos anulados no computan` evita un error futuro.
* **Elige el tipo de script adecuado al trabajo**: Terminal para la interfaz, Algoritmo para cálculos, Plantilla de impresión para documentos, Función API para lógica de servidor. Ver [scripts y eventos](/docs/desarrollo/flex/scripts).
* **Un script, una responsabilidad.** Si crece demasiado, separa la lógica en scripts pequeños y encadénalos con `F.ExecuteScript`.
```javascript
@ Los pedidos de más de 3.000 € llevan descuento por volumen
num umbralDescuento = 3000
¿v.totalPedido > v.umbralDescuento ? v.descuento = 5
```
## Condiciones legibles [#condiciones-legibles]
El if en línea `¿condición ? acción` y el bloque `if` / `end` hacen lo mismo; la diferencia es cuánto cabe dentro.
* **En línea** cuando hay una condición y una sola acción. Una línea, un vistazo.
* **Bloque** cuando hay varias acciones, ramas `else` o `elseif`, o lógica anidada. Estirar un if en línea con acciones encadenadas se vuelve ilegible enseguida.
```javascript
if v.totalPedido > v.umbralDescuento
v.descuento = 5
v.avisoCliente = "Descuento por volumen aplicado"
else
v.descuento = 0
end
```
Escribe las condiciones en positivo cuando puedas y compara con valores con nombre (`v.umbralDescuento`), no con números sueltos repartidos por el script.
## Valida antes de operar [#valida-antes-de-operar]
DinaScript no tiene try/catch: si una operación falla a mitad de script, no hay red de seguridad. La defensa es comprobar antes con un `if`, sobre todo los valores que vienen del usuario o de campos que pueden estar vacíos.
```javascript
@ Comprueba antes de usar: no hay manejo de errores después
¿F.IsEmpty_Text(v.emailCliente) = 1 ? v.error = "Falta el email del cliente"
```
Las funciones `IsEmpty_*` e `IsNotEmpty_*` cubren texto, fecha, hora y fecha-hora. Están en [lógica y comparación](/docs/desarrollo/flex/dinascript/funciones/logica-y-comparacion).
## Rendimiento: carga lo justo [#rendimiento-carga-lo-justo]
Cargar un listado es un viaje a la base de datos. La regla: que viajen las filas que necesitas, no todas.
* **Filtra en la carga, no en el bucle.** Un `F.DataListLoadAddFilter` recorta la consulta antes de traer datos. Un `if` dentro del recorrido trae toda la sección y descarta filas ya cargadas.
* **Pagina con cabeza.** El tercer parámetro de `F.DataListLoad` limita cuántos resultados llegan. Pide 200 si vas a usar 200.
* **No cargues listados dentro de un recorrido.** Un `F.DataListLoad` dentro de un bloque `F.ProcessDataList_Ini` … `F.ProcessDataList_End` es un viaje a la base de datos por cada fila. Si necesitas cruzar datos, replantea: casi siempre lo resuelve un informe con las columnas ya cruzadas o un algoritmo.
* **Guarda en variable lo que leas varias veces.** Leer un campo o llamar a la misma función en cada vuelta del bucle repite trabajo; asígnalo una vez antes de entrar.
* **Los totales son de los algoritmos.** Para sumar, contar o promediar registros no recorras un listado en un script: un algoritmo con `F.Aggregate_Sum`, `F.Aggregate_Count` o `F.Aggregate_Average` compila a SQL y calcula donde viven los datos.
```javascript
@ El filtro viaja en la consulta: llegan solo los pedidos pendientes
F.DataListLoad(v.listadoPedidos, 1, 200)
F.DataListLoadAddFilter(v.listadoPedidos, "estado", "=", "pendiente")
```
## Algoritmos: el tipo más simple que cubra el cálculo [#algoritmos-el-tipo-más-simple-que-cubra-el-cálculo]
Cada [tipo de algoritmo](/docs/desarrollo/flex/algoritmos) opera sobre un alcance distinto, y el coste crece con el alcance:
* **Lineal**: el cálculo vive en la propia fila y sus relaciones directas. El más barato; tu primera opción para campos auto-calculados.
* **Cruzado**: resume registros relacionados en un valor (la factura que suma sus líneas). Cada cruce adicional encarece la consulta: no cruces lo que puedas leer con un Lineal.
* **Búsqueda**: resuelve el `id` de un registro de otra sección a partir de un filtro.
* **Datos**: agregado global de una sección, para dashboards e informes.
* **Independiente**: valores de sesión o composición de otros algoritmos, sin contexto de fila.
Recorta pronto: el **prefiltrado** y los filtrados de izquierda y derecha reducen las filas antes de agregar. Filtrar después de traer todo es pagar la consulta grande para quedarte con el resultado pequeño. Las partes del algoritmo están explicadas en [algoritmos](/docs/desarrollo/flex/algoritmos).
## Recálculo automático y cadenas [#recálculo-automático-y-cadenas]
Un campo auto-calculado no se refresca solo por arte de magia. Su algoritmo se recalcula cuando:
1. Se **guarda o borra un registro** de la sección origen.
2. Un administrador lanza un **recálculo masivo**.
3. Lo dispara una **tarea programada**.
4. Cambia el resultado de **otro algoritmo del que depende**.
El sistema ordena la ejecución por dependencias y detecta los ciclos: un algoritmo no puede depender, directa o indirectamente, de su propio resultado.
Un algoritmo pesado enganchado a un campo auto-calculado se paga en **cada guardado** de la sección origen. Y una cadena larga de algoritmos convierte un guardado en una cascada de recálculos. Si guardar se vuelve lento, mira ahí primero: acorta la cadena o acota con filtros.
Encadenar algoritmos es legítimo para construir cálculos por etapas, pero mantén las cadenas cortas y con un propósito claro por eslabón.
## Límites del lenguaje [#límites-del-lenguaje]
| Límite | Qué implica al escribir |
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
| Sin recursión | Un script no puede llamarse a sí mismo, ni directamente ni a través de una cadena de `F.ExecuteScript`. |
| Sin funciones propias | Todas las funciones son las integradas del espacio `F.`. Para reutilizar lógica, sepárala en otro script. |
| Ejecución línea a línea | No hay expresiones multilínea: cada instrucción completa en su línea. |
| Sin try/catch | No existe manejo de excepciones. Protege las operaciones delicadas con comprobaciones previas. |
| Ejecución síncrona | Las instrucciones corren una tras otra; un paso lento retrasa todo lo que viene después. |
| Indiferente a mayúsculas | `F.Round` y `f.round` son la misma función. Usa la grafía de la referencia para poder buscarla. |
| Palabras clave bilingües | `if` y `si` valen igual. Elige una y no las mezcles en el mismo script. |
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
→ [Scripts y eventos](/docs/desarrollo/flex/scripts)
# C.: el registro del formulario (/docs/desarrollo/flex/dinascript/c.-registro-del-formulario)
`I.` lee el registro que recorres en un listado. `C.` va un paso más allá: apunta al **registro abierto en el formulario** y, además de leerlo, **lo escribe**. Es el prefijo central de los [scripts de formulario y de campo](/docs/desarrollo/flex/scripts): casi todo script que reacciona a lo que hace el usuario lee o asigna algo con `C.`.
`C.` solo existe donde hay un formulario abierto: scripts de formulario y de campo del Terminal. En una fórmula de algoritmo o en un script independiente no hay "registro actual en edición", y da error de contexto. Ahí usa [`I.` o `D.`](/docs/desarrollo/flex/dinascript/i.-d.-a.-otros-espacios-de-nombre).
## Leer y escribir campos [#leer-y-escribir-campos]
`C.Campo` devuelve el valor actual del campo, con los cambios que el usuario aún no ha guardado. Asignarlo lo cambia en el formulario, como si el usuario lo hubiera tecleado:
```javascript
@ El título de la tarea se compone solo: clave + resumen
C.TextoPrincipal = F.Concat(C.Clave, ' ', C.Resumen)
```
Los nombres de campo son los de tu esquema, los mismos que ves en `S.Fields.Seccion.Campo`. La diferencia: `S.` te da la **referencia** del campo (su ID, para pasarlo a funciones) y `C.` te da su **valor**.
`C.ID` devuelve el identificador del propio registro. Es lo que pasas cuando creas un registro relacionado que debe apuntar al actual:
```javascript
F.AddElement_SetValue(S.Fields.TareasDeProyectos.ReferenciaTarea.ID, C.ID)
```
Un registro recién iniciado todavía no existe en el servidor. Si el script va a usar `C.ID` para relacionar otros registros, guarda antes con `F.Save()`. Compruébalo con `F.IsNew()` si lo necesitas.
## Leer a través de una relación [#leer-a-través-de-una-relación]
Cuando el campo es una **relación**, `C.` no se queda en el ID: encadena con punto y lee campos de la ficha relacionada.
```javascript
@ Condiciones de pago definidas en la ficha del cliente seleccionado
txt condiciones = C.ReferenciaCliente.CondicionesPagoVenta
num dias = C.ReferenciaCliente.PlazoDiasCobroVentas
```
El encadenado admite más de un salto. Aquí el script salta del registro al proyecto, del proyecto a su flujo y del flujo a su tipo por defecto:
```javascript
C.ReferenciaTipo = F.GetRowById(S.Sections.TiposDeTareaDeProyectos.ID, C.ReferenciaProyecto.ReferenciaFlujo.ReferenciaTipo)
```
## Asignar una relación [#asignar-una-relación]
Un campo de relación acepta cualquier expresión que devuelva un identificador de registro:
| Origen | Ejemplo |
| -------------------------- | ------------------------------------------------------------------------------------------------ |
| Otro campo de relación | `C.ReferenciaNumeracionSerie = C.ReferenciaTipoDeVenta.ReferenciaNumeracionOrdinarias` |
| Un registro buscado por ID | `C.ReferenciaBono = F.GetRowById(S.Sections.BonosHoras.ID, C.ReferenciaProyecto.ReferenciaBono)` |
| Vaciarla | `C.ReferenciaProducto = ''` |
Una relación sin valor es **cadena vacía**, no un nulo. La comprobación canónica es contra `''`:
```javascript
if C.ReferenciaCliente <> ''
C.CondicionesDePago = C.ReferenciaCliente.CondicionesPagoVenta
end if
```
## Comparar con enumeraciones [#comparar-con-enumeraciones]
Los campos de tipo lista se comparan contra `S.Enums`, nunca contra números sueltos:
```javascript
if C.TipoFactura = S.Enums.tipofactura.rectificativo
C.ReferenciaNumeracionSerie = C.ReferenciaTipoDeVenta.ReferenciaNumeracionRectificativas
end if
```
El encadenado también funciona aquí: `C.ReferenciaEstado.EstadoTarea = S.Enums.tareaestado.enproceso` lee el enum de la ficha de estado relacionada y lo compara.
## Desde una línea, el formulario que la contiene [#desde-una-línea-el-formulario-que-la-contiene]
En las **secciones de lista** (las líneas de una factura, de un pedido, de un presupuesto), el script de la línea puede subir a su registro contenedor con `C.RelacionElementoContenedorListador`:
```javascript
@ La línea hereda la categoría general indicada en la factura
if C.RelacionElementoContenedorListador.ReferenciaCategoriaGeneral <> ''
C.ReferenciaCategoriaDeVenta = C.RelacionElementoContenedorListador.ReferenciaCategoriaGeneral
end if
```
Es la vía para que las líneas hereden valores del documento (categoría, impuesto, configuración) sin que el usuario los repita línea a línea.
## C. frente a los demás prefijos [#c-frente-a-los-demás-prefijos]
| Prefijo | Apunta a | Escribe |
| ------- | -------------------------------------- | ------- |
| `C.` | El registro abierto en el formulario | Sí |
| `I.` | El registro que recorres en un listado | No |
| `D.` | Usuario, empresa, fecha y sistema | No |
| `V.` | Variables del script | Sí |
Existe también `R.`, que apunta a la sección relacionada en scripts de campos personales. Es un caso minoritario: si estás empezando, todo lo que necesitas está en `C.`.
***
→ [Recetas de scripts](/docs/desarrollo/flex/dinascript/recetas-de-scripts)
→ [Scripts y eventos](/docs/desarrollo/flex/scripts)
→ [Esquema (S.)](/docs/desarrollo/flex/dinascript/s.-espacio-de-nombre-schema)
→ [Espacios I., D. y A.](/docs/desarrollo/flex/dinascript/i.-d.-a.-otros-espacios-de-nombre)
→ [Funciones (F.)](/docs/desarrollo/flex/dinascript/funciones)
# Espacios I., D. y A. (/docs/desarrollo/flex/dinascript/i.-d.-a.-otros-espacios-de-nombre)
La página del esquema (`S.`) te dice qué secciones y campos existen. Los prefijos `I.`, `D.` y `A.` van un paso más allá: durante la ejecución del script devuelven el **valor real**.
* `I.` es el valor del registro que estás recorriendo ahora.
* `D.` son los datos del entorno: usuario, empresa, fecha y sistema.
* `A.` es el resultado de ejecutar un algoritmo.
Los tres usan la misma sintaxis punteada, de lo general a lo concreto, igual que `S.`.
## I.: el registro actual [#i-el-registro-actual]
`I.` lee un campo del registro que recorres en ese momento. Tiene dos formas:
| Forma | Devuelve |
| ------------------- | ------------------------------------------------ |
| `I.Seccion.Campo` | Un campo del registro de la lista que recorres. |
| `I.Informe.Columna` | Una columna de la fila del informe que recorres. |
También admite `I.Seccion.Algoritmo...` para leer un algoritmo sobre el registro actual.
`I.` solo funciona dentro de un bloque de recorrido de listado (`F.ProcessDataList_Ini` / `F.ProcessDataList_End`) o del bloque de listado de una función API. En un algoritmo suelto da error de contexto: no hay "registro actual" que recorrer.
Donde `S.` te da la referencia del campo, `I.` te da su valor. Ejemplos reales:
```
I.Ventas.Cliente
I.Productos.Nombre
I.Productos.Stock
```
## D.: datos del sistema y del entorno [#d-datos-del-sistema-y-del-entorno]
`D.` reúne todo lo que no depende del registro sino del contexto de ejecución. Tiene cuatro subespacios.
| Subespacio | Devuelve |
| ---------------------------------------------- | ---------------------------------------------------- |
| `D.SesionActual.` | Datos de la ficha del usuario que ejecuta el script. |
| `D.EmpresaActual.` | Datos de la empresa actual. |
| `D.DatosEspeciales.` | Fecha, hora y datos del sistema. |
| `D.AlgoritmosDeBusqueda..` | Algoritmos de búsqueda (solo en algoritmos). |
`D.SesionActual` y `D.EmpresaActual` sirven para personalizar el resultado y dejar constancia de quién y qué empresa ejecuta.
### D.DatosEspeciales [#ddatosespeciales]
Fecha, hora y datos del sistema disponibles en cualquier script. Las claves más usadas:
| Clave | Tipo | Devuelve |
| --------------------------------------- | ------------ | ------------------------- |
| `D.DatosEspeciales.FechaActual` | fecha | La fecha de hoy. |
| `D.DatosEspeciales.FechaYHoraActual` | fecha y hora | Fecha y hora del momento. |
| `D.DatosEspeciales.HoraActual` | hora | La hora actual. |
| `D.DatosEspeciales.DiaActual` | entero | Día del mes. |
| `D.DatosEspeciales.MesActual` | entero | Número de mes. |
| `D.DatosEspeciales.MesActualNombre` | texto | Nombre del mes. |
| `D.DatosEspeciales.AñoActual` | entero | Año actual. |
| `D.DatosEspeciales.TrimestreActual` | entero | Trimestre en curso. |
| `D.DatosEspeciales.SemestreActual` | entero | Semestre en curso. |
| `D.DatosEspeciales.SemanaActual` | entero | Semana del año. |
| `D.DatosEspeciales.DiaDeLaSemanaActual` | texto | Día de la semana. |
| `D.DatosEspeciales.Sistema.Version` | texto | Versión del sistema. |
Los nombres van en español tal cual, incluida la `ñ` de `AñoActual`.
También hay familias para fechas relativas, `FechasAvanzadas.Inicios.*` y `FechasAvanzadas.Finales.*`, que resuelven límites de periodo:
```
D.DatosEspeciales.FechasAvanzadas.Inicios.InicioDeMes
D.DatosEspeciales.FechasAvanzadas.Finales.FinDeMes
```
### D.AlgoritmosDeBusqueda [#dalgoritmosdebusqueda]
Solo está disponible dentro de scripts de tipo algoritmo. Se usa junto al operador `en` para filtrar o buscar:
```
... en D.AlgoritmosDeBusqueda.Categoria.KeyWord
```
## A.: ejecutar un algoritmo y leer su valor [#a-ejecutar-un-algoritmo-y-leer-su-valor]
`A..` ejecuta un algoritmo de tipo Cálculo o Dato y devuelve su resultado como un valor que puedes usar en el script.
```
A.Categoria.NombreAlgoritmo
```
El formato del dato devuelto lo define el propio algoritmo: número, texto, fecha o relación.
No confundas `A.` con `D.AlgoritmosDeBusqueda`. `A.` **lee un valor calculado**. Los algoritmos de búsqueda se usan con el operador `en` para filtrar dentro de otro algoritmo.
Aquí solo documentamos cómo invocar un algoritmo desde DinaScript. Para saber qué es un algoritmo y cómo se define, ve a la página de Algoritmos.
## Prefijos reservados [#prefijos-reservados]
Existen otros prefijos en el motor, pero hoy no aportan y no debes usarlos:
* `P.`, `L.` y `G.` están reservados. Se reconocen, pero no están operativos todavía.
* `C.` y `R.` leen y escriben el registro abierto en el formulario (`C.` sección principal, `R.` sección relacionada). Tienen su propia página: [C.: el registro del formulario](/docs/desarrollo/flex/dinascript/c.-registro-del-formulario).
## Relacionado [#relacionado]
→ [Esquema (S.)](/docs/desarrollo/flex/dinascript/s.-espacio-de-nombre-schema)
→ [DinaScript](/docs/desarrollo/flex/dinascript)
→ [Funciones (F.)](/docs/desarrollo/flex/dinascript/funciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
→ [Informes](/docs/desarrollo/flex/informes)
→ [Secciones](/docs/desarrollo/flex/secciones)
# DinaScript (/docs/desarrollo/flex/dinascript)
Con DinaScript escribes la lógica que ejecutan los **algoritmos**, los **scripts** y los **documentos dinámicos** de Flex. Cubre desde operaciones básicas hasta integraciones con APIs externas.
### Conceptos Fundamentales [#conceptos-fundamentales]
#### 1. Espacios de Nombres (Namespaces) [#1-espacios-de-nombres-namespaces]
DinaScript organiza sus funciones en **espacios de nombres** que agrupan funcionalidades relacionadas:
* **`F.`** - [Funciones generales](/docs/desarrollo/flex/dinascript/funciones) (manipulación de datos, fechas, texto, etc.)
* **`S.`** - [Sistema](/docs/desarrollo/flex/dinascript/s.-espacio-de-nombre-schema) (acceso a metadatos y configuración de Dinaup)
* **`C.`** - [Registro del formulario](/docs/desarrollo/flex/dinascript/c.-registro-del-formulario) (leer y escribir el registro abierto, en scripts de formulario)
* **`I.`** - [Iterador](/docs/desarrollo/flex/dinascript/i.-d.-a.-otros-espacios-de-nombre) (datos del registro actual en procesamiento)
* **`D.`** - [Datos globales del sistema](/docs/desarrollo/flex/dinascript/i.-d.-a.-otros-espacios-de-nombre)
* **`V.`** - Variables locales o globales del script
* **`A.`** - [Opciones avanzadas de algoritmos](/docs/desarrollo/flex/dinascript/i.-d.-a.-otros-espacios-de-nombre)
## Sintaxis de DinaScript [#sintaxis-de-dinascript]
### Declaración de Variables [#declaración-de-variables]
#### Tipos de Variables (Solo 2 tipos) [#tipos-de-variables-solo-2-tipos]
```javascript
// TEXTO (txt) - Para todo tipo de cadenas, fechas, booleanos, GUIDs
txt nombre = "Juan"
txt apellido = 'García'
txt vacio = ""
txt fecha = "2024-12-25" // Fechas como texto
txt guid = "550e8400-e29b-41d4-a716-446655440000"
// NÚMERO (num) - Para enteros y decimales
num entero = 42
num decimal = 3.14159
num negativo = -10
num cero = 0
num booleano = 1 // 1 = true, 0 = false
```
#### Variables del Sistema [#variables-del-sistema]
```javascript
// v. = Variables locales (las que tú creas)
txt miTexto = "Hola"
num miNumero = 100
// I. = Iterador (datos del registro actual en un bucle)
txt clienteNombre = I.Clientes.Nombre
num clienteSaldo = I.Clientes.Saldo
```
### Operadores [#operadores]
#### Operadores Aritméticos [#operadores-aritméticos]
```javascript
num suma = 10 + 5 // 15
num resta = 10 - 5 // 5
num multiplicacion = 10 * 5 // 50
num division = 10 / 5 // 2
num modulo = 10 % 3 // 1 (resto)
// Operaciones combinadas
num resultado = (10 + 5) * 2 - 3 // 27
```
#### Operadores de Comparación [#operadores-de-comparación]
```javascript
// Igual
if v.edad = 18 // Igual a
if v.nombre == "Juan" // También funciona
// Diferente
if v.edad <> 18 // Diferente de
if v.nombre != "Juan" // También funciona
// Mayor y menor (solo con números)
if v.edad > 18 // Mayor que
if v.edad >= 18 // Mayor o igual que
if v.edad < 18 // Menor que
if v.edad <= 18 // Menor o igual que
// Comparación de texto
if v.estado = "activo"
if v.estado <> "" // No vacío
```
#### Operadores Lógicos [#operadores-lógicos]
```javascript
// AND - Todas las condiciones deben ser verdaderas
if v.edad >= 18 and v.tieneLicencia = 1
F.Write("Puede conducir")
end if
// OR - Al menos una condición debe ser verdadera
if v.dia = "sábado" or v.dia = "domingo"
F.Write("Es fin de semana")
end if
```
### Estructuras de Control [#estructuras-de-control]
#### IF Simple [#if-simple]
```javascript
if v.temperatura > 30
F.Write("Hace calor")
end if
```
#### IF-ELSE [#if-else]
```javascript
if v.edad >= 18
F.Write("Mayor de edad")
else
F.Write("Menor de edad")
end if
```
#### IF-ELSEIF-ELSE [#if-elseif-else]
```javascript
if v.nota >= 9
F.Write("Sobresaliente")
elseif v.nota >= 7
F.Write("Notable")
elseif v.nota >= 5
F.Write("Aprobado")
else
F.Write("Suspenso")
end if
```
#### IF Anidados [#if-anidados]
```javascript
txt tipoPlan = "premium"
num esMiembro = 1
if v.esMiembro = 1
if v.tipoPlan = "premium"
F.Write("Acceso completo")
elseif v.tipoPlan = "basico"
F.Write("Acceso limitado")
else
F.Write("Plan no válido")
end if
else
F.Write("No es miembro")
end if
```
### Bucles y Procesamiento [#bucles-y-procesamiento]
#### ProcessDataList (bucle sobre registros) [#processdatalist-bucle-sobre-registros]
```javascript
F.DataListLoad(S.Sections.Productos.ID, 1, 999999)
F.DataListLoadAddFilter(S.Sections.Productos.ID, S.Fields.Productos.Activo.ID, '=', 1)
num totalProductos = 0
num productosConBajoStock = 0
F.ProcessDataList_Ini(S.Sections.Productos.ID)
v.totalProductos = v.totalProductos + 1
// Verificar stock
if I.Productos.Stock < 10 and I.Productos.Importante = 1
F.Write(F.Concat("ALERTA: ", I.Productos.Nombre, " bajo stock"))
v.productosConBajoStock = v.productosConBajoStock + 1
elseif I.Productos.Stock = 0
F.Write(F.Concat("SIN STOCK: ", I.Productos.Nombre))
end if
F.ProcessDataList_End
```
### Trabajar con texto [#trabajar-con-texto]
#### Concatenación [#concatenación]
```javascript
// Usando F.Concat
txt nombre = "Juan"
txt apellido = "García"
txt mensaje = F.Concat("Hola ", v.nombre, " ", v.apellido)
// Concatenación múltiple
txt calle = "Gran Vía"
txt numero = "123"
txt ciudad = "Madrid"
txt codigoPostal = "28001"
txt direccion = F.Concat4(v.calle, " ", v.numero, ", ", v.ciudad, " ", v.codigoPostal)
// Con condiciones
num hora = 14
txt saludo = ""
if v.hora < 12
v.saludo = F.Concat("Buenos días, ", v.nombre)
elseif v.hora < 20
v.saludo = F.Concat("Buenas tardes, ", v.nombre)
else
v.saludo = F.Concat("Buenas noches, ", v.nombre)
end if
```
#### Comparación de Texto [#comparación-de-texto]
```javascript
// Comparación exacta
txt nombre = "Juan"
if v.nombre = "Juan"
F.Write("Es Juan")
end if
// Verificar si está vacío
txt email = ""
if v.email = ""
F.Write("Email no proporcionado")
end if
if v.email <> ""
F.Write("Email proporcionado")
end if
// Contiene texto (usando función)
txt descripcion = "Tarea urgente para hoy"
if F.Contains(v.descripcion, "urgente")
F.Write("Tarea prioritaria")
end if
// Empieza o termina con
txt codigo = "ES12345"
if F.StartsWith(v.codigo, "ES")
F.Write("Código español")
end if
txt archivo = "documento.pdf"
if F.EndsWith(v.archivo, ".pdf")
F.Write("Es un PDF")
end if
```
### Trabajar con números [#trabajar-con-números]
#### Comparaciones y Rangos [#comparaciones-y-rangos]
```javascript
num edad = 25
// Verificar rangos
if v.edad >= 0 and v.edad <= 17
F.Write("Menor de edad")
elseif v.edad >= 18 and v.edad <= 65
F.Write("Adulto")
elseif v.edad > 65
F.Write("Tercera edad")
end if
// Validar valores
num precio = 100
num descuento = 15
num precioFinal = 0
if v.precio > 0
if v.descuento >= 0 and v.descuento <= 100
v.precioFinal = v.precio * (1 - v.descuento/100)
else
F.Write("Descuento no válido")
end if
else
F.Write("Precio no válido")
end if
```
#### Trabajar con booleanos (como números) [#trabajar-con-booleanos-como-números]
```javascript
// true = 1, false = 0
num activo = 1
num verificado = 0
num tieneLicencia = 1
// Verificación simple
if v.activo = 1
F.Write("Usuario activo")
end if
// Múltiples verificaciones
if v.activo = 1 and v.verificado = 1
F.Write("Usuario activo y verificado")
end if
// Toggle (cambiar estado)
v.activo = 1 - v.activo // Si era 1 pasa a 0, si era 0 pasa a 1
// Contador de condiciones verdaderas
num condicionesCumplidas = v.activo + v.verificado + v.tieneLicencia
if v.condicionesCumplidas >= 2
F.Write("Al menos 2 condiciones cumplidas")
end if
```
### Trabajar con fechas (como texto) [#trabajar-con-fechas-como-texto]
#### Comparación de Fechas [#comparación-de-fechas]
```javascript
// Las fechas se manejan como texto o mediante funciones F.
txt fechaHoy = F.Cast_DateToText(D.DatosEspeciales.FechaActual)
txt fechaVencimiento = "2024-12-31"
// Para comparar fechas, usar funciones F.
num diasDiferencia = F.DaysDifferenceBetweenDates(D.DatosEspeciales.FechaActual, v.fechaVencimiento)
if v.diasDiferencia < 0
F.Write("Vencido")
elseif v.diasDiferencia = 0
F.Write("Vence hoy")
elseif v.diasDiferencia <= 7
F.Write("Vence esta semana")
else
F.Write(F.Concat("Vence en ", F.Cast_NumToText(v.diasDiferencia), " días"))
end if
```
### Manejo de Valores Vacíos/Cero [#manejo-de-valores-vacíoscero]
#### Verificación de Valores [#verificación-de-valores]
```javascript
// Texto vacío
txt nombre = ""
if v.nombre = ""
v.nombre = "Sin nombre"
end if
// Número cero
num cantidad = 0
if v.cantidad = 0
F.Write("Cantidad no especificada")
end if
// Booleano (como número)
num activo = 0
if v.activo = 0
v.activo = 1 // Activar por defecto
end if
// Verificación múltiple
txt valor1 = ""
txt valor2 = "algo"
num tieneValores = 0
if v.valor1 <> "" or v.valor2 <> ""
v.tieneValores = 1
end if
```
### Patrones Comunes [#patrones-comunes]
#### Validación de Formulario [#validación-de-formulario]
```javascript
num formularioValido = 1
txt errores = ""
txt nombre = ""
txt email = "test@test"
num edad = 15
if v.nombre = ""
v.formularioValido = 0
v.errores = F.Concat(v.errores, "- Nombre requerido\n")
end if
if v.email = "" or not F.Contains(v.email, "@")
v.formularioValido = 0
v.errores = F.Concat(v.errores, "- Email inválido\n")
end if
if v.edad < 18 or v.edad > 120
v.formularioValido = 0
v.errores = F.Concat(v.errores, "- Edad fuera de rango\n")
end if
if v.formularioValido = 1
F.Write("Formulario enviado correctamente")
else
F.Write(F.Concat("Errores encontrados:\n", v.errores))
end if
```
#### Switch-like con IF [#switch-like-con-if]
```javascript
txt dia = "lunes"
txt tipo = ""
if v.dia = "lunes" or v.dia = "martes" or v.dia = "miércoles" or v.dia = "jueves" or v.dia = "viernes"
v.tipo = "laborable"
elseif v.dia = "sábado" or v.dia = "domingo"
v.tipo = "fin de semana"
else
v.tipo = "día no válido"
end if
```
#### Conversión entre Tipos [#conversión-entre-tipos]
```javascript
// Número a Texto
num cantidad = 42
txt cantidadTexto = F.Cast_NumToText(v.cantidad)
// Texto a Número
txt precio = "99.99"
num precioNum = F.Cast_TextToNum(v.precio)
// Booleano como número
num estaActivo = 1
txt estadoTexto = ""
if v.estaActivo = 1
v.estadoTexto = "Activo"
else
v.estadoTexto = "Inactivo"
end if
```
#### Cálculo con Condiciones [#cálculo-con-condiciones]
```javascript
// Sistema de puntos con múltiples criterios
num puntoBase = 100
num multiplicador = 1
txt categoria = "oro"
num esNuevoCliente = 0
num comprasEsteMes = 5
// Multiplicador por categoría
if v.categoria = "bronce"
v.multiplicador = 1
elseif v.categoria = "plata"
v.multiplicador = 1.5
elseif v.categoria = "oro"
v.multiplicador = 2
elseif v.categoria = "platino"
v.multiplicador = 3
end if
// Bonus adicionales
num bonus = 0
if v.esNuevoCliente = 1
v.bonus = v.bonus + 50
end if
if v.comprasEsteMes >= 5
v.bonus = v.bonus + 100
elseif v.comprasEsteMes >= 3
v.bonus = v.bonus + 50
end if
// Cálculo final
num puntosFinales = (v.puntoBase * v.multiplicador) + v.bonus
```
#### Control de Flujo con Flags [#control-de-flujo-con-flags]
```javascript
// Usar números como banderas (flags)
num continuar = 1
num error = 0
txt mensajeError = ""
// Validación paso a paso
txt codigoProducto = "PRD123"
num stock = 5
num cantidadSolicitada = 10
if v.codigoProducto = ""
v.error = 1
v.mensajeError = "Código de producto vacío"
v.continuar = 0
end if
if v.continuar = 1 and v.stock < v.cantidadSolicitada
v.error = 1
v.mensajeError = "Stock insuficiente"
v.continuar = 0
end if
if v.continuar = 1
F.Write("Pedido procesado correctamente")
else
F.Write(F.Concat("Error: ", v.mensajeError))
end if
```
### Notas Importantes sobre Variables [#notas-importantes-sobre-variables]
1. **Solo existen `txt` y `num`** - Todo lo demás se maneja con estas dos
2. **Booleanos son números** - `1` = true, `0` = false
3. **Fechas son texto** - Usar funciones F. para manipularlas
4. **GUIDs son texto** - Se almacenan como cadenas
5. **No hay arrays nativos** - Usar DataTables para colecciones
6. **Variables siempre con prefijo** - `v.` para locales, `I.` para iterador
7. **Conversión explícita** - Usar F.Cast\_\* para convertir entre tipos
# Recetas de scripts (/docs/desarrollo/flex/dinascript/recetas-de-scripts)
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](/docs/desarrollo/flex/scripts); la sintaxis de `C.` en [el registro del formulario](/docs/desarrollo/flex/dinascript/c.-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 [#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.
```javascript
@ 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 [#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.
```javascript
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](/docs/desarrollo/flex/campos#autorrellenado) 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 [#derivar-campos-cuando-cambia-el-estado]
**Evento:** Campo cambiado, sobre el campo de estado. El registro mantiene solos sus indicadores y fechas reales.
```javascript
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 [#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.
```javascript
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](/docs/desarrollo/flex/dinascript/funciones/interaccion-y-formulario).
## Pedir confirmación en vez de bloquear [#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.
```javascript
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 [#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.
```javascript
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_Begin` → `SetValue` → `Commit`) 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 [#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.
```javascript
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 [#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.
```javascript
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 [#recalcular-un-importe-mientras-se-edita]
**Evento:** Tick de recálculo. Mantiene un campo derivado al día sin esperar al guardado.
```javascript
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 [#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.
```javascript
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 eventos](/docs/desarrollo/flex/scripts)
→ [C.: el registro del formulario](/docs/desarrollo/flex/dinascript/c.-registro-del-formulario)
→ [Funciones (F.)](/docs/desarrollo/flex/dinascript/funciones)
→ [Buenas prácticas de DinaScript](/docs/desarrollo/flex/dinascript/buenas-practicas)
# Espacio de Nombres (S.) (/docs/desarrollo/flex/dinascript/s.-espacio-de-nombre-schema)
El espacio **`S.`** (Sistema) es la puerta de acceso al **esquema** de [Dinaup Flex](/docs/desarrollo/flex) desde [DinaScript](/docs/desarrollo/flex/dinascript). Con él consultas la estructura y configuración de tu sistema (secciones, campos, relaciones, algoritmos, informes) **durante la ejecución** de algoritmos, scripts y documentos dinámicos.
La idea clave: en vez de escribir a mano el identificador de un campo o una sección, lo referencias por su nombre. Así tu código no depende de identificadores internos y sigue funcionando aunque la configuración cambie.
`S.` es **solo lectura**: te da metadatos y referencias para construir consultas y lógica. Para recorrer registros usas el iterador `I.`, y para crear o modificar datos, las funciones del espacio [`F.`](/docs/desarrollo/flex/dinascript/funciones).
***
## Para qué sirve [#para-qué-sirve]
Las rutas `S.` te permiten escribir código que se adapta a la configuración actual del sistema. Con ellas puedes:
* Referenciar una **sección** o un **campo** por su nombre, sin manejar identificadores a mano.
* Pasar esas referencias a las funciones de [`F.`](/docs/desarrollo/flex/dinascript/funciones) que cargan o filtran datos (`F.DataListLoad`, `F.DataListLoadAddFilter`, `F.ProcessDataList_Ini`).
* Leer **propiedades** de un elemento del esquema: nombre, tipo de dato, si es obligatorio, visible o bloqueado.
* Acceder a **informes, columnas, algoritmos y documentos** configurados para reutilizarlos desde código.
* Resolver valores de **enumeraciones** e **intervalos** definidos en tu sistema.
***
## Cómo se escribe una ruta S. [#cómo-se-escribe-una-ruta-s]
Una ruta `S.` se lee de izquierda a derecha, de lo general a lo concreto: primero la categoría, luego el elemento y, si aplica, la propiedad.
```
S..[.].
```
| Parte | Qué es | Ejemplo |
| --------------- | --------------------------------------------------------------------------------------------------- | -------------------------------- |
| **Categoría** | El tipo de elemento del esquema. | `Sections`, `Fields`, `Reports`… |
| **Elemento** | El nombre del elemento concreto. | `Productos`, `Clientes` |
| **Subelemento** | Un nivel más fino cuando lo hay (un campo dentro de una sección, una columna dentro de un informe). | `Activo`, `Total` |
| **Atributo** | La propiedad que quieres leer. El más habitual es `ID`. | `ID`, `Nombre` |
El uso más frecuente es obtener el **`ID`** de una sección o un campo para pasarlo a una función:
```javascript
// Cargar los productos activos y recorrerlos
F.DataListLoad(S.Sections.Productos.ID, 1, 999999)
F.DataListLoadAddFilter(S.Sections.Productos.ID, S.Fields.Productos.Activo.ID, '=', 1)
F.ProcessDataList_Ini(S.Sections.Productos.ID)
F.Write(F.Concat("Producto: ", I.Productos.Nombre))
F.ProcessDataList_End
```
***
## Acceso a secciones y campos [#acceso-a-secciones-y-campos]
Las dos categorías que más usarás son `S.Sections` y `S.Fields`.
### S.Sections: Secciones [#ssections-secciones]
Accede a una [sección](/docs/desarrollo/flex/secciones) por su nombre y obtén sus propiedades o, sobre todo, su `ID`.
```javascript
S.Sections.NombreSeccion.ID // Identificador de la sección
S.Sections.NombreSeccion.Nombre // Nombre de la sección
```
### S.Fields: Campos [#sfields-campos]
Accede a un **campo** dentro de una sección. La ruta lleva primero la sección y luego el campo, porque un mismo nombre de campo puede existir en varias secciones.
```javascript
S.Fields.NombreSeccion.NombreCampo.ID // Identificador del campo
S.Fields.NombreSeccion.NombreCampo.Nombre // Nombre del campo
```
Con estas dos categorías construyes la mayoría de cargas y filtros de datos: la sección dice **de dónde** lees y el campo dice **sobre qué** filtras u ordenas.
```javascript
F.DataListLoadAddFilter(S.Sections.Ventas.ID, S.Fields.Ventas.Estado.ID, '=', "pendiente")
F.DataListLoadSetOrder(S.Sections.Ventas.ID, S.Fields.Ventas.Fecha.ID, 0)
```
### Campos de relación [#campos-de-relación]
Cuando una sección **se relaciona** con otra (una venta apunta a un cliente, una línea apunta a un producto), esa conexión vive en un campo de relación de la sección. Lo referencias como cualquier otro campo:
```javascript
// El campo "Cliente" de la sección "Ventas" guarda la relación con el cliente
S.Fields.Ventas.Cliente.ID
```
Una vez estás recorriendo registros con el iterador, ese campo te da el **valor de la relación** del registro actual:
```javascript
F.ProcessDataList_Ini(S.Sections.Ventas.ID)
txt clienteDeLaVenta = I.Ventas.Cliente
// ...usa el valor para cargar o cruzar datos del cliente
F.ProcessDataList_End
```
`S.Fields...` te da la **referencia** del campo (para filtrar, ordenar o leer su configuración). El **valor** de ese campo en un registro concreto lo obtienes con el iterador (`I.Seccion.Campo`) mientras recorres una lista.
***
## La sesión y el usuario actual [#la-sesión-y-el-usuario-actual]
Tu código se ejecuta **dentro de una sesión**: la de la persona o el proceso que lanza el algoritmo, script o documento. A través de `S.` puedes leer datos de esa sesión para adaptar el comportamiento a **quién** está ejecutando.
El dato más útil es el **usuario de la sesión actual**, que te permite, por ejemplo, personalizar un saludo, filtrar lo que ve cada persona o registrar quién lanzó una acción.
```javascript
S.UsuarioSesionActual // Usuario que está ejecutando ahora mismo
```
Usa el usuario de la sesión para **personalizar y acotar**: mostrar solo lo relevante para quien ejecuta o dejar constancia del autor de una operación. La sesión la gestiona Dinaup; tu código solo la consulta.
***
## Variables de preguntas (v.X) [#variables-de-preguntas-vx]
Un algoritmo o documento puede **preguntar** datos al usuario antes de ejecutarse (una fecha, una opción, un texto). Cada respuesta queda disponible en tu código como una **variable** del espacio `v.`, usando el nombre que diste a la pregunta.
```javascript
// La pregunta "FechaInicio" se lee como una variable v.
txt desde = v.FechaInicio
if v.IncluirInactivos = 1
F.Write("Incluyendo registros inactivos")
end if
```
Las variables `v.` son las mismas que usas para tus **variables locales** dentro del script (ver [DinaScript](/docs/desarrollo/flex/dinascript)): las creas con `txt` o `num` y las lees con el prefijo `v.`. La diferencia es que, en el caso de una pregunta, el valor inicial lo aporta el usuario al ejecutar.
Combina las preguntas con `S.`: el usuario responde *qué* quiere ver (un estado, un rango) en una variable `v.`, y tú usas las referencias `S.Fields...` para filtrar exactamente por ese campo. Así un mismo algoritmo sirve para muchos casos sin tocar el código.
***
## Catálogo de categorías [#catálogo-de-categorías]
Además de secciones y campos, `S.` cubre el resto del esquema de Flex. Todas siguen el mismo patrón: nombre del elemento y, normalmente, `.ID` para usarlo en una función.
| Categoría | Para qué | Patrón |
| ---------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------- |
| **S.Sections** | Secciones del sistema. | `S.Sections.NombreSeccion.ID` |
| **S.Fields** | Campos (incluidos los de relación) de una sección. | `S.Fields.NombreSeccion.NombreCampo.ID` |
| **S.Algorithms** | [Algoritmos](/docs/desarrollo/flex/algoritmos) configurados. | `S.Algorithms.NombreAlgoritmo.ID` |
| **S.Reports** | [Informes](/docs/desarrollo/flex/informes), organizados por categoría. | `S.Reports.Categoria.NombreInforme.ID` |
| **S.Columns** | Columnas de un informe. | `S.Columns.Categoria.NombreInforme.NombreColumna.ID` |
| **S.DynamicDocuments** | Plantillas de documentos dinámicos. | `S.DynamicDocuments.Categoria.NombreDocumento.ID` |
| **S.Intervals** | Intervalos personalizados. | `S.Intervals.NombreIntervalo` |
| **S.Scripts** | Scripts globales. | `S.Scripts.NombreScript.ID` |
| **S.ScriptsSections** | Scripts asociados a una sección concreta. | `S.ScriptsSections.NombreSeccion.NombreScript.ID` |
| **S.Enums** | Valores de enumeraciones del sistema. | `S.Enums.NombreEnum.Valor` |
***
## Patrón de uso típico [#patrón-de-uso-típico]
Estas piezas encajan así en un caso real: el usuario responde una pregunta, tú resuelves las referencias del esquema con `S.`, cargas los datos con `F.` y los recorres con `I.`.
### El usuario responde la pregunta [#el-usuario-responde-la-pregunta]
El algoritmo pregunta un estado y guarda la respuesta en `v.Estado`.
### Referencias del esquema con S. [#referencias-del-esquema-con-s]
Usas `S.Sections` y `S.Fields` para apuntar a la sección y al campo correctos, sin manejar identificadores a mano.
### Carga y filtro con F. [#carga-y-filtro-con-f]
Pasas esas referencias a `F.DataListLoad` y `F.DataListLoadAddFilter` para traer solo lo que pidió el usuario.
### Recorrido con I. [#recorrido-con-i]
Recorres el resultado con `F.ProcessDataList_Ini` y lees cada registro con el iterador `I.`.
```javascript
// 1. El usuario respondió la pregunta "Estado"
// 2. + 3. Referencias del esquema y carga filtrada
F.DataListLoad(S.Sections.Ventas.ID, 1, 999999)
F.DataListLoadAddFilter(S.Sections.Ventas.ID, S.Fields.Ventas.Estado.ID, '=', v.Estado)
// 4. Recorrido del resultado
F.ProcessDataList_Ini(S.Sections.Ventas.ID)
F.Write(F.Concat(I.Ventas.Numero, " — ", I.Ventas.Cliente))
F.ProcessDataList_End
```
***
## Preguntas frecuentes [#preguntas-frecuentes]
S. es el esquema: te da referencias y propiedades de la configuración (qué secciones y campos existen). I. es el iterador: te da los valores del registro que estás recorriendo en ese momento. Sueles usar S. para preparar la consulta y I. para leer cada resultado.
No. S. es solo lectura: sirve para consultar el esquema y obtener referencias. Para crear o modificar registros usas las funciones del espacio F.
Cada pregunta queda disponible como una variable v. con el nombre que le diste. Por ejemplo, una pregunta llamada FechaInicio se lee como v.FechaInicio. Son las mismas variables v. que usas para tus variables locales.
Con S.UsuarioSesionActual obtienes el usuario de la sesión actual. Lo usas para personalizar la salida o para dejar constancia de quién lanzó la operación.
El campo de relación se referencia como cualquier campo: S.Fields.Ventas.Cliente.ID. El valor de esa relación en un registro concreto lo lees con el iterador mientras recorres la lista: I.Ventas.Cliente.
***
→ [DinaScript](/docs/desarrollo/flex/dinascript)
→ [Funciones (espacio F.)](/docs/desarrollo/flex/dinascript/funciones)
→ [Secciones](/docs/desarrollo/flex/secciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
→ [Informes](/docs/desarrollo/flex/informes)
# Crear documento dinámico (/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
### Crea tu primer documento dinámico [#crea-tu-primer-documento-dinámico]
1. Haz clic en `Configuración`
2. Pincha sobre `listado` en `Documentos dinámicos`
3. Dale a + Agregar
4. Elige la plantilla que quieras, por ejemplo `HTML`.
5. Dale un `Nombre` al documento, una `Categoría` y pincha sobre `Código`
6. Borra todo el contenido que hay dentro y sustitúyelo por un "Hola".
7. Pincha sobre `Variables`.
8. Dale a `Añadir nueva pregunta`.
9. En `Nombre de variable` escribe "tu nombre". El valor se le asignará posteriormente cuando se haga la consulta al documento.
10. Modifica el `Formato` para que sea tipo `Tipo Texto`, como se ve en la captura.
11. Dale a la pestaña del `Código` de nuevo.
12. Sitúate al final de la línea del texto `Hola` que has escrito anteriormente y pincha sobre `Bloque Script`.
13. Ahora dentro del bloque de scripts escribe `F.Write(v.tuNombre)`
14. Dale a ✔ Aceptar para guardar el documento creado.
### Acceder al documento dinámico [#acceder-al-documento-dinámico]
#### A través de Dinaup Desktop [#a-través-de-dinaup-desktop]
Para acceder al documento dinámico en la aplicación de escritorio necesitas ser usuario administrador.
1. Colócate en el panel adecuado donde vas a agregar el acceso al documento y pulsa sobre los 3 puntos de la parte superior y elige `Agregar acceso directo a Documento`.
2. En el desplegable selecciona el documento deseado, por ejemplo el que has creado antes.
3. Abre el documento agregado.
4. Escribe el valor para la variable `tu nombre` y dale a ✔ Aceptar.
#### A través de API [#a-través-de-api]
Para acceder al documento dinámico, primero necesitas conocer la ID del documento y luego consultarlo a través de la API.
# Envío de emails (/docs/desarrollo/flex/documentos-dinamicos/envio-de-emails)
Un [documento dinámico](/docs/desarrollo/flex/documentos-dinamicos) se manda por correo desde su propia vista previa. Los metadatos que declaras con `F.MetaData_Set` llegan ya rellenos a ese correo: remitente, destinatario, asunto, cuerpo y nombre del archivo adjunto.
Todos estos metadatos son **opcionales**: lo que no fijes lo rellena a mano quien envía, en la vista previa. `email_body` incluido — sin él, el correo se envía igual, con el cuerpo en blanco para escribirlo antes de mandarlo.
```
F.MetaData_Set('email_subject','Purchase Order Confirmation')
F.MetaData_Set('email_body','Dear customer, please find attached your invoice.')
F.MetaData_Set('email_to','john.doe@example.com')
F.MetaData_Set('email_to_name','John Doe')
F.MetaData_Set('email_attachment_name','invoice_12345.pdf')
F.MetaData_Set('email_from','pedidos@midominio.com')
F.MetaData_Set('email_from_name','Mi Empresa')
```
***
## Las dos formas de enviar [#las-dos-formas-de-enviar]
La barra del documento tiene dos botones, y no mandan lo mismo:
| Botón | Cuerpo del correo | Adjunto |
| ------------------------------- | ---------------------------- | ------------------- |
| **Enviar por email** | El documento renderizado | Ninguno |
| **Adjuntar y enviar por email** | Lo que digas en `email_body` | El documento en PDF |
`email_body` solo interviene en **Adjuntar y enviar por email**. En el otro botón el documento *es* el correo, así que ese metadato se ignora.
Con email_body
El documento se convierte en PDF y
email_body
se usa como cuerpo del mensaje.
El email
De
Mi Empresa
Para
Ana López
Asunto
Factura F-2026/154
Hola Ana,
te envío la factura para que la revises. Un saludo.
Este texto sale de
email_body
. Sin él, llega en blanco.
PDF
Factura F-2026-154.pdf
El adjunto
Factura F-2026-154.pdf
PDF
FACTURA F-2026/154
31/07/2026
Faro delantero izquierdo180,00 €
Mano de obra · 2 h820,00 €
Total1.210,00 €
El documento, convertido a PDF. Su nombre lo fija
email_attachment_name
.
***
## Metadatos disponibles [#metadatos-disponibles]
| Metadato | Qué hace |
| ----------------------- | ----------------------------------------------------------------------------------------------- |
| `email_subject` | Asunto del correo. |
| `email_body` | Cuerpo del correo al adjuntar. Admite HTML, o el ID de otro documento dinámico (ver más abajo). |
| `email_to` | Dirección del destinatario. |
| `email_to_name` | Nombre del destinatario. Sin él, el correo no se puede enviar. |
| `email_from` | Dirección del remitente. Exige dominio verificado. |
| `email_from_name` | Nombre visible del remitente. |
| `email_attachment_name` | Nombre con el que viaja el PDF adjunto. Sustituye al nombre del documento. |
***
## El cuerpo puede ser otra plantilla [#el-cuerpo-puede-ser-otra-plantilla]
`email_body` acepta el **ID de otro documento dinámico**. Cuando lo detecta, Dinaup ejecuta esa plantilla con las mismas variables del documento original y usa su HTML como cuerpo del correo.
```
F.MetaData_Set('email_body','a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d')
```
Con eso separas las dos piezas: la plantilla de impresión viaja como PDF adjunto y la plantilla del correo se diseña aparte, con su propio HTML y los mismos datos del registro.
***
## Remitente y dominio verificado [#remitente-y-dominio-verificado]
Por defecto el correo sale de **Dinaup ``**. Con `email_from` sale desde tu dirección, y el remitente recibe además una copia oculta del envío.
`email_from` exige que su dominio esté verificado en tu licencia. Si tienes dominios verificados y la dirección no pertenece a ninguno, el envío se rechaza con el error «El dominio no está verificado». Si tu licencia no tiene ninguno, `email_from` se ignora y el correo sale desde `noreply@dinaup.com`.
***
## Vista previa antes de enviar [#vista-previa-antes-de-enviar]
Los metadatos rellenan el correo, no lo mandan. Dinaup abre una vista previa con el remitente, el destinatario, el asunto y el cuerpo ya puestos, y desde ahí decides. El destinatario, su nombre y el asunto se pueden corregir a mano; al adjuntar, el cuerpo también se edita.
El botón **Enviar correo** sigue bloqueado mientras falte la dirección del destinatario, su nombre o el asunto. De ahí que `email_to_name` importe tanto como `email_to`: sin nombre, quien envía tiene que escribirlo cada vez.
***
## Alias antiguos [#alias-antiguos]
Los documentos escritos hace tiempo usan otras claves, que se siguen leyendo:
| Clave actual | Alias que se mantienen |
| --------------- | ------------------------------------------------------------- |
| `email_subject` | `email_asunto` |
| `email_body` | `email_cuerpo` |
| `email_to` | `email_para`, `email_to_1`, `email_para_1`, `email_destino1` |
| `email_to_name` | `email_para_nombre`, `email_to_name_1`, `email_para_nombre_1` |
En documentos nuevos escribe la clave actual. Los alias no se reconocen en todos los puntos de lectura: `email_cuerpo` funciona al ejecutar el documento, pero el listado de documentos del [SDK .NET](/docs/desarrollo/dotnet/sdk) solo lee `email_body`.
***
## Ejemplos [#ejemplos]
```
F.MetaData_Set('email_subject',F.Concat('Factura ',D.EmpresaActual.TextoPrincipal,' nº',v.Factura.NumeroDeFacturaCompleto,' - ',v.Factura.ReferenciaCliente.NombrePersonalRazonSocial))
F.MetaData_Set('email_body','Hola, Te envío la factura para que la revises. Si hay algo que ajustar o cualquier duda, cuéntamelo sin problema. ¡Quedo atento para avanzar cuando tú quieras! Un saludo.')
F.MetaData_Set('email_to',v.Factura.ReferenciaCliente.IdentificadorAcceso)
F.MetaData_Set('email_to_name',v.Factura.ReferenciaCliente.NombrePersonalRazonSocial)
F.MetaData_Set('email_attachment_name',F.Concat('Factura ',D.EmpresaActual.TextoPrincipal,' n ',v.Factura.NumeroDeFacturaCompleto,' - ',v.Factura.ReferenciaCliente.NombrePersonalRazonSocial,'.pdf'))
```
```
F.MetaData_Set('email_subject',F.Concat('Pedido ',D.EmpresaActual.TextoPrincipal,' nº',v.Pedido.NumeroDePedido,' - ',v.Pedido.NombreDeCliente))
F.MetaData_Set('email_body','Hola, Te envío el pedido para que lo revises. Si hay algo que ajustar o cualquier duda, cuéntamelo sin problema. ¡Quedo atento para avanzar cuando tú quieras! Un saludo.')
F.MetaData_Set('email_to',v.Pedido.ReferenciaCliente.IdentificadorAcceso)
F.MetaData_Set('email_to_name',v.Pedido.ReferenciaCliente.NombrePersonalRazonSocial)
F.MetaData_Set('email_attachment_name',F.Concat('Pedido ',D.EmpresaActual.TextoPrincipal,' n ',v.Pedido.NumeroDePedido,' - ',v.Pedido.NombreDeCliente,'.pdf'))
```
***
→ [Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
→ [Mostrar e imprimir](/docs/desarrollo/flex/documentos-dinamicos/mostrar-e-imprimir)
→ [DinaScript](/docs/desarrollo/flex/dinascript)
# Documentos dinámicos (/docs/desarrollo/flex/documentos-dinamicos)
Un **documento dinámico** es una plantilla programable que mezcla tus datos de Dinaup con código para producir un resultado a medida: una factura en PDF, un email personalizado, un panel con gráficos o una respuesta JSON para otro sistema. Tú defines la plantilla una vez y Dinaup la rellena con datos reales cada vez que se usa.
La plantilla se escribe con [DinaScript](/docs/desarrollo/flex/dinascript) sobre tecnología web estándar (HTML, CSS, JavaScript). El mismo documento puede imprimirse, enviarse por email, incrustarse como widget en un dashboard o consultarse desde una API externa.
¿Es tu primer documento dinámico? Salta a **[Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)** para entender el flujo básico (código + variables) y vuelve aquí cuando quieras elegir el tipo adecuado o ver un ejemplo completo.
***
## Tipos de documento dinámico [#tipos-de-documento-dinámico]
No todos los documentos dinámicos sirven para lo mismo. Al crearlo eliges un **tipo**, y ese tipo determina qué genera y dónde se usa. Estos son los disponibles:
| Tipo | Qué produce | Para qué sirve |
| ------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Diseño de informe** | Una plantilla visual asociada a un [informe](/docs/desarrollo/flex/informes) | Dar formato a los resultados de un informe (cómo se ven las filas y los totales al presentarlos). |
| **Documento de lectura libre (HTML)** | Una página HTML completa | Impresión (facturas, albaranes, presupuestos en PDF), emails y paneles con gráficos o tablas. Es el tipo más versátil. |
| **API de lectura libre (JSON / XML)** | Datos estructurados en JSON o XML | Exponer información de Dinaup a otro sistema mediante un endpoint que se consulta en remoto. |
| **API de escritura** | Una operación que recibe datos y los guarda | Recibir información desde fuera y crear o actualizar registros en tus secciones. |
| **Documento contable** | Asientos y datos para contabilidad | Generar la información contable derivada de tus registros con el formato que necesita la contabilidad. |
Si dudas, casi siempre quieres un **Documento de lectura libre (HTML)**: cubre impresión, email y dashboards con la misma plantilla. Reserva los tipos de **API** para cuando otro sistema vaya a hablar con Dinaup, y el **Documento contable** para cuando el destino sea la contabilidad.
***
## Cuándo usar cada uno [#cuándo-usar-cada-uno]
Elige el tipo según **adónde va el resultado**:
* **Lo vas a imprimir o enviar por email** → Documento de lectura libre (HTML). Diseñas la página con HTML y CSS, la generas en PDF para imprimir o la mandas como cuerpo de un correo. Es el caso de una factura, un albarán o un presupuesto. Ver **[Plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas)**.
* **Lo quieres mostrar dentro de Dinaup** → Documento de lectura libre (HTML) incrustado como **widget** en un dashboard: el resumen de un proyecto, un panel con gráficos, una tabla de seguimiento.
* **Quieres dar formato a un informe** → Diseño de informe, asociado al [informe](/docs/desarrollo/flex/informes) cuyos resultados quieres presentar con un aspecto concreto.
* **Otro sistema va a leer datos de Dinaup** → API de lectura libre (JSON / XML). Publicas un endpoint que devuelve los datos ya estructurados, listos para que la otra aplicación los consuma.
* **Otro sistema va a enviar datos a Dinaup** → API de escritura. El documento recibe la entrada y la convierte en registros nuevos o actualizados en tus secciones.
* **El destino es la contabilidad** → Documento contable, para producir asientos y la información contable a partir de tus datos.
***
## Qué puedes hacer con ellos [#qué-puedes-hacer-con-ellos]
Con documentos dinámicos resuelves, entre muchas otras cosas:
1. Enviar **correos electrónicos personalizados** con los datos de cada registro.
2. Crear **plantillas de impresión**, como facturas o albaranes en PDF.
3. Mostrar el **resumen de un proyecto** o un panel a medida.
4. Construir una **página con gráficos y tablas** para un dashboard.
5. Publicar o guardar **datos en JSON / XML** para integraciones.
6. Generar **ficheros para transferencias bancarias** (SEPA).
7. Hacer **cálculos matemáticos o financieros** sobre tus datos.
8. Producir la **información contable** derivada de tus movimientos.
***
## Tecnologías compatibles [#tecnologías-compatibles]
La plantilla se escribe sobre web estándar, así que puedes apoyarte en herramientas que ya conoces:
* **HTML, CSS y JavaScript** para el contenido y el diseño.
* **Bootstrap** para maquetar rápido sin escribir CSS desde cero.
* **Vue** para partes interactivas.
* **Google Charts** para gráficos en paneles e informes.
El código que rellena la plantilla con tus datos lo pones con [DinaScript](/docs/desarrollo/flex/dinascript): defines variables, recorres los registros y vuelcas el resultado.
***
## Por dónde empezar [#por-dónde-empezar]
### Crea tu primer documento [#crea-tu-primer-documento]
Sigue **[Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)** para dar de alta una plantilla, elegir su tipo y abrir el editor de código con sus variables.
### Parte de un ejemplo real [#parte-de-un-ejemplo-real]
En **[Ejemplos](/docs/desarrollo/flex/documentos-dinamicos/ejemplos)** tienes plantillas completas (una factura para imprimir, un libro registro en HTML) listas para copiar y adaptar a tu negocio.
### Conéctalo a tus datos [#conéctalo-a-tus-datos]
Ajusta las secciones, campos y textos de la plantilla para que reflejen tu información, guarda y prueba el resultado.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Un documento de lectura libre (HTML) produce una página pensada para que la lea una persona: se imprime, se envía por email o se muestra en un dashboard. Una API produce datos pensados para que los consuma otro sistema (lectura en JSON/XML) o recibe datos de fuera para guardarlos (escritura). Mismo motor, destino distinto.
Sí. Un documento de lectura libre genera el HTML una vez y tú decides el destino: convertirlo en PDF para imprimir o mandarlo como cuerpo de un correo. No hace falta duplicar la plantilla.
Para los casos básicos te basta con copiar un ejemplo y cambiar textos y campos. Para plantillas a medida ayuda conocer HTML y CSS, y la lógica que rellena los datos se escribe con DinaScript, que está pensado para esto.
Con un documento de tipo Diseño de informe, asociado al informe cuyos resultados quieres presentar. La plantilla controla cómo se ven las filas y los totales al mostrarlos o imprimirlos.
***
→ [Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
→ [Plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas)
→ [Ejemplos](/docs/desarrollo/flex/documentos-dinamicos/ejemplos)
→ [Informes](/docs/desarrollo/flex/informes)
→ [DinaScript](/docs/desarrollo/flex/dinascript)
# Mostrar e imprimir el documento (/docs/desarrollo/flex/documentos-dinamicos/mostrar-e-imprimir)
Ya tienes el documento generado: llamaste a [`POST /api/dynamicdocuments`](/docs/desarrollo/integraciones/webhook/entrantes#post-apidynamicdocuments-documentos-dinámicos), lo exportaste desde Dinaup o lo recibiste por email. Lo que tienes en la mano es **una página HTML completa**. Esta página explica qué hacer con ella para verla en tu web o convertirla en PDF.
```bash
curl -X POST "https://webhook.dinaup.com/api/dynamicdocuments?id=" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{ "factura": "" }' \
-o factura.html
```
***
## Lo único importante: el HTML llega vivo [#lo-único-importante-el-html-llega-vivo]
Una plantilla de impresión no es HTML plano. Como cuenta [Tecnologías compatibles](/docs/desarrollo/flex/documentos-dinamicos#tecnologías-compatibles), las plantillas se apoyan en **Bootstrap, Vue y Google Charts**, que se cargan desde internet y se ejecutan en el navegador. La [plantilla de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas) es justo así: el fichero que recibes trae los datos y las instrucciones para pintarlos, pero **el dibujo lo hace el navegador**.
La consecuencia práctica es una sola, y de ella salen todos los errores típicos:
Si abres el HTML en algo que no ejecuta JavaScript, verás la plantilla en crudo: los huecos de datos aparecen como `{{ ... }}` sin sustituir, o directamente no aparece nada. No es que el documento se haya generado mal — es que todavía no ha terminado de montarse.
Así que solo hay dos destinos válidos, y los dos pasan por un navegador de verdad: **incrustarlo en un `iframe`** o **pasarlo por un navegador headless para sacar el PDF**.
***
## Mostrarlo en tu web: siempre en un iframe [#mostrarlo-en-tu-web-siempre-en-un-iframe]
`elemento.innerHTML = html` **nunca** va a funcionar. Los navegadores no ejecutan las etiquetas `
```
`sandbox=""` no significa «protección normal»: significa **todos los permisos apagados**, empezando por ejecutar JavaScript. Es la causa número uno de que un documento aparezca con los `{{ }}` a la vista. Y añadir `allow-same-origin` junto a `allow-scripts` anula el aislamiento por completo: si vas a hacer eso, usa directamente la opción B.
### Opción B · Mismo origen [#opción-b--mismo-origen]
Conviertes el HTML en un fichero temporal del navegador y se lo das al `iframe` por su `src`. El documento queda en tu mismo origen, así que **sí** puedes medir su altura o lanzar la impresión desde fuera. Llama a la clave API solo desde tu backend.
```js
const marco = document.getElementById('doc');
const url = URL.createObjectURL(new Blob([html], { type: 'text/html' }));
marco.onload = () => URL.revokeObjectURL(url); // libera la memoria del fichero temporal
marco.src = url;
```
Y a partir de ahí, con el documento ya cargado:
```js
marco.contentWindow.print(); // abrir el diálogo de impresión
marco.style.height = marco.contentDocument.body.scrollHeight + 'px'; // ajustar el alto
```
***
## Convertirlo en PDF [#convertirlo-en-pdf]
Para archivar la factura o adjuntarla a un email necesitas un PDF. Vale cualquier navegador headless — Puppeteer o Playwright en tu servidor, o un servicio de render como **Cloudflare Browser Rendering**, **Browserless** o similar — pero en todos hay que cumplir **tres condiciones**, o el PDF sale mal:
1. **Esperar a que el JavaScript termine.** El PDF se captura cuando tú digas; si lo capturas al instante, congelas la página a medio montar y salen los `{{ }}`.
2. **Imprimir los fondos.** Las plantillas usan colores de fondo en cabeceras y totales; sin esta opción salen en blanco.
3. **Tamaño A4.** Las plantillas ya declaran `@page { size: A4 }`; dale al navegador un lienzo acorde (794 × 1123 px a 96 ppp).
Con Puppeteer son cuatro líneas:
```js
const pagina = await navegador.newPage();
await pagina.setViewport({ width: 794, height: 1123 });
await pagina.setContent(html, { waitUntil: 'networkidle0' }); // condición 1
const pdf = await pagina.pdf({ format: 'A4', printBackground: true }); // condiciones 2 y 3
```
`networkidle0` espera a que no queden descargas en curso, que es justo lo que necesitas: Bootstrap y Vue vienen de internet, y hasta que llegan y se ejecutan no hay factura. Si tu servicio de render no ofrece esa espera, casi todos aceptan una **espera fija** (uno o dos segundos) o **esperar a que aparezca un elemento** de la plantilla; cualquiera de las dos sirve.
***
## Enviarlo por email [#enviarlo-por-email]
No hace falta que montes tú el correo: la propia plantilla puede fijar asunto, cuerpo, destinatario y nombre del adjunto. Está en [Envío de emails](/docs/desarrollo/flex/documentos-dinamicos/envio-de-emails).
***
## Errores típicos [#errores-típicos]
El JavaScript del documento no llegó a ejecutarse. Las tres causas, por orden de frecuencia: lo insertaste con innerHTML, el iframe lleva sandbox sin allow-scripts, o el PDF se capturó antes de que la página terminara de montarse.
La plantilla oculta bloques enteros cuando no le llegan datos. Comprueba que estás enviando las variables de entrada del documento en el cuerpo de la petición y que el registro existe: si la variable llega vacía, el documento se genera correctamente pero no tiene nada que pintar.
El documento carga Bootstrap y las fuentes desde internet. Si lo abres en una máquina sin salida a la red, o tu web bloquea recursos externos con una política de seguridad de contenido (CSP), el HTML llega pero el diseño no.
Falta activar la impresión de fondos: printBackground: true en Puppeteer, o la opción equivalente en tu servicio de render. Es una opción del navegador, no de la plantilla.
Sí, el fichero es autosuficiente en cuanto a datos: los tuyos ya vienen dentro. Pero necesita conexión para descargar Bootstrap y Vue. Si quieres un archivo que sobreviva sin internet, guarda el PDF, no el HTML.
Un documento lleva datos que quizá no controlas del todo (el nombre de un cliente, unas notas). Si lo incrustas aislado —sandbox="allow-scripts" sin allow-same-origin— el documento se pinta pero no puede leer la sesión ni las cookies de tu página. Reserva el mismo origen para tus propios documentos dentro de tu propia aplicación.
***
→ [Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
→ [Plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas)
→ [Envío de emails](/docs/desarrollo/flex/documentos-dinamicos/envio-de-emails)
→ [Referencia del endpoint](/docs/desarrollo/integraciones/webhook/entrantes#post-apidynamicdocuments-documentos-dinámicos)
# Plantilla de impresión de facturas (/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas)
## Datos que siempre se deben mostrar [#datos-que-siempre-se-deben-mostrar]
```
resumen.NumeroFactura
resumen.Fecha
resumen.EmpresaRazonSocial
resumen.EmpresaNIF
resumen.EmpresaDireccion
resumen.EmpresaEmail
totales
conceptos
```
## Visibles si (v-if="resumen.ClienteNIF") [#visibles-si--v-ifresumenclientenif]
```html
resumen.ClienteNombre
resumen.ClienteNIF
resumen.ClienteDireccion
resumen.ClienteEmail
```
## Datos visibles solo si están rellenados [#datos-visibles-solo-si-están-rellenados]
```
resumen.LogoURL
resumen.FechaVencimiento
resumen.DireccionEnvio
resumen.CondicionesPago
resumen.Notas
resumen.EnlacePago
resumen.VerifactuQR
```
## Tabla BI [#tabla-bi]
Usa esta tabla tal cual:
```
Tipo
Base
Cuota IVA
RE %
Cuota RE
Tipo
Base
Cuota
{{ bi.IVAPorciento }}%
{{ euro(bi.BaseImponible) }}
{{ euro(bi.CuotaIVA) }}
{{ bi.REPorciento }}
{{ euro(bi.CuotaRE) }}
{{ bi.IVAPorciento }}%
{{ euro(bi.BaseImponible) }}
{{ euro(bi.CuotaIVA) }}
```
# QR Veri*factu (/docs/desarrollo/flex/documentos-dinamicos/qr-verifactu)
El **QR de Veri\*factu** es el código que la normativa antifraude obliga a imprimir en cada factura. Permite que cualquiera (cliente o Hacienda) **verifique la factura** escaneándolo contra la sede electrónica de la AEAT.
Dinaup **genera y firma ese QR por ti** cuando registra la factura. En tu [plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas) no lo calculas: solo lo **colocas** donde quieras que aparezca en el documento.
El QR es **verificable**, no decorativo. Codifica los datos fiscales de la factura (emisor, número, fecha, importe) y un sello que la AEAT comprueba. No intentes recalcularlo ni montar el hash a mano: usa el que Dinaup expone.
***
## Cómo encaja en la plantilla [#cómo-encaja-en-la-plantilla]
Una plantilla de impresión es un [documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico) HTML que combina los datos de la factura con tu maquetación. Entre los datos que Dinaup pone a tu disposición está el **QR de Veri\*factu** ya resuelto, listo para pintar.
| Pieza | De dónde sale |
| ------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Datos de la factura (número, fecha, totales, conceptos) | Resumen de la factura que recibe la plantilla |
| **QR de Veri\*factu** | Lo entrega Dinaup ya generado y firmado, junto al resto de datos de la factura |
| Maquetación (dónde y cómo se ve el QR) | Tú, en el HTML de la plantilla |
Igual que el logo, el enlace de pago o las notas, el QR es **un dato más** que muestras solo si la factura lo lleva. Para el listado completo de datos disponibles y cómo condicionar su visibilidad, consulta la [plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas).
***
## Insertar el QR [#insertar-el-qr]
### Abre tu plantilla de impresión de facturas [#abre-tu-plantilla-de-impresión-de-facturas]
Edita el [documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico) que usas para imprimir facturas. Es donde defines la maquetación HTML del documento.
### Coloca el QR donde quieras que aparezca [#coloca-el-qr-donde-quieras-que-aparezca]
Inserta el QR de Veri\*factu en el punto del documento donde debe imprimirse (habitualmente junto al total o en el pie de la factura). La sintaxis concreta para volcar el QR está documentada en la propia [plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas), junto al resto de campos.
### Muéstralo solo si la factura lo lleva [#muéstralo-solo-si-la-factura-lo-lleva]
No todas las facturas generan QR. Condiciona su impresión a que el dato venga relleno, igual que harías con el logo o las notas, para que la plantilla siga siendo válida en facturas sin Veri\*factu.
El QR aparece **solo cuando la factura está acogida a Veri\*factu**. Si tu empresa aún no lo tiene activado, el dato llega vacío y la plantilla no debe pintar nada. Revisa el estado de Veri\*factu en tu empresa en la [página de Veri\*factu](/docs/rtg/pymes/facturacion/ventas/verifactu).
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Dinaup genera y firma el QR de Veri\*factu al registrar la factura. La plantilla solo lo coloca en el documento. No tienes que calcular el contenido ni el sello.
Porque el QR solo se genera para facturas acogidas a Veri\*factu. Si tu empresa no lo tiene activado, o la factura no entra en el régimen, el dato llega vacío. Por eso conviene condicionar su impresión a que venga relleno.
Los datos fiscales de la factura (emisor, número completo, fecha de expedición e importe total) junto a un sello que permite verificarla contra la sede electrónica de la AEAT. Es el QR oficial de Veri\*factu, no uno propio de Dinaup.
***
→ [Plantilla de impresión de facturas](/docs/desarrollo/flex/documentos-dinamicos/plantilla-de-impresion-facturas)
→ [Crear un documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
→ [Veri\*factu (producto)](/docs/rtg/pymes/facturacion/ventas/verifactu)
→ [Declaración Veri\*factu (legal)](/docs/cuenta/legal/declaracion-verifactu)
# Filtrar informe por rango de fechas (/docs/desarrollo/flex/informes/filtrar-informe-por-rango-de-fechas)
Una variable de informe formula la pregunta del intervalo y un filtro rápido la aplica sobre el campo de fecha.
**Recomendación**: para informes contables utiliza siempre campos de tipo **Fecha** (sin hora). Las fechas con hora tienen implicaciones de zona horaria que pueden causar discrepancias entre regiones.
***
#### Añade la variable de intervalo de fechas [#añade-la-variable-de-intervalo-de-fechas]
Las variables de informe son preguntas que el sistema formula al usuario antes de ejecutar la consulta.
1. Abre la ventana de configuración del informe.
2. Pulsa sobre **`Añadir pregunta de intervalo de fecha y hora`**.
3. En **Nombre de variable** escribe `Fecha` y pulsa **Aceptar**.
#### Configura el formato de la pregunta [#configura-el-formato-de-la-pregunta]
Al pulsar "Añadir pregunta de intervalo...", el sistema crea por defecto una variable de tipo **Fecha y hora dinámica**. Puedes cambiar el formato según tus necesidades.
**Tipos de formato disponibles**
| Formato | Solicita al usuario | Uso recomendado |
| ------------------------- | ---------------------------------- | -------------------------------------- |
| **Fecha** | Un único valor de fecha | Filtrar por fecha exacta |
| **Fecha y hora** | Un único valor con fecha y hora | Filtrar por momento exacto |
| **Fecha dinámica** | Intervalo desde/hasta (solo fecha) | Informes contables, ventas por periodo |
| **Fecha y hora dinámica** | Intervalo desde/hasta (con hora) | Logs, eventos con hora exacta |
**¿Qué significa "dinámica"?** El sufijo "dinámica" indica que se solicita un **intervalo** (desde y hasta) en lugar de un valor único. Por eso, al usar "Añadir pregunta de intervalo...", el tipo predeterminado es dinámico.
**Zona horaria**: los campos con hora pueden mostrar resultados diferentes según la ubicación del usuario. Un registro del "31 de enero a las 23:00 UTC" aparecerá como "1 de febrero" en zonas horarias adelantadas. Para informes contables, usa **Fecha dinámica**.
#### Configura el filtrado rápido [#configura-el-filtrado-rápido]
Vincula la variable con el campo que deseas filtrar:
1. En la sección **Filtrado rápido**, pulsa **Agregar condición**.
2. Configura los siguientes parámetros:
| Parámetro | Valor |
| -------------- | ---------------------------------------------------------- |
| **Campo** | Fecha contable (o el campo de fecha que corresponda) |
| **Operador** | Entre desde y hasta |
| **Parámetros** | Selecciona las variables `Fecha (desde)` y `Fecha (hasta)` |
#### Guarda y consulta el informe [#guarda-y-consulta-el-informe]
Una vez configurado:
1. Guarda los cambios del informe.
2. Al consultar el informe, el sistema solicita el intervalo de fechas antes de mostrar los resultados.
***
# Informes (/docs/desarrollo/flex/informes)
Un **informe** es una configuración que produce un listado de datos a partir de una sección. Eliges qué columnas quieres, cómo filtrarlas, cómo agruparlas y ordenarlas, y obtienes una consulta reutilizable: para verla en pantalla, exportarla o consumirla desde la API. Todo sin escribir SQL.
Un informe **siempre nace de una sección**. La sección es el origen de los datos (las "tablas" de Flex); el informe es la vista que defines sobre ella. Antes de crear un informe, ten clara la sección de la que vas a partir.
***
## Qué puedes hacer con un informe [#qué-puedes-hacer-con-un-informe]
| Capacidad | Para qué sirve |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Selección de columnas** | Eliges exactamente qué campos de la sección aparecen en el listado, incluidos datos de secciones relacionadas. |
| **Filtrado rápido** | Acotas los resultados con condiciones sobre los campos (igual, distinto, contiene, entre desde y hasta…) sin escribir nada de código. |
| **Filtro por algoritmo** | Cuando la condición es un cálculo y no un campo directo, un [algoritmo](/docs/desarrollo/flex/algoritmos) decide qué filas entran. |
| **Columnas calculadas** | Añades columnas cuyo valor lo produce un [algoritmo](/docs/desarrollo/flex/algoritmos): totales, búsquedas en otras secciones, agregados de registros relacionados. |
| **Rol de columna** | Le dices al informe **qué tipo de dato** es una columna (moneda, porcentaje, cantidad…) para que la formatee y la trate bien. |
| **Visibilidad de columna** | Controlas cuándo se muestra u oculta una columna sin tener que quitarla del informe. |
| **Agrupación y ordenación** | Agrupas filas por uno o varios campos y ordenas el resultado como necesites. |
| **Preguntas dinámicas** | El informe pregunta parámetros al usuario antes de ejecutarse (por ejemplo, un rango de fechas) y filtra con su respuesta. |
| **Consumo por API** | Expones el informe como endpoint para que sistemas externos lean sus datos de forma estandarizada. |
***
## Filtrado: rápido o por algoritmo [#filtrado-rápido-o-por-algoritmo]
Hay dos formas de acotar qué filas devuelve un informe, y se combinan:
* **Filtrado rápido**: condiciones directas sobre los campos de la sección. Eliges un campo, un operador y un valor (o un parámetro). Es el filtro del día a día y no requiere código.
* **Filtro por algoritmo**: cuando lo que decide la pertenencia de una fila es un cálculo (un total, una comparación derivada, un dato de otra sección), un [algoritmo](/docs/desarrollo/flex/algoritmos) resuelve la condición.
Las **preguntas dinámicas** (también llamadas variables del informe) convierten un filtro fijo en uno interactivo: el sistema pregunta el valor al usuario justo antes de ejecutar la consulta. El caso más habitual es delimitar un periodo temporal.
→ Guía: [Filtrar informe por rango de fechas](/docs/desarrollo/flex/informes/filtrar-informe-por-rango-de-fechas)
***
## Columnas calculadas, agrupación y ordenación [#columnas-calculadas-agrupación-y-ordenación]
Un informe no se limita a volcar campos tal cual:
* **Columnas calculadas**: el valor de la columna lo genera un [algoritmo](/docs/desarrollo/flex/algoritmos). Sirve para sumar líneas de un documento, traer el nombre de un registro relacionado o calcular un importe derivado, todo dentro del propio listado.
* **Agrupación**: juntas las filas por uno o varios campos para obtener subtotales y resúmenes en lugar del detalle fila a fila.
* **Ordenación**: defines el orden del resultado por las columnas que elijas.
Los cálculos de un informe se apoyan en **algoritmos**, que se ejecutan como consultas SQL optimizadas. Entender los tipos de algoritmo (lineal, cruzado, búsqueda…) te ayuda a decidir qué columna calculada o qué filtro necesitas. → [Algoritmos](/docs/desarrollo/flex/algoritmos)
***
## Rol de una columna [#rol-de-una-columna]
El **rol** le dice al informe qué clase de dato representa una columna. No cambia el valor: cambia cómo se interpreta, se formatea y se trata en pantalla, en los totales y en la exportación. Por defecto una columna es **automática**, y el informe deduce su trato por el formato del campo. Cuando ese trato automático no acierta, fijas el rol a mano.
| Rol | Cuándo usarlo |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Automático** | El informe decide el trato de la columna según el tipo del campo. Es el valor por defecto y vale para la mayoría de columnas. |
| **Moneda** | La columna es un importe. Se presenta como dinero (decimales y símbolo monetario) y se comporta como tal en sumas y totales. |
| **Porcentaje** | La columna es un tanto por ciento. Se muestra en formato porcentual en lugar de como número suelto. |
| **Cantidad** | La columna es una cantidad asociada al propósito del informe (por ejemplo, unidades). El informe la trata como su magnitud principal. |
| **Última vez visto** | Marca la columna que representa la fecha/momento de última actividad, para usarla como referencia temporal del registro. |
El rol es sobre todo **formato y semántica**: una columna con rol *Moneda* se ve y se suma como dinero. Si una cifra aparece sin símbolo de moneda o un porcentaje sale como número crudo, casi siempre se arregla fijando el rol correcto.
***
## Visibilidad de una columna [#visibilidad-de-una-columna]
La **visibilidad** controla cuándo aparece una columna sin obligarte a eliminarla del informe. Es útil para tener columnas que solo importan en ciertos contextos, o que el informe necesita para calcular o filtrar pero que no quieres mostrar.
| Visibilidad | Comportamiento |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **Siempre visible** | La columna aparece en todos los casos. |
| **Siempre oculta** | La columna nunca se muestra, pero sigue formando parte del informe (sirve para cálculos o filtros internos sin ensuciar el listado). |
| **Automática** | El informe decide si mostrarla según el contexto. Es el comportamiento por defecto. |
| **Oculta en complementos** | La columna se ve en el informe principal, pero se oculta cuando el informe se usa como complemento dentro de otra vista. |
Ocultar una columna **no es lo mismo que quitarla**. Una columna oculta sigue calculándose y puede usarse para filtrar, agrupar u ordenar; solo deja de mostrarse. Quítala del informe solo si de verdad no la necesitas para nada.
***
## Consumir informes desde la API [#consumir-informes-desde-la-api]
Cualquier informe puede convertirse en una fuente de datos para integraciones externas. Los **informes API** son informes normales que cumplen unas convenciones de nombre y categoría para poder consumirse de forma estandarizada. Se dividen en **sincronizables** y **no sincronizables** según su complejidad.
Es la vía recomendada para que un sistema externo lea datos de Dinaup: defines el informe una vez y lo consultas como endpoint, sin acoplarte a la estructura interna de la base de datos.
→ [Informes API](/docs/desarrollo/flex/informes/informes-api) · [Integraciones](/docs/desarrollo/integraciones)
***
## Subpáginas [#subpáginas]
Configura un informe para que pregunte un intervalo de fechas antes de ejecutarse.
Expón un informe como endpoint para integraciones: convenciones, sincronizables y no sincronizables.
***
→ [Filtrar informe por rango de fechas](/docs/desarrollo/flex/informes/filtrar-informe-por-rango-de-fechas)
→ [Informes API](/docs/desarrollo/flex/informes/informes-api)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
# Informes API (/docs/desarrollo/flex/informes/informes-api)
Un informe API es un informe normal que cumple tres requisitos para que un sistema externo lo consuma:
* Nombre: debe empezar por el prefijo `API -`.
* Categoría: `Funcionalidad`.
* Subcategoría: `API`.
Los informes API se clasifican en dos tipos:
* **Syncable** (Sincronizable)
* **Non-Syncable** (No sincronizable)
Ten cuidado al modificarlos: un cambio inapropiado puede generar incompatibilidades con los sistemas conectados. Recomendaciones:
* **Agregar columnas**: incorporar columnas nuevas no debería afectar a la compatibilidad, aunque puede afectar al rendimiento.
* **Editar columnas**: modificar columnas existentes puede provocar incompatibilidades con otros sistemas que ya usan el informe.
* **Ampliación de informes**: si necesitas agregar una columna, valora crear un informe nuevo. En informes pequeños puede bastar con añadir la columna: mantener menos informes simplifica su administración.
### Syncable (Sincronizable) [#syncable-sincronizable]
Los informes sincronizables incluyen, además de las columnas necesarias, las columnas requeridas para la sincronización (por ejemplo `ID`, `Eliminado` o `FechaIA`). No contienen datos relacionados. En términos SQL, corresponden a consultas sencillas del tipo:
```
SELECT a, b, c FROM xx;
```
(sin JOIN, GROUP BY ni subconsultas)
Ejemplo: en un informe sincronizable de ventas, se puede incluir la columna `Ventas > Cliente ID`, pero no se deben incluir niveles adicionales como `Ventas > Cliente ID > Nombre`.
Estos informes son compatibles con [Dinaup PG Sync](/docs/desarrollo/integraciones/dinaup-pg-sync).
### Non-Syncable (No sincronizable) [#non-syncable-no-sincronizable]
Los informes no sincronizables contienen datos complejos, como relaciones, filtros avanzados, agrupaciones, algoritmos o datos indirectos.
Debido a esta complejidad, estos informes no son compatibles con [Dinaup PG Sync](/docs/desarrollo/integraciones/dinaup-pg-sync).
# API REST: Referencia de endpoints (/docs/desarrollo/integraciones/webhook/entrantes)
La API REST de Dinaup lee y escribe tus datos con peticiones HTTP desde cualquier lenguaje. Todos los endpoints se sirven desde `https://webhook.dinaup.com`.
***
## Autenticación [#autenticación]
Toda petición (salvo el ping) lleva un **Token Bearer** en la cabecera HTTP:
```
Authorization: Bearer
```
El token no es tu Clave API en crudo. Dinaup lo deriva de la clave y su secreto, y lo antepone con el identificador de tu terminal:
```
_
```
No lo compones a mano. Genera la Clave API en **dinaup.com > Claves API**, marca la clave como **compatible con webhooks**, y copia el Token Bearer ya montado desde el [Playground](#playground). El token hereda los permisos del usuario de la clave: solo accede a lo que ese usuario puede ver y escribir.
→ Ver [Claves API](/docs/cuenta/claves-api)
Usa el token solo en tu backend. Nunca lo incrustes en código público ni en el frontend de una web.
***
## `GET /`: Ping [#get--ping]
Verifica que el servidor responde. No requiere autenticación.
**Request:**
```bash
curl -X GET "https://webhook.dinaup.com"
```
**Response:** `200 OK`
```
"Hola :)"
```
***
## `GET /api/whoami`: Usuario de la clave [#get-apiwhoami-usuario-de-la-clave]
Devuelve el usuario asociado al token. Úsalo para comprobar que la autenticación funciona.
**Request:**
```bash
curl -X GET "https://webhook.dinaup.com/api/whoami" \
-H "Authorization: Bearer "
```
**Response:** `200 OK`
```json
{
"User": "..."
}
```
El campo `User` trae la información de la sesión del usuario en Dinaup.
***
## Límites de tasa [#límites-de-tasa]
Cada endpoint limita las peticiones por tenant (identificado por el token). El control es un cubo de tokens: un saldo máximo que se repone poco a poco.
| Endpoint | Saldo máximo | Reposición | Periodo |
| -------------------------- | ------------ | ---------- | ------- |
| WriteOperations | 30 | 5 | 10 s |
| Reports | 30 | 5 | 10 s |
| DynamicDocuments | 30 | 5 | 10 s |
| Whoami | 60 | 10 | 10 s |
| Herramientas (AEAT / VIES) | 10 | 2 | 10 s |
Las herramientas fiscales limitan por IP, no por token. Si superas el saldo, recibes `429 Too Many Requests` con la cabecera `Retry-After: 10`.
***
## `POST /api/reports`: Consultar informes [#post-apireports-consultar-informes]
Ejecuta un [informe de Dinaup Flex](/docs/desarrollo/flex/informes) y devuelve las filas en JSON. El informe define columnas, filtros y agrupaciones; tú solo lo disparas.
**Parámetros (query string):**
| Parámetro | Tipo | Obligatorio | Descripción |
| ----------------- | ---- | ----------- | ----------------------------------------------------- |
| `id` | UUID | Sí | ID del informe |
| `page` | int | No | Número de página. Por defecto 1 |
| `resultsPerPage` | int | No | Resultados por página. Por defecto 10 |
| `withFiles` | bool | No | Incluir URLs de archivos adjuntos. Por defecto false |
| `safeColumnsName` | bool | No | Usar GUIDs como nombres de columna. Por defecto false |
**Body (opcional):** JSON plano con los valores de las variables del informe, si tiene preguntas dinámicas.
```json
{
"variableFiltro1": "valor1",
"variableFiltro2": "valor2"
}
```
**Request:**
```bash
curl -X POST "https://webhook.dinaup.com/api/reports?id=&page=1&resultsPerPage=100" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{}'
```
**Response:**
```json
{
"data": [
{"columna1": "valor1", "columna2": "valor2"},
{"columna1": "valor3", "columna2": "valor4"}
],
"currentPage": 1,
"totalPages": 5,
"totalResults": 42,
"files": []
}
```
Activa `safeColumnsName=true` en producción: los nombres de columna dejan de cambiar si renombras un campo en Dinaup. Los resultados vienen paginados, así que itera con `page` y `resultsPerPage` para conjuntos grandes.
***
## `POST /api/dynamicdocuments`: Documentos dinámicos [#post-apidynamicdocuments-documentos-dinámicos]
Renderiza un [documento dinámico](/docs/desarrollo/flex/documentos-dinamicos) y devuelve su contenido. Los documentos dinámicos son plantillas que combinan datos de varias secciones en HTML, JSON o texto.
**Parámetros (query string):**
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ----------- | ------------------------- |
| `id` | UUID | Sí | ID del documento dinámico |
**Body (opcional):** JSON plano con las variables a sustituir en la plantilla.
```json
{
"clienteId": "abc-123"
}
```
**Request:**
```bash
curl -X POST "https://webhook.dinaup.com/api/dynamicdocuments?id=" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"clienteId": "abc-123"}'
```
**Response:** `200 OK` con el contenido renderizado del documento como texto.
***
## `POST /api/writeoperations`: Escribir datos [#post-apiwriteoperations-escribir-datos]
Crea, edita o elimina registros en cualquier sección de Dinaup.
**Parámetros (query string):**
| Parámetro | Tipo | Obligatorio | Descripción |
| -------------- | ------ | ----------- | ----------------------------------------------------------------- |
| `sectionId` | UUID | Sí | ID de la sección donde escribir |
| `FieldPrimary` | string | Sí | Campo clave que identifica registros. Normalmente `id` |
| `scripts` | bool | No | Ejecutar los scripts de servidor de la sección. Por defecto false |
**Headers:**
```
Authorization: Bearer
Content-Type: application/json
```
### Crear, editar y eliminar [#crear-editar-y-eliminar]
La operación la decide el valor del campo `id`:
| Valor de `id` | Operación | Descripción |
| ------------------- | ---------- | ------------------------------------------------- |
| `""` (cadena vacía) | **Crear** | Se crea un registro nuevo. Dinaup genera el ID |
| UUID existente | **Editar** | Se actualizan los campos enviados de ese registro |
Para **eliminar**, edita el registro con el campo `eliminado` a `1`:
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"eliminado": "1"
}
```
No hay endpoint DELETE. El borrado es lógico y se hace por WriteOperations.
### Nombres de campo (`pr_*`) [#nombres-de-campo-pr_]
Cada campo se identifica por su columna PostgreSQL, con formato `pr_XXXXXXXXX`. Consulta los nombres de cada sección desde:
* **Play Dinaup** → módulo Desarrollo → Esquema
* **Dinaup Desktop** (app Windows) → configuración de la sección
* **doc-flex.dinaup.com** → referencia de todas las secciones
* **SDK .NET ([MyDinaup](/docs/desarrollo/dotnet/mydinaup))** → la librería tipada de tu esquema; cada columna `pr_XXXXXXXXX` con un nombre legible
Los valores viajan siempre como texto (`"100.00"`, `"1"`), no como números ni booleanos.
### Formato 1: Objeto simple [#formato-1-objeto-simple]
Un solo registro como diccionario de campos:
```json
{
"id": "",
"pr_cliente": "id-del-cliente",
"pr_importe": "100.00"
}
```
### Formato 2: Objeto con lista (padre + hijos) [#formato-2-objeto-con-lista-padre--hijos]
Para secciones con una sección lista asociada (por ejemplo, Factura + Líneas):
```json
{
"Main": {
"id": "",
"pr_cliente": "id-del-cliente"
},
"List": [
{"pr_item": "producto-1", "pr_cantidad": "10"},
{"pr_item": "producto-2", "pr_cantidad": "20"}
]
}
```
### Formato 3: Lote de objetos [#formato-3-lote-de-objetos]
Varios registros en una sola petición:
```json
[
{"id": "", "pr_campo1": "valor1"},
{"id": "", "pr_campo1": "valor2"}
]
```
### Formato 4: Lote de objetos con listas [#formato-4-lote-de-objetos-con-listas]
Varios registros padre-hijo en una sola petición:
```json
[
{
"Main": {"id": "", "pr_campo": "valor1"},
"List": [{"pr_item": "val1"}]
},
{
"Main": {"id": "", "pr_campo": "valor2"},
"List": [{"pr_item": "val2"}]
}
]
```
**Ejemplo completo (crear un registro):**
```bash
curl -X POST "https://webhook.dinaup.com/api/writeoperations?sectionId=&FieldPrimary=id&scripts=true" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"id": "",
"pr_cliente": "id-del-cliente",
"pr_importe": "100.00"
}'
```
Un objeto simple y un lote fallan entero si una operación es inválida. Trata siempre el código de respuesta antes de dar la escritura por buena.
Las escrituras respetan los permisos del usuario de la clave. Si ese usuario no puede escribir en una sección, la operación se rechaza.
***
## Herramientas fiscales [#herramientas-fiscales]
Validan un identificador fiscal contra el censo oficial. Requieren token y limitan por IP.
### `GET /api/tools/aeat/NIFCheck`: Validar NIF/CIF [#get-apitoolsaeatnifcheck-validar-nifcif]
Valida un NIF o CIF contra la Agencia Estatal de Administración Tributaria.
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ------ | ----------- | --------------------------------- |
| `nif` | string | Sí | NIF o CIF a validar |
| `nombre` | string | Sí | Nombre o razón social del titular |
```bash
curl -X GET "https://webhook.dinaup.com/api/tools/aeat/NIFCheck?nif=B00000000&nombre=Empresa%20SL" \
-H "Authorization: Bearer "
```
### `GET /api/tools/vies/VATCheck`: Validar VIES [#get-apitoolsviesvatcheck-validar-vies]
Valida un número de identificación fiscal intracomunitario contra el sistema VIES. Útil antes de emitir una factura con IVA al 0 % a un operador intracomunitario.
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ------ | ----------- | ------------------------------ |
| `nif` | string | Sí | NIF intracomunitario a validar |
```bash
curl -X GET "https://webhook.dinaup.com/api/tools/vies/VATCheck?nif=ESB00000000" \
-H "Authorization: Bearer "
```
***
## Códigos de respuesta [#códigos-de-respuesta]
| Código | Significado |
| ------ | ----------------------------------------------------------------------------------- |
| `200` | Operación correcta |
| `400` | Parámetros o cuerpo inválidos (falta `sectionId`, `FieldPrimary`, GUID mal formado) |
| `401` | Token inválido o ausente |
| `403` | El usuario de la clave no tiene permiso para esta operación |
| `404` | Recurso no encontrado (informe, documento, sección) |
| `429` | Superado el límite de tasa. Reintenta pasados los segundos de `Retry-After` |
| `500` | Error interno del servidor |
***
## Playground [#playground]
Prueba todos los endpoints y copia el Token Bearer de cada clave API, sin herramientas externas:
[Abrir el Playground de Webhooks](https://play.dinaup.com/App/Dev/IncomingWebhooks)
# API y Webhooks (/docs/desarrollo/integraciones/webhook)
Dinaup integra en dos direcciones. Eliges según quién empieza la conversación.
| Dirección | Quién llama | Para qué |
| ------------------------ | ----------- | -------------------------------------------------------------------------- |
| **API REST** (entrantes) | Tú → Dinaup | Lees informes, generas documentos y escribes registros con peticiones HTTP |
| **Webhooks salientes** | Dinaup → Tú | Dinaup avisa a tu servidor cuando se crea o modifica un registro |
Las dos usan el mismo servidor: `https://webhook.dinaup.com`.
***
## API REST: tú preguntas, Dinaup responde [#api-rest-tú-preguntas-dinaup-responde]
Envías peticiones HTTP y recibes JSON. Sirve para conectar una tienda online, alimentar un dashboard, importar datos en lote o sincronizar con otro sistema desde cualquier lenguaje.
Cinco endpoints y dos herramientas de validación fiscal:
| Endpoint | Método | Para qué |
| -------------------------- | ------ | ---------------------------------------------------- |
| `/` | `GET` | Ping. Comprueba que el servidor responde |
| `/api/whoami` | `GET` | Devuelve el usuario asociado a tu clave |
| `/api/reports` | `POST` | Ejecuta un informe de Flex y devuelve sus filas |
| `/api/dynamicdocuments` | `POST` | Renderiza un documento dinámico |
| `/api/writeoperations` | `POST` | Crea, edita o elimina registros en cualquier sección |
| `/api/tools/aeat/NIFCheck` | `GET` | Valida un NIF/CIF contra la AEAT |
| `/api/tools/vies/VATCheck` | `GET` | Valida un NIF intracomunitario contra el VIES |
Cada petición viaja firmada con un **Token Bearer** en la cabecera. El token hereda los permisos del usuario de la clave: solo lee y escribe lo que ese usuario puede ver.
→ [Referencia completa de endpoints](/docs/desarrollo/integraciones/webhook/entrantes)
***
## Webhooks salientes: Dinaup te avisa [#webhooks-salientes-dinaup-te-avisa]
Configuras una URL y Dinaup le envía un `POST` cuando cambia un registro de la sección que vigilas. Reaccionas al momento, sin consultar la API en bucle.
1. Eliges la sección a vigilar y si disparas en altas, en modificaciones o en ambas.
2. Acotas con campos disparadores y campos obligatorios.
3. Tu servidor recibe el registro antes y después del cambio.
→ [Configuración de webhooks salientes](/docs/desarrollo/integraciones/webhook/salientes)
***
## Qué dirección uso [#qué-dirección-uso]
| Necesitas | Usa |
| ---------------------------------------- | --------------------------------------------------------------------------------------------- |
| Leer o escribir datos desde tu código | API REST |
| Crear facturas desde una tienda online | API REST: `POST /api/writeoperations` |
| Volcar un informe a un dashboard | API REST: `POST /api/reports` |
| Enterarte al instante de una venta nueva | Webhook saliente en la sección de ventas |
| Sincronizar clientes con un CRM | Webhook saliente (avisa) + API REST (lee el detalle) |
| Automatizar sin escribir código | Webhook saliente hacia [n8n, Make o Zapier](/docs/desarrollo/integraciones/zapier-make-y-n8n) |
***
## Playground [#playground]
Prueba los endpoints y simula un webhook saliente desde Dinaup, sin herramientas externas. El Playground también genera el Token Bearer de cada clave API.
[Abrir el Playground de Webhooks](https://play.dinaup.com/App/Dev/IncomingWebhooks)
# Webhooks salientes (/docs/desarrollo/integraciones/webhook/salientes)
Un webhook saliente hace que Dinaup avise a tu servidor cuando cambia un registro. Configuras una URL, y Dinaup le envía un `POST` en cuanto se cumple lo que definiste. Reaccionas al momento, sin consultar la API en bucle.
***
## Cómo funciona [#cómo-funciona]
```
[Dinaup] → se crea o modifica un registro → se cumplen las condiciones → POST → [Tu servidor]
```
1. Un usuario o un proceso crea o modifica un registro en la sección que vigilas.
2. Dinaup comprueba las condiciones del webhook (evento, campos disparadores, campos obligatorios).
3. Si se cumplen, envía un `POST` a tu URL con el registro antes y después del cambio.
***
## Configuración [#configuración]
Los webhooks salientes se crean desde el módulo **Desarrollo** de Play Dinaup. Cada uno se guarda activo desde el momento en que lo creas.
### Campos del formulario [#campos-del-formulario]
| Campo | Descripción |
| --------------------------- | ----------------------------------------------------------------- |
| **Título** | Nombre con el que identificas el webhook |
| **Sección** | La tabla que vigilas: Ventas/Ingresos, Entidades, Productos… |
| **Disparar Modificaciones** | Envía cuando se actualiza un registro existente |
| **Disparar Nuevos** | Envía cuando se crea un registro |
| **URL** | La dirección de tu servidor que recibe el `POST` |
| **Bearer Token** | Opcional. Token que Dinaup incluye en la cabecera `Authorization` |
| **Campos Disparadores** | Solo dispara si cambia alguno de estos campos |
| **Campos Obligatorios** | Solo dispara si estos campos están rellenos |
Marca **Modificaciones**, **Nuevos** o ambos: son los dos eventos que disparan el aviso.
### Acotar el disparo [#acotar-el-disparo]
Dos filtros evitan avisos con datos irrelevantes o incompletos:
* **Campos disparadores.** Si eliges campos aquí, el webhook solo salta cuando cambia alguno de ellos. Un cambio en otro campo no dispara. Si no eliges ninguno, cualquier cambio dispara.
* **Campos obligatorios.** El webhook no salta hasta que estos campos tengan valor. Evita, por ejemplo, avisar de un borrador de factura sin cliente.
Al usar campos obligatorios, eliges el modo:
| Modo | Cuándo dispara |
| ---------------------------------- | ---------------------------------------------------- |
| **Todos los campos seleccionados** | Solo si todos los campos obligatorios están rellenos |
| **Al menos un campo** | Basta con que uno tenga valor |
### Seguridad [#seguridad]
Rellena el **Bearer Token** para que Dinaup lo mande en cada petición:
```
Authorization: Bearer
```
Tu servidor compara ese token con el que configuraste y descarta lo que no cuadre. El campo es opcional; sin él, la petición llega sin cabecera `Authorization`.
***
## Payload [#payload]
Dinaup envía un `POST` con el cuerpo en JSON. Dos objetos: el registro antes del cambio y después.
```json
{
"previousData": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"pr_cliente": "Cliente Antiguo",
"pr_importe": "100.00"
},
"newData": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"pr_cliente": "Cliente Nuevo",
"pr_importe": "150.00"
}
}
```
* **`previousData`**: el registro tal como estaba antes.
* **`newData`**: el registro tras el cambio.
Comparas los dos objetos para saber qué campos cambiaron. En un alta, ambos traen el registro recién creado. Cada campo llega por su nombre `pr_*` (la columna PostgreSQL de la sección) y su valor como texto.
Para traducir los nombres `pr_*` a campos legibles, consulta el esquema de la sección en Play Dinaup → módulo Desarrollo → Esquema, o en doc-flex.dinaup.com.
***
## Buenas prácticas [#buenas-prácticas]
| Práctica | Motivo |
| ------------------------------------ | --------------------------------------------- |
| Responde con `2xx` en cuanto recibas | Tu servidor confirma que la entrega llegó |
| Verifica el Bearer Token | Descarta peticiones que no vengan de Dinaup |
| Procesa en asíncrono | Encola el trabajo pesado y responde rápido |
| Registra lo que recibes | Te da rastro para depurar |
| Usa campos disparadores | Evitas avisos por cambios que no te interesan |
***
## Casos de uso [#casos-de-uso]
| Caso | Configuración |
| -------------------------------------- | ------------------------------------------------------------------------------------- |
| Avisar a Slack de una venta nueva | Sección Ventas/Ingresos · Nuevos · URL de n8n/Make hacia Slack |
| Sincronizar clientes con un CRM | Sección Entidades · Nuevos + Modificaciones · Campos disparadores: Nombre, NIF, Email |
| Actualizar stock en la tienda online | Sección Productos · Modificaciones · Campo disparador: Stock |
| Email de bienvenida a clientes nuevos | Sección Entidades · Nuevos · Campo obligatorio: Email |
| Generar albarán al confirmar un pedido | Sección Ventas/Ingresos · Modificaciones · Campo disparador: Estado |
***
## Probar antes de conectar [#probar-antes-de-conectar]
El Playground incluye un simulador: eliges un webhook y un registro, y Dinaup manda el `POST` a la URL que le des con el payload real. Ves el cuerpo antes de programar tu receptor.
[Abrir el Playground de Webhooks](https://play.dinaup.com/App/Dev/OutcomingWebhooks)
# Dinaup & n8n (/docs/desarrollo/integraciones/zapier-make-y-n8n/dinaup-and-n8n)
Lanza una solicitud HTTP desde **n8n** con tus credenciales de **Dinaup**.
### Crear una nueva credencial de tipo Header Auth [#crear-una-nueva-credencial-de-tipo-header-auth]
1. Abre la sección **Credenciales** en n8n.
2. Pulsa **Crear nueva** y selecciona **Header Auth**.
### Rellenar los campos de la credencial [#rellenar-los-campos-de-la-credencial]
* En el campo **Name**, escribe: `Authorization`
* En el campo **Value**, escribe: `Bearer XXXXXXXXXXXXXXX`
*(Sustitúyelo por el token Webhook que te proporciona Dinaup)*
* Asigna un nombre en la parte de arriba para identificarla: `Dinaup MiEmpresa`
* Pulsa **Guardar**.
### Agregar un nodo HTTP Request al flujo [#agregar-un-nodo-http-request-al-flujo]
* Abre la configuración del nodo **HTTP Request**.
* En el apartado **Authentication**, selecciona la credencial creada.
* Configura la URL, el método y los datos necesarios según el endpoint de Dinaup.
# Zapier, Make y n8n (/docs/desarrollo/integraciones/zapier-make-y-n8n)
Conecta **Dinaup** con plataformas de automatización como **Zapier**, **Make** o **n8n** mediante **webhooks**. Opcionalmente, un **Cloudflare Worker** transforma y protege las peticiones antes de que lleguen a Dinaup.
### Conexión vía Webhook [#conexión-vía-webhook]
Dinaup recibe y envía datos mediante webhooks estándar. Genera una URL de webhook en tu escenario de Zapier, Make o n8n y configúrala directamente en Dinaup.
## Simplifica los webhooks (opcional) [#simplifica-los-webhooks-opcional]
Intercalar un **Cloudflare Worker** entre Dinaup y tu herramienta de automatización transforma las URLs o el cuerpo de las solicitudes para adaptarlas al formato que esperan Make, Zapier o n8n.
# Datos (/docs/desarrollo/recursos/datos)
# Países Unión Europea (/docs/desarrollo/recursos/datos/paises-union-europea)
## Códigos [#códigos]
Listado de códigos **ISO 3166-1 alfa-2** de los países de la Unión Europea. Se utilizan en facturación, Verifactu, SII y validaciones fiscales automáticas.
```
AT, BE, BG, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IE, IT, LV, LT, LU, MT, NL, PL, PT, RO, SK, SI, ES, SE
```
## Código y nombre [#código-y-nombre]
Código y nombre de cada país miembro de la UE.
| Código | País |
| ------ | -------------------- |
| AT | Austria |
| BE | Bélgica |
| BG | Bulgaria |
| HR | Croacia |
| CY | Chipre |
| CZ | Chequia (Rep. Checa) |
| DK | Dinamarca |
| EE | Estonia |
| FI | Finlandia |
| FR | Francia |
| DE | Alemania |
| GR | Grecia |
| HU | Hungría |
| IE | Irlanda |
| IT | Italia |
| LV | Letonia |
| LT | Lituania |
| LU | Luxemburgo |
| MT | Malta |
| NL | Países Bajos |
| PL | Polonia |
| PT | Portugal |
| RO | Rumanía |
| SK | Eslovaquia |
| SI | Eslovenia |
| ES | España |
| SE | Suecia |
### Fuentes [#fuentes]
* [europa.eu/principles-countries-history/eu-countries\_en](https://european-union.europa.eu/principles-countries-history/eu-countries_en)
# Flujo de desarrollo (/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo)
Esta página describe el **ciclo de trabajo recomendado** para construir sobre Dinaup con Terminal: desde que te conectas a un tenant hasta que publicas tu trabajo como módulo. No entra en el detalle conceptual de cada pieza (eso vive en la documentación de [Flex](/docs/desarrollo/flex)), sino en **el orden y el porqué** de cada fase.
Terminal organiza este recorrido como un proceso por pasos. No tienes que recorrerlo entero cada vez: en el día a día saltarás directo a la fase que toque (editar un campo, ajustar un informe). Pero la primera vez, y antes de cada publicación, conviene tenerlo claro de principio a fin.
Antes de empezar necesitas Terminal instalado y conectado a un tenant con **licencia Flex** activa. Si aún no lo tienes, empieza por la [guía de la sección](/docs/desarrollo/recursos/dinaup-terminal).
***
## Las cuatro fases del ciclo [#las-cuatro-fases-del-ciclo]
Estas son las fases. Las tres primeras son **construcción** (defines cómo se comporta el sistema); la última es **distribución** (empaquetas y publicas lo construido).
| Fase | Qué haces | Dónde se explica el concepto |
| ------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| **1. Conectar** | Abres Terminal y eliges el tenant sobre el que vas a trabajar. | Esta página |
| **2. Modelar datos** | Creas y editas secciones y sus campos. | [Secciones](/docs/desarrollo/flex/secciones) · [Campos](/docs/desarrollo/flex/campos) |
| **3. Dar comportamiento** | Añades algoritmos, informes y documentos dinámicos. | [Flex](/docs/desarrollo/flex) |
| **4. Publicar** | Empaquetas todo como módulo y lo distribuyes por un canal. | [Flex](/docs/desarrollo/flex) |
***
## El ciclo en detalle [#el-ciclo-en-detalle]
### Conéctate al tenant [#conéctate-al-tenant]
Al abrir Terminal, lo primero es elegir **sobre qué tenant** vas a trabajar. Un tenant es el entorno de un cliente o proyecto concreto: tiene sus propias secciones, datos y configuración.
Trabaja siempre sabiendo dónde estás. Modelar contra el tenant equivocado es la forma más fácil de romper algo que funcionaba.
Lo que editas con Flex afecta a **todos los usuarios** de ese tenant. Si vas a probar cambios delicados, hazlo primero en un entorno de pruebas, no sobre el tenant de producción de un cliente.
### Crea o edita una sección [#crea-o-edita-una-sección]
Una **sección** es una tabla de datos: clientes, facturas, productos, lo que tu solución necesite. Es el cimiento de todo lo demás, así que empieza por aquí.
Decide qué tipo de información va a guardar la sección y créala. Si vas a tener varias secciones que comparten campos comunes, plantéate apoyarlas en una **sección base** para no repetir estructura.
→ El modelo completo de secciones está en [Secciones](/docs/desarrollo/flex/secciones).
### Añade los campos [#añade-los-campos]
Dentro de cada sección defines los **campos** (sus columnas). Para cada campo eliges tres cosas:
* **Tipo**: texto, número, decimal, fecha, sí/no, relación con otra sección…
* **Rol**: qué papel cumple ese dato dentro de la sección.
* **Validación y comportamiento**: si es obligatorio, su rango o formato, su valor por defecto, si se autorrellena a partir de otros campos o se bloquea como solo lectura.
Modela los campos pensando en cómo se van a rellenar y consultar después. Un buen diseño de campos te ahorra cálculos y correcciones más adelante.
→ Tipos, roles y validaciones en detalle en [Campos](/docs/desarrollo/flex/campos).
### Da comportamiento con algoritmos [#da-comportamiento-con-algoritmos]
Cuando un valor no se introduce a mano sino que **se calcula**, lo resuelves con un **algoritmo**: el total de una línea, un acumulado, un dato traído de otra sección.
Los algoritmos son el motor de cálculo de Flex. Se usan para rellenar campos, generar columnas en informes y componer documentos. Defínelos una vez y reutilízalos donde haga falta.
→ Tipos de algoritmo y cómo se conectan: [Flex](/docs/desarrollo/flex).
### Construye informes [#construye-informes]
Un **informe** convierte tus secciones en listados y consultas útiles: eliges columnas, aplicas filtros y orden, agrupas y añades columnas calculadas con algoritmos.
Es la forma de explotar la información que ya estás guardando, sin escribir consultas a mano. Si una solución necesita que el usuario "vea" o "filtre" datos, casi siempre es un informe.
### Genera documentos dinámicos [#genera-documentos-dinámicos]
Un **documento dinámico** combina los datos de un registro con una plantilla para producir una salida con formato: una factura, un presupuesto, un correo, una respuesta para una integración.
Son la capa de presentación: lo que el sistema entrega hacia fuera. Diséñalos cuando tu solución tenga que **emitir** algo, no solo guardarlo.
### Publica como módulo [#publica-como-módulo]
Cuando el conjunto funciona, **empaquetas** todo el trabajo (secciones, campos, algoritmos, informes y documentos) en un **módulo** reutilizable. Es el paso que convierte una personalización suelta en algo distribuible y repetible.
Publicar tiene su propio mini-recorrido, que cubre la siguiente sección. El detalle de la ventana de publicación está en [Publicar un módulo](/docs/desarrollo/recursos/dinaup-terminal/ventanas/publicar-un-modulo).
***
## La fase de publicación [#la-fase-de-publicación]
Publicar no es "subir y ya". Terminal te guía por una serie de comprobaciones para que el módulo llegue completo y a quien debe. A grandes rasgos:
### Prepara el módulo [#prepara-el-módulo]
Reúnes en el módulo todas las piezas que has construido. Es el momento de revisar que no falte nada y que lo que incluyes tenga sentido como una unidad coherente.
### Valida las dependencias [#valida-las-dependencias]
Un módulo suele apoyarse en otras piezas (otras secciones, otros módulos). Terminal **comprueba esas dependencias** antes de dejarte publicar, para que el módulo no llegue al destino con cabos sueltos que lo dejarían a medio funcionar.
Resolver las dependencias antes de publicar evita el problema clásico: instalar un módulo que "casi" funciona porque le falta algo de lo que dependía en origen.
### Asigna versión y canal [#asigna-versión-y-canal]
Cada publicación lleva una **versión** (para saber qué cambió respecto a la anterior) y se envía por un **canal** (que determina quién recibe ese módulo y cuándo).
Pensar versión y canal como parte de la publicación (y no como un detalle administrativo) es lo que te permite distribuir cambios de forma ordenada y poder volver atrás si hace falta.
***
## Cómo encaja con el resto [#cómo-encaja-con-el-resto]
* El **qué** (el modelo de secciones, campos, algoritmos, informes y documentos) vive en la documentación de [Flex](/docs/desarrollo/flex). Esta página es solo el **orden** en que lo aplicas desde Terminal.
* El **detalle de cada ventana** del Terminal (qué opción es cada cosa al diseñar secciones, editar campos o escribir algoritmos) está en [Ventanas del Terminal](/docs/desarrollo/recursos/dinaup-terminal/ventanas/disenar-secciones-y-campos).
* La **instalación y la conexión inicial** al tenant las cubre la [guía de la sección](/docs/desarrollo/recursos/dinaup-terminal).
* La mecánica de **empaquetar y distribuir** (módulos, versiones, canales) se desarrolla en [Publicar un módulo](/docs/desarrollo/recursos/dinaup-terminal/ventanas/publicar-un-modulo); aquí solo se sitúa dentro del ciclo.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. El ciclo completo es la foto general. En el día a día entras directo a lo que necesites: ajustar un campo, retocar un informe, sacar una nueva versión de un módulo. El recorrido entero importa sobre todo la primera vez y antes de cada publicación.
De abajo arriba: primero las secciones y sus campos (los datos), después los algoritmos (los cálculos), y por último informes y documentos (cómo se explotan y se presentan). Cada capa se apoya en la anterior.
Para que el módulo llegue al destino entero. Si una pieza depende de otra que no incluyes, el módulo se instalaría incompleto y fallaría. La validación detecta esos huecos antes de publicar, no después.
En la documentación de Flex. Allí está el concepto de secciones, campos, algoritmos, informes y documentos. Esta página se queda en el flujo: qué haces, en qué orden y por qué.
***
→ [Volver a Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal)
→ [Secciones](/docs/desarrollo/flex/secciones)
→ [Campos](/docs/desarrollo/flex/campos)
→ [Documentación de Flex](/docs/desarrollo/flex)
# Dinaup Terminal (/docs/desarrollo/recursos/dinaup-terminal)
**Dinaup Terminal** (también llamado **Dinaup Desktop**) es una aplicación de escritorio para Windows pensada para el trabajo técnico sobre Dinaup. Es el entorno desde el que personal cualificado y partners **personalizan un tenant con [Flex](/docs/desarrollo/flex)** (crean secciones, campos, algoritmos, informes y documentos) y **empaquetan esas personalizaciones como módulos** para distribuirlas.
No es una herramienta para el usuario final. Quien factura, atiende clientes o controla el inventario trabaja desde la aplicación web de Dinaup. Terminal está dirigido a quien construye y mantiene ese sistema por debajo.
Para usar Dinaup Terminal necesitas una **licencia Flex** activa en el tenant que vas a personalizar. Sin ella puedes instalar y abrir la app, pero no editar la estructura.
***
## Para quién es [#para-quién-es]
Terminal está hecho para perfiles que intervienen en la **configuración profunda** del producto:
| Perfil | Para qué lo usa |
| ------------------------ | ---------------------------------------------------------------------------------------------- |
| **Personal técnico** | Modela las secciones, campos y algoritmos de un tenant; ajusta informes y documentos a medida. |
| **Partner / integrador** | Construye una solución vertical sobre Dinaup y la publica como módulo reutilizable. |
***
## Qué puedes hacer desde Terminal [#qué-puedes-hacer-desde-terminal]
Terminal es la puerta de entrada al trabajo con Flex sobre un tenant real:
* **Diseñar la estructura de datos**: crear y editar [secciones](/docs/desarrollo/flex/secciones) y [campos](/docs/desarrollo/flex/campos).
* **Automatizar y calcular**: definir [algoritmos](/docs/desarrollo/flex/algoritmos) y [scripts](/docs/desarrollo/flex/scripts) que reaccionan a eventos.
* **Explotar la información**: construir [informes](/docs/desarrollo/flex/informes) y [documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos).
* **Empaquetar y publicar**: agrupar todo ese trabajo en módulos y distribuirlos por canales.
El **qué** (el modelo conceptual de secciones, campos, algoritmos, informes y documentos) vive en la documentación de **[Flex](/docs/desarrollo/flex)**. Esta sección cubre el **cómo y el dónde**: instalar la herramienta, conectarla a un tenant y seguir el ciclo de desarrollo y publicación.
***
## En esta sección [#en-esta-sección]
Instala Dinaup Terminal en Windows y conéctalo al tenant que vas a personalizar.
Empaqueta tus personalizaciones como módulos y distribúyelos por canales.
El ciclo de trabajo recomendado: diseñar, probar y publicar cambios sobre un tenant.
Personalizar un tenant con Flex modifica cómo se comporta el sistema para todos sus usuarios. Trabaja con criterio y prueba cada cambio antes de darlo por bueno.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La aplicación web es donde el usuario final trabaja a diario (facturar, vender, gestionar). Dinaup Terminal es el entorno técnico desde el que se personaliza ese sistema con Flex y se publican módulos. Una es para usar Dinaup; la otra, para construirlo y mantenerlo.
Buena parte del trabajo de Flex (secciones, campos, informes) se configura sin escribir código. Para lógica avanzada existen los algoritmos y DinaScript. En cualquier caso, es una herramienta para perfiles técnicos, no para el usuario final.
Sí. Necesitas una licencia Flex activa en el tenant que vas a personalizar. Sin ella no podrás editar su estructura.
En la documentación de Flex. Esta sección se centra en la herramienta de escritorio; Flex explica los conceptos que manejas con ella.
***
→ [Documentación de Flex](/docs/desarrollo/flex)
# Instalación y conexión (/docs/desarrollo/recursos/dinaup-terminal/instalacion-y-conexion)
**Dinaup Terminal** es la aplicación de escritorio para abrir Dinaup en Windows. En esta página instalas el programa, aceptas la licencia y conectas la aplicación a tu organización para empezar a trabajar.
El proceso completo son dos pasos: **instalar** (con winget o el ejecutable) y **conectar** (indicar a qué organización entras y con qué usuario).
***
## Antes de empezar [#antes-de-empezar]
Para instalar y conectar Dinaup Terminal necesitas:
* Un **equipo con Windows**.
* Tus **datos de acceso**: el servidor de tu organización, tu **licencia** y un **usuario** con su contraseña. Si no los tienes, pídelos a quien administre Dinaup en tu empresa.
La instalación no requiere permisos de administrador: la aplicación se instala dentro de tu perfil de usuario.
***
## Instalar Dinaup Terminal [#instalar-dinaup-terminal]
Tienes dos formas de instalarlo (winget o la descarga del ejecutable); las dos dejan la misma aplicación, lista para abrir.
### Instálalo [#instálalo]
La forma recomendada es **winget**, el gestor de paquetes de Windows. Abre PowerShell o el Símbolo del sistema y ejecuta:
```bash
winget install Dinaup.CLI
```
**¿Sin winget?** Descarga el ejecutable y ábrelo con doble clic; la primera vez se copia a tu perfil de usuario y queda listo para las siguientes.
[**Descargar Dinaup Terminal**](https://dinaupcdn.com/dl/latest/DinaupLauncher.exe)
### Acepta la licencia [#acepta-la-licencia]
Al abrirse por primera vez, Dinaup Terminal te muestra las **condiciones de uso**. Léelas y acéptalas para continuar. Sin aceptar la licencia, la aplicación no se abre.
Dinaup Terminal se mantiene actualizado por su cuenta. No tienes que reinstalarlo cada vez que sale una versión nueva: la aplicación comprueba si hay actualización y la aplica sola.
***
## Conectar a tu organización [#conectar-a-tu-organización]
Una vez instalada, Dinaup Terminal necesita saber **a qué organización te conectas** y **quién eres**. Esto se hace una sola vez por equipo; después, la aplicación recuerda tu acceso.
Para conectar necesitas tres datos:
| Dato | Qué es |
| ------------ | ------------------------------------------------------------------------------------------------------ |
| **Servidor** | La dirección de la organización a la que perteneces. Identifica tu instancia de Dinaup. |
| **Licencia** | El identificador de tu empresa dentro de ese servidor. Determina los datos a los que accedes. |
| **Usuario** | Tu cuenta personal (usuario y contraseña). Determina qué puedes ver y hacer dentro de la organización. |
Introduce los tres datos en la pantalla de acceso de Dinaup Terminal y confirma. Si son correctos, la aplicación valida tu identidad y abre Dinaup con tu organización ya cargada.
La próxima vez que abras Dinaup Terminal, entrará directamente con la última organización que usaste: no tendrás que volver a teclear el servidor ni la licencia.
### Si gestionas varias organizaciones [#si-gestionas-varias-organizaciones]
Dinaup Terminal puede guardar el acceso a **más de una organización** en el mismo equipo y dejarte elegir cuál abrir cada vez. Es útil si trabajas con varias empresas o entornos. Tienes el detalle de cómo manejar varias licencias y los comandos disponibles en el [resumen de Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal).
***
## Qué ves al entrar [#qué-ves-al-entrar]
Lo que puedes hacer dentro de Dinaup depende del **usuario** con el que te conectas. Cada usuario tiene un rol que define su nivel de acceso:
| Rol | Qué puede hacer |
| ----------------- | ------------------------------------------------------------------------------------------------------------ |
| **Administrador** | Acceso completo a la organización: trabajar con todos los datos y gestionar la configuración y los usuarios. |
| **Desarrollador** | Acceso orientado a configurar y adaptar el sistema, además del trabajo habitual. |
| **Lectura** | Acceso de solo consulta: puede ver la información, pero no modificarla. |
Si esperas poder hacer algo y la opción no aparece o está bloqueada, lo más probable es que tu usuario no tenga ese permiso. Habla con quien administre Dinaup en tu organización para revisar tu rol.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Dinaup Terminal se instala dentro de tu perfil de usuario, así que no hace falta ser administrador del equipo para descargarlo y abrirlo.
No. La aplicación se actualiza sola: cada vez que la abres, comprueba si hay una versión más reciente y la aplica antes de continuar.
De quien administre Dinaup en tu empresa. El servidor y la licencia identifican tu organización; el usuario y la contraseña son tu cuenta personal de acceso.
Lo que ves depende del rol de tu usuario (administrador, desarrollador o lectura). Si te falta una opción, probablemente tu usuario no tiene ese permiso. Pídeselo a quien administre tu organización.
***
→ [Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal)
# Módulos y canales (/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales)
Dinaup no es un bloque único: la funcionalidad se reparte en **módulos**, paquetes versionados que se publican en una galería compartida y se instalan en tu licencia. Cada módulo avanza por **canales** de madurez (desarrollo, beta, producción), y tu licencia decide de qué canal recibe las versiones. Entender esto te ayuda a saber **qué tienes instalado, qué versión es y por qué** unas licencias ven novedades antes que otras.
***
## Qué es un módulo [#qué-es-un-módulo]
Un **módulo** es un paquete que agrupa funcionalidad relacionada y se publica con un **número de versión**. Dentro lleva las piezas que definen cómo se comporta esa parte de Dinaup: las secciones donde guardas datos, los campos de cada sección, los algoritmos de cálculo y las pantallas asociadas.
Lo importante a nivel conceptual:
* Un módulo es **versionado**: cada publicación tiene su versión, y se puede actualizar a una más nueva sin rehacer nada manualmente.
* Un módulo es **autocontenido**: trae todo lo que necesita para funcionar, así su instalación es predecible.
* Un módulo es **compartido**: vive en una galería común desde la que cualquier licencia compatible puede instalarlo.
No confundas un módulo con una sección. Una [sección](/docs/desarrollo/flex/secciones) es un sitio donde guardas registros. Un módulo es el **paquete** que puede traer varias secciones, sus campos y sus algoritmos de una vez, listos para usar.
***
## La galería compartida [#la-galería-compartida]
Los módulos se publican en una **galería** común. Es el catálogo desde el que tu licencia instala y actualiza funcionalidad, sin que tengas que copiar nada entre equipos ni reconstruir configuraciones a mano.
Esto te da dos cosas:
* **Reutilización**: una funcionalidad publicada una vez está disponible para todas las licencias compatibles.
* **Consistencia**: todas las licencias que instalan el mismo módulo en la misma versión obtienen exactamente el mismo comportamiento.
***
## Canales de madurez [#canales-de-madurez]
No todas las licencias deben recibir la misma versión de un módulo al mismo tiempo. Una novedad recién hecha conviene probarla antes de soltarla a quien trabaja en producción. Para eso existen los **canales**: etapas de madurez por las que va pasando cada versión.
| Canal | Para qué es | Quién lo usa |
| -------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| **Desarrollo** | Versión en construcción, sujeta a cambios constantes. Sirve para crear y probar mientras se trabaja. | Quien está desarrollando el módulo. |
| **Beta** | Versión candidata, ya estable pero en validación. Sirve para probar en condiciones reales antes del salto final. | Equipos de prueba y validación. |
| **Producción** | Versión publicada y estable. Es la que se usa para trabajar de verdad. | El cliente final, en su día a día. |
El sentido es siempre el mismo: una versión nace en **desarrollo**, cuando madura pasa a **beta** para validarse, y cuando se considera estable se publica en **producción**. Cada canal es un peldaño más fiable que el anterior.
**Producción** y **release** son lo mismo: el canal estable, el que reciben los clientes finales. Verás los dos nombres según el contexto.
***
## La licencia fija tu canal [#la-licencia-fija-tu-canal]
Cada licencia tiene asignado **un canal**, y ese canal determina qué versión de cada módulo recibe. La asignación **no la eliges tú sobre la marcha**: viene fijada por la licencia.
Esto significa que:
* Una licencia de **producción** recibe versiones estables. **No** puede instalar módulos en versión de desarrollo o beta: el selector de canal está bloqueado en estable.
* Una licencia de **beta** o **desarrollo** sí puede trabajar con versiones más tempranas, porque su propósito es justamente probar.
El bloqueo es deliberado y te protege: evita que un entorno de trabajo real acabe ejecutando una versión a medio hacer. Un cliente que trabaja en producción **nunca** se topa por accidente con código experimental.
Si esperas ver una novedad y no aparece, lo más probable es que tu licencia esté en el canal de **producción** y la novedad todavía viva en **beta** o **desarrollo**. Llegará cuando esa versión se promocione al canal estable.
***
## Autoactualización del núcleo [#autoactualización-del-núcleo]
El **núcleo** de Dinaup se mantiene al día solo. Cuando hay una versión nueva publicada en el canal que corresponde a tu licencia, el sistema la incorpora: no tienes que reinstalar nada ni perseguir actualizaciones.
Así, abriendo Dinaup con normalidad, trabajas siempre sobre la versión que tu canal considera vigente. La actualización es transparente y respeta el canal asignado: una licencia de producción se actualiza a la última versión **estable**, nunca a una de prueba.
***
## Compatibilidad de versión [#compatibilidad-de-versión]
Como cada módulo se publica con su versión, Dinaup tiene en cuenta la **compatibilidad** entre las piezas. Un módulo declara con qué versiones del núcleo (y de otros módulos de los que dependa) funciona, de modo que solo se instalan o actualizan combinaciones que encajan.
En la práctica:
* No se aplica una versión de módulo que no sea compatible con el núcleo que tienes.
* Las actualizaciones automáticas respetan esas reglas: si una versión nueva exigiera algo que aún no tienes, espera hasta que el conjunto sea coherente.
El objetivo es que nunca te quedes con una combinación de piezas que no funcionen juntas.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Una sección es un sitio concreto donde guardas registros. Un módulo es el paquete versionado que puede traer varias secciones, sus campos y sus algoritmos de una sola vez. Instalas un módulo; dentro de él aparecen las secciones.
Porque tu licencia lo fija. Si es de producción, el selector de canal queda bloqueado en estable a propósito, para que un entorno de trabajo real no ejecute versiones a medio hacer. Los canales de desarrollo y beta son para licencias destinadas a probar.
No. El núcleo se actualiza solo a la versión vigente de tu canal. Una licencia de producción recibe siempre la última versión estable, sin que tengas que reinstalar ni perseguir actualizaciones.
Casi siempre es cuestión de canal: la novedad todavía está en beta o desarrollo y tu licencia está en producción. Aparecerá cuando esa versión se promocione al canal estable.
Son el mismo canal: el estable, el que reciben los clientes finales. Es solo una cuestión de nombre según el contexto.
***
→ [Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal)
→ [Secciones (Flex)](/docs/desarrollo/flex/secciones)
→ [Algoritmos (Flex)](/docs/desarrollo/flex/algoritmos)
# Compras y gastos (/docs/desarrollo/recursos/secciones-nucleo/compras-y-gastos)
Secciones de fábrica del núcleo de Dinaup en el dominio de **compras y gastos**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Catálogos de compra [#catálogos-de-compra]
Tarifa de compra pactada con un proveedor: lista de productos con precios, descuentos y condiciones de pedido (mínimos/máximos) que se aplica al comprar a esa entidad. Es el espejo de compras de los catálogos de venta; no confundir con el documento de compra (Compras / Gastos).
* ID de sección: `d64c88c8-080f-436e-a5e3-74cf009b10e6` · tiene **sección lista** (líneas del documento)
### Categorías de Compra [#categorías-de-compra]
Categoría con la que se clasifican las Compras/Gastos y que dirige su contabilización: subcuenta de gasto, subcuenta de devoluciones, si son servicios y si entra en la contabilidad automática. Homóloga de "Categorías de Ventas" pero para el lado de compras.
* ID de sección: `003d9171-a61c-4658-b4c9-4bf7b5c91f76`
### Compras / Gastos [#compras--gastos]
Factura recibida o gasto de la empresa: documento de compra con proveedor, líneas de productos/conceptos, impuestos, retención y totales calculados. Es el registro fiscal real (con nº de factura y NIF), no un presupuesto ni un pedido; genera pagos, entradas de inventario y asiento contable.
* ID de sección: `8fac2930-c1ea-48b5-ab89-50a0725e86e2` · tiene **sección lista** (líneas del documento)
### Entradas de Compra [#entradas-de-compra]
Recepción en almacén de mercancía de una compra a proveedor: producto, cantidad, almacén, hueco y lote, con estado Pendiente/Completada/Anulada que gobierna cómo impacta en el stock. Es el eslabón logístico de la compra — la factura vive en Compras/Gastos.
* ID de sección: `3b8b467f-2f7a-439d-8c4c-cdc732ad02fd`
### Libros registros de Compras / Gastos [#libros-registros-de-compras--gastos]
Maestro de libros registro para clasificar las compras y gastos (los "libros" fiscales/organizativos en los que se anotan las facturas recibidas): nombre, descripción, color y orden. Es catálogo de clasificación, no contiene las facturas.
* ID de sección: `ca3736db-f579-4c93-9265-9cb8fbd56560`
### Pagos de Compras [#pagos-de-compras]
Pago (o devolución) asociado a una compra/gasto: importe, método de pago, depósito monetario y estado de tramitación. Registra el flujo de dinero saliente; el documento de gasto en sí es Compras / Gastos y el cobro de ventas tiene su sección homóloga.
* ID de sección: `b97a298f-0c73-4206-8567-2d3c7e2d7263`
### Presupuestos de Compras y Gastos [#presupuestos-de-compras-y-gastos]
Presupuesto/cotización de una compra o gasto a un proveedor: documento previo, sin efecto contable ni de stock, con líneas de productos, importes, impuestos y descuentos. Usa esta sección para pedir precio u ofertas; la compra real va en Compras / Gastos.
* ID de sección: `e9fd98be-d22e-4bfd-84a3-ad22df3173e3` · tiene **sección lista** (líneas del documento)
### Salidas de Compras [#salidas-de-compras]
Salida de inventario ligada a una compra: devolución de mercancía a proveedor (típicamente por compra rectificativa). Descuenta stock del almacén vía movimiento interno; no es la salida de venta ni un movimiento interno genérico.
* ID de sección: `377ed111-4619-4c2e-b3ae-a959d6a71d89`
# Contabilidad y fiscal (/docs/desarrollo/recursos/secciones-nucleo/contabilidad-y-fiscal)
Secciones de fábrica del núcleo de Dinaup en el dominio de **contabilidad y fiscal**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Actividades de Empresas [#actividades-de-empresas]
Actividad económica declarada de la empresa (censo AEAT): epígrafe IAE, clave de actividad, régimen de IVA e IRPF y clave de operaciones predeterminada. Configuración fiscal de la propia empresa, no de sus clientes ni proveedores.
* ID de sección: `0c7c944f-f276-41f3-a2ca-90103a1b3b4c`
### Asientos contables [#asientos-contables]
Asiento de contabilidad de partida doble: cabecera con concepto, fecha y ejercicio, y líneas debe/haber contra subcuentas del Cuadro de cuentas. Se genera manualmente o automáticamente desde ventas, compras, cobros, pagos, nóminas, movimientos bancarios e inmovilizado. No usar para el documento comercial (factura); solo para su reflejo contable.
* ID de sección: `66424ed7-e5b3-4be1-a567-6ace93896a7d` · tiene **sección lista** (líneas del documento)
### Claves de operaciones [#claves-de-operaciones]
Catálogo maestro de claves fiscales de operación (códigos tipo AEAT/SII para clasificar operaciones): nombre, clave y observaciones. Los documentos fiscales referencian estas claves; aquí no hay lógica ni importes.
* ID de sección: `6b3081df-9592-467f-93f1-c4e29f0d68d8`
### Códigos CNAE [#códigos-cnae]
Catálogo de códigos CNAE (Clasificación Nacional de Actividades Económicas): código + descripción. Tabla de referencia para clasificar la actividad de empresas y entidades — no confundir con Epígrafes de actividades económicas (IAE) ni Códigos CPA.
* ID de sección: `f71bf53b-eb5d-4eae-9b60-80da126239a2`
### Códigos CPA [#códigos-cpa]
Catálogo de códigos CPA (Clasificación de Productos por Actividades): código + concepto. Dato maestro de clasificación estadística europea de productos/servicios, referenciado desde otras secciones; no confundir con CNAE (actividades) ni LER (residuos).
* ID de sección: `280cafd3-ea92-4129-8caf-832ccfb60c99`
### Cuadro de cuentas [#cuadro-de-cuentas]
Plan contable de la empresa: cada registro es una cuenta (grupo, subgrupo, cuenta o subcuenta) con código numérico único, jerarquía y flags fiscales. Las subcuentas son las únicas que admiten asientos. No confundir con Asientos contables (los apuntes) ni con Cuadros de cuentas oficiales (las plantillas PGC).
* ID de sección: `ba5315ec-72b7-4795-b612-9f1fdf299635`
### Cuadros de cuentas oficiales [#cuadros-de-cuentas-oficiales]
Plan contable oficial de referencia (p. ej. PGC español): el documento define el plan y sus líneas son los grupos/cuentas oficiales con su código numérico. Es la plantilla normativa; las subcuentas reales de la empresa viven en "Cuadro de cuentas".
* ID de sección: `a34c0a77-e9a7-4c73-a959-73cb48749fbf` · tiene **sección lista** (líneas del documento)
### Datos fiscales [#datos-fiscales]
Ficha fiscal de una entidad o ubicación: NIF, razón social o nombre/apellidos, y domicilio fiscal desglosado. Es la identidad tributaria usada en facturación/Verifactu; no confundir con la ficha general de la Entidad ni con direcciones de envío.
* ID de sección: `f3b161a4-dbe4-44ea-9259-b41dc8f88fc1`
### Documentos oficiales [#documentos-oficiales]
Registro de presentaciones fiscales/administrativas: un modelo o trámite oficial (tipo, ejercicio contable, periodo, fecha de presentación, estado y documento adjunto). Sirve para el seguimiento de trámites ante la administración; no es el archivo legal en sí (Archivo de documentos legales) ni un documento a digitalizar.
* ID de sección: `c14b249c-051f-4a86-9a08-9fc0c98d483f`
### Ejercicios contables [#ejercicios-contables]
Ejercicio fiscal de la empresa: año, fechas de inicio/fin, estado abierto/cerrado, tabla IRPF/Sociedades aplicable y serie de numeración de asientos. Marco temporal al que se anclan asientos y libros registro — no confundir con los cierres operativos de caja diarios.
* ID de sección: `e048cebc-3d71-4e70-b076-dcd39e146781`
### Epígrafe actividades económica [#epígrafe-actividades-económica]
Catálogo de epígrafes de actividades económicas (IAE): código único, descripción, categoría y parámetros de módulos (índice de cuota devengada, porcentaje de ingreso a cuenta). Referencia fiscal; no confundir con Códigos CNAE ni Actividades de Empresas.
* ID de sección: `b5b8a709-9ec4-4920-9cd7-2536e35b725b`
### Impuestos [#impuestos]
Tipo impositivo (IVA/recargo de equivalencia) aplicable en documentos de venta y compra: porcentaje, multiplicadores derivados, subcuentas contables y clasificación fiscal Verifactu. Es el catálogo maestro de impuestos, no un apunte fiscal.
* ID de sección: `ed839ee7-95d0-4b4c-bc41-6881c48fc6de`
### Inmovilizado [#inmovilizado]
Activo fijo contable de la empresa: bien adquirido que se amortiza (coste, valor residual, vida útil, cuentas contables). Enlaza la factura de compra de origen con los asientos de amortización; no es un gasto corriente (eso es Compras / Gastos) ni un vehículo/recurso operativo.
* ID de sección: `3bce6b71-a934-4cf9-be13-8d215ec8bb06`
### Retenciones [#retenciones]
Dato maestro de retención fiscal (IRPF y similares): porcentaje, tipo, subcuentas contables donde imputar y ámbito de aplicación (compras/ventas, tipos de venta, TPV). Es la definición reutilizable que se aplica en documentos; no confundir con "Tablas de IRPF/ Sociedades" (tramos progresivos).
* ID de sección: `a5e64894-a805-4ab2-b108-044ce68de6c1`
### Tablas de IRPF/ Sociedades [#tablas-de-irpf-sociedades]
Tabla de tramos impositivos de IRPF o Impuesto de Sociedades: la cabecera define tipo y estado; cada línea es un tramo (desde-hasta) con su porcentaje a aplicar. Es configuración fiscal por tramos, no la retención puntual de un documento (eso es "Retenciones").
* ID de sección: `8ca6776a-4455-4fba-9b96-173a97a38005` · tiene **sección lista** (líneas del documento)
# CRM y marketing (/docs/desarrollo/recursos/secciones-nucleo/crm-y-marketing)
Secciones de fábrica del núcleo de Dinaup en el dominio de **crm y marketing**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Anuncios / Publicidad [#anuncios--publicidad]
Concepto creativo de anuncio publicitario dentro del marketing: producto que promociona, avatar objetivo, punto de dolor, estrategia y objetivo de campaña, con estado de ciclo creativo (nace en "Ideación"). Las variantes concretas viven en Versiones de Anuncios; su uso real, en Campañas y Resultados de Campañas.
* ID de sección: `cd850f40-e02c-4c6f-90b1-9598770259c8`
### Asignaciones de Casos de éxito a Avatares de Clientes [#asignaciones-de-casos-de-éxito-a-avatares-de-clientes]
Tabla de unión N:M del CRM de marketing: vincula un Caso de éxito con un Avatar de Cliente (perfil de cliente ideal). Solo las dos referencias; sin atributos propios.
* ID de sección: `25c43353-59ce-4dcb-af16-fab374302872`
### Asignaciones de Entidades a Proyectos [#asignaciones-de-entidades-a-proyectos]
Vínculo N:M entidad-proyecto: asigna una entidad (persona/empresa) a un proyecto con un rol. El servidor deriva rol predeterminado, nombre, foto y la incorporación a Mattermost. Un registro = una participación en un proyecto.
* ID de sección: `67986864-1b07-47df-80c4-2d977f61a413`
### Asignaciones de Puntos de dolor de Clientes a Avatares de Clientes [#asignaciones-de-puntos-de-dolor-de-clientes-a-avatares-de-clientes]
Tabla de unión N:M del marketing: vincula un Punto de dolor de Clientes con un Avatar de Clientes (buyer persona). Solo dos referencias; para asociar dolores a avatares, no para definirlos.
* ID de sección: `7d96c5ae-ea9e-4e46-a51e-b7577db75709`
### Asignaciones de Testimonios de Clientes a Casos de éxito [#asignaciones-de-testimonios-de-clientes-a-casos-de-éxito]
Vínculo N:M entre un Testimonio de Cliente y un Caso de éxito: permite mostrar el mismo testimonio en varios casos y varios testimonios por caso. Tabla de asignación pura de marketing, sin lógica.
* ID de sección: `4f8bc1f7-870f-4f09-84aa-ebccd1af1bc6`
### Avatares de Clientes [#avatares-de-clientes]
Buyer persona de marketing: perfil arquetípico de cliente con nombre, descripción, foto, tipo y estado. Se enriquece asociándole casos de éxito y puntos de dolor mediante secciones de asignación; no es una entidad/cliente real (eso es Entidades).
* ID de sección: `2b24de5c-d6f3-4947-892f-1b8e6db2ee04`
### Campañas [#campañas]
Campaña de marketing: acción publicitaria con tipo, estrategia, anuncio, plataforma, presupuesto, fechas y estado. Agrupa Resultados de Campañas (que acumulan la inversión real); no es el anuncio en sí (Anuncios / Publicidad) ni la estrategia global (Estrategias de Marketing).
* ID de sección: `2c6e763a-f7eb-4099-b653-5c773410b94f`
### Casos de éxito [#casos-de-éxito]
Caso de éxito comercial: historia documentada de un cliente (referente) con resumen, tipo, estado y puntos clave como líneas. Material de marketing/ventas; no confundir con Testimonios de Clientes, que se asocian a los casos vía sección de asignaciones.
* ID de sección: `073caeae-7d24-448f-8b85-518db553b19c` · tiene **sección lista** (líneas del documento)
### Citas [#citas]
Cita agendada con un cliente (o contacto sin ficha): fecha de inicio/fin, tipo, estado, empleado responsable, lugar y notas de preparación/conclusión. Se evalúa en la agenda automáticamente. Distinta de "Eventos de Agendas" (evento genérico) y de "Eventos de CRM" (actividad comercial registrada a posteriori).
* ID de sección: `85871e82-8b4d-4f21-afa1-fdefc74fcf5e`
### Contenidos Redes Sociales [#contenidos-redes-sociales]
Pieza de contenido para redes sociales (post): texto, cuenta destino, tipo, estado editorial, fecha de publicación y URL del post publicado, enlazable a una estrategia de marketing y a un producto de marketing. No es la cuenta (Cuentas en Redes Sociales) ni un anuncio de pago (Anuncios / Publicidad).
* ID de sección: `a0289771-9905-4dff-b1b6-f09e34c8b6b8`
### Cuentas en Redes Sociales [#cuentas-en-redes-sociales]
Registro de una cuenta/perfil de la empresa en una red social: URL, red, dueño y responsable interno. Inventario de presencia social para el módulo de marketing — no publica ni conecta con la red, solo la cataloga.
* ID de sección: `1213ee06-95a9-4c61-aaa3-ec17cbf621b3`
### Entidades [#entidades]
Ficha maestra de personas y empresas con las que se relaciona el negocio: clientes, proveedores, bancos, contactos y usuarios web. Centraliza datos de contacto, fiscales, comerciales y de acceso. Es el "quién" al que apuntan ventas, compras, cobros, pagos y CRM.
* ID de sección: `eec5029a-440d-4505-8560-b88b3ff5917d`
### Estrategias de Marketing [#estrategias-de-marketing]
Plan de marketing de alto nivel: nombre, periodo (inicio/fin), objetivos y detalles en texto libre. Es el paraguas estratégico bajo el que cuelgan campañas concretas — no mide resultados ni contiene anuncios.
* ID de sección: `47bbf6d8-59bf-462f-ae29-79fbb3d9a300`
### Eventos de CRM [#eventos-de-crm]
Interacción comercial planificada dentro de una Oportunidad CRM: llamada, reunión o contacto con tipo, inicio, duración y estado. Siempre cuelga de una oportunidad; para actividad no comercial usar Tareas o Anotaciones internas.
* ID de sección: `fd0d1ce2-84a0-4686-8b7c-7f0664809145`
### Grupos de Entidades [#grupos-de-entidades]
Agrupación arbitraria de entidades (clientes, proveedores, contactos): un grupo con tipo, observaciones y sus miembros en lista. Para segmentar/clasificar entidades en colecciones; no confunde con departamentos ni con la ficha de la entidad.
* ID de sección: `2c0d89c4-7bbc-4f3b-bd2b-423ba80f6959` · tiene **sección lista** (líneas del documento)
### Historial de cambio de estado de Oportunidades CRM [#historial-de-cambio-de-estado-de-oportunidades-crm]
Registro de auditoría: una entrada por cada cambio de estado de una oportunidad CRM (oportunidad + nuevo estado + fecha y autor). Solo lectura en la práctica — lo alimenta el sistema; no es el estado actual de la oportunidad, es su traza histórica.
* ID de sección: `ced35b76-ad81-4cbf-a513-52e062cebd0d`
### Historial de cambio de Fases de Oportunidades CRM [#historial-de-cambio-de-fases-de-oportunidades-crm]
Historial de transiciones de fase de una oportunidad CRM: qué oportunidad pasó a qué fase del proceso de venta, quién y cuándo. Registro append-only de trazabilidad del pipeline; la fase vigente vive en la propia Oportunidad CRM.
* ID de sección: `fcd11d19-0710-43e0-b316-476a3119c729`
### Llamadas [#llamadas]
Registro CRM de una llamada telefónica: con quién se habló, dirección (entrante/saliente), motivo, notas, transcripción, resumen y conclusiones. Es el histórico de la conversación; las tareas o eventos que deriven de ella van en sus propias secciones.
* ID de sección: `84a51b78-7f95-41be-a4de-4f656571b23f`
### Métodos de captación de clientes [#métodos-de-captación-de-clientes]
Catálogo de canales por los que llegan clientes nuevos (recomendación, web, publicidad...): nombre, descripción e icono. Etiqueta CRM para atribuir el origen de cada cliente; no confundir con Canales de Venta ni Campañas.
* ID de sección: `34ce97cd-9632-4fdf-bf42-52adc168a25c`
### Métodos de contacto [#métodos-de-contacto]
Catálogo de vías de contacto con clientes (teléfono, email, WhatsApp, visita...): nombre, descripción e icono. Maestro simple que otras secciones (CRM, entidades) referencian para clasificar cómo se contactó; no guarda contactos concretos.
* ID de sección: `2ebb4ef9-d9dd-4624-aab0-a129c7a2c13d`
### Motivos de pérdidas de oportunidades [#motivos-de-pérdidas-de-oportunidades]
Catálogo CRM de razones por las que se pierde una oportunidad de venta (precio, competencia...), con tipo, color, si es recuperable y días para reintentar. Se usa al cerrar Oportunidades CRM como perdidas; no registra la pérdida en sí.
* ID de sección: `bdddb78b-2fb1-45d5-90ba-aa525a629680`
### Objeciones [#objeciones]
Catálogo comercial de objeciones de clientes ("es caro", "ya tengo proveedor") con sus respuestas preparadas como líneas. Es material de argumentario CRM reutilizable, no el registro de una objeción concreta en una venta — para vincularla a un proceso existe Asignaciones de Objeciones a Procesos.
* ID de sección: `3e2c20ef-6e49-4a1b-9038-1384a4c55c9b` · tiene **sección lista** (líneas del documento)
### Objetivos de campañas de Marketing [#objetivos-de-campañas-de-marketing]
Catálogo de objetivos de marketing (notoriedad, captación, conversión...): nombre, descripción e icono. Es una tabla de clasificación que referencian Anuncios/Publicidad y Campañas; no fija metas numéricas ni periodos (eso sería Objetivos de Venta para comerciales).
* ID de sección: `c7a3b071-f03f-4bcd-ae2b-43aa053d6d9a`
### Oportunidades CRM [#oportunidades-crm]
Oportunidad de venta del CRM: un cliente potencial interesado en algo, con valor estimado, prioridad, proceso/fase comercial y estado (abierta/ganada/perdida). No es la venta ni el presupuesto — es el seguimiento comercial previo; su actividad se registra en Eventos de CRM.
* ID de sección: `a013f0e4-bd0d-4bef-8f7d-83ba35cb9e21`
### Puntos de dolor de Clientes [#puntos-de-dolor-de-clientes]
Catálogo de marketing/ventas: cada registro es un problema o frustración típica de los clientes, con tipo, estado y una lista de soluciones que la empresa ofrece (vinculables a un Producto de Marketing). No es una incidencia de un cliente concreto: es material argumental comercial.
* ID de sección: `276b0425-1c1f-4ac6-93b9-9691a6ed1830` · tiene **sección lista** (líneas del documento)
### Resultados de Campañas [#resultados-de-campañas]
Medición periódica del rendimiento de una campaña de marketing: un registro por periodo (Desde/Hasta) con la inversión realizada, conclusiones y una lista de KPIs a rellenar. No es la campaña ni el anuncio — es el informe de resultados de un intervalo concreto.
* ID de sección: `667dea58-d1b9-42aa-a0dc-9cc340f93f66` · tiene **sección lista** (líneas del documento)
### Testimonios de Clientes [#testimonios-de-clientes]
Testimonio o reseña de un cliente para marketing: texto, firma, foto, autor (entidad) y su empresa, con tipo y estado de catálogo. Material comercial reutilizable; los casos de éxito completos van en su propia sección.
* ID de sección: `5d46a56c-63f9-431b-9c75-f9c7d19e762f`
### Versiones de Anuncios [#versiones-de-anuncios]
Variante concreta (versión) de un anuncio publicitario: número de versión, título, creatividad (imagen) y estado, con contador de resultados de campaña. Sirve para test A/B y evolución de creatividades — el anuncio contenedor vive en Anuncios/Publicidad.
* ID de sección: `20b3cfe1-c9b8-4e9b-aeaa-d9030bf33997`
# Desguaces y vehículos (/docs/desarrollo/recursos/secciones-nucleo/desguaces-y-vehiculos)
Secciones de fábrica del núcleo de Dinaup en el dominio de **desguaces y vehículos**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Cambios de estados de Recambios [#cambios-de-estados-de-recambios]
Historial de transiciones de estado de un recambio de vehículo: qué recambio, a qué estado pasó, quién y cuándo. Registro append-only de trazabilidad; el estado vigente vive en el propio Recambio.
* ID de sección: `678210b7-13a2-4a0f-bc76-02f6a3ad00ab`
### Cambios de estados de Vehículos para Desguace [#cambios-de-estados-de-vehículos-para-desguace]
Log histórico de cada cambio de estado de un Vehículo para desguace: vehículo, estado nuevo, quién y cuándo. Traza de auditoría append-only; el estado vigente vive en el propio vehículo, no aquí.
* ID de sección: `795be9f5-75cf-4226-923d-6b4c372c3fb6`
### Clasificación de demandas de productos [#clasificación-de-demandas-de-productos]
Catálogo maestro de categorías para clasificar demandas de productos (las de "Demandas Sin Registro" y "Demandas Sin Stock"): nombre + descripción. Solo etiqueta de agrupación para análisis; no registra la demanda en sí.
* ID de sección: `cd4b944c-3e3f-4baf-b3bb-56fc77f3b867`
### Códigos de Tratamiento [#códigos-de-tratamiento]
Catálogo de códigos de tratamiento de residuos (normativa medioambiental): código + concepto, con nombre compuesto automáticamente. Tabla maestra de referencia para el módulo de residuos/desguace; no registra operaciones.
* ID de sección: `86ce0d68-d0cb-4e90-8608-316390393885`
### Códigos LER [#códigos-ler]
Catálogo de códigos LER (Lista Europea de Residuos): código oficial, concepto y unidad de medida con la que se cuantifica el residuo. Tabla maestra de clasificación para el módulo de residuos, no un registro de residuo concreto.
* ID de sección: `6e7a7130-b1e3-417b-8f2d-f2a81674cabb`
### Combustibles [#combustibles]
Catálogo de tipos de combustible (gasolina, diésel, eléctrico...) con icono y color, para clasificar vehículos. Lista de valores pura: sin cantidades, precios ni lógica.
* ID de sección: `3cd40e9c-c099-4afe-9c76-6dbfa7ca6d25`
### Demandas Sin Registro [#demandas-sin-registro]
Anotación de demanda de un producto que NO existe en el catálogo: el cliente pidió algo, no lo teníamos registrado y se apunta como texto libre para detectar oportunidades. Si el producto sí existe pero no hay stock, la sección correcta es "Demandas Sin Stock".
* ID de sección: `b2f282cd-c072-4a42-a417-ea45e4996cb5`
### Demandas Sin Stock [#demandas-sin-stock]
Registro de demanda no atendida por falta de stock: qué pidió un cliente y no había (producto, concepto libre o detalle de recurso), con señales de venta perdida. Para detectar qué reponer; no confunde con "Demandas Sin Registro" (producto no catalogado).
* ID de sección: `c96ce0e1-7b26-4d82-aca0-42b7aafe831b`
### Detalles de Recambios [#detalles-de-recambios]
Ficha maestra/plantilla de un tipo de recambio para una versión de vehículo concreta: tipo de pieza, referencias (OEM, EAN, visual), precios y costes de referencia. Los Recambios físicos en stock apuntan a esta ficha; aquí no hay unidades, solo la definición y sus precios orientativos.
* ID de sección: `54372e44-7399-4c8f-a911-081fed6fee26`
### Detalles de Vehículos para desguace [#detalles-de-vehículos-para-desguace]
Ficha técnica maestra de una versión de vehículo (marca + modelo + acabado + años + motor) usada en desguaces: precios de referencia de compra/venta, peso e info técnica. Es el catálogo del que cuelgan los Vehículos para desguace y los Detalles de Recambios; NO es un vehículo físico concreto.
* ID de sección: `2a361175-27c8-43be-943b-f9c7f171a18d`
### Detalles vehículos de empresa [#detalles-vehículos-de-empresa]
Ficha maestra técnico-comercial de un modelo de vehículo: marca, modelo, años, versión/acabado, precios y costes de referencia con margen calculado. Es la plantilla de la que las unidades físicas (Vehículos de la empresa) copian marca y modelo; no representa un vehículo concreto con matrícula.
* ID de sección: `86041dd2-961d-4fb4-9014-645ee713593a`
### Familias de recambios [#familias-de-recambios]
Catálogo plano de familias para clasificar recambios de desguace (motor, carrocería, electrónica...): nombre, descripción e icono. Tabla maestra de agrupación; el recambio apunta a su familia, aquí no hay jerarquía ni atributos técnicos.
* ID de sección: `1b1d6afd-facc-430f-bd46-5e1ffc3493aa`
### Historial de Asignación de Precios a Recambios [#historial-de-asignación-de-precios-a-recambios]
Registro de auditoría de cada cambio de precio de venta de un recambio: qué pieza, qué precio nuevo, quién y cuándo. Solo traza — el precio vigente vive en el propio Recambio.
* ID de sección: `4b24d789-2d27-4b50-acf8-e933451a8f76`
### Historial de Control de Calidad de Recambios [#historial-de-control-de-calidad-de-recambios]
Anotación de auditoría: registra que un recambio pasó un control de calidad, quién lo hizo y cuándo. Solo traza (recambio + empleado + fecha + texto); no guarda resultado estructurado ni estados — para incidencias está Incidencias con Recambios.
* ID de sección: `4fa5d0b6-f890-4a0e-8c99-5918a7a19ebf`
### Historial de Limpieza de Recambios [#historial-de-limpieza-de-recambios]
Log de limpiezas de recambios: cada registro deja constancia de que un recambio fue limpiado, con fecha y empleado de la sesión. Solo trazabilidad; el estado del recambio vive en Recambios y otros historiales (picking, revisado) cubren el resto de hitos.
* ID de sección: `3b7e82a9-cca4-49a6-a2d1-70216d410018`
### Historial de Recambios Picking [#historial-de-recambios-picking]
Registro histórico de un evento de picking sobre un Recambio: qué pieza se recogió, de qué hueco y almacén, quién y cuándo. Es un log de trazabilidad append-only, no un documento operativo; el movimiento de stock lo llevan otras secciones.
* ID de sección: `39382599-e1ab-4ca3-a457-ff8dd175314c`
### Historial de Recambios Revisados [#historial-de-recambios-revisados]
Evento de revisión de un recambio (desguace): quién lo revisó, cuándo y dónde estaba (almacén y hueco). Log inmutable de trazabilidad; el estado actual del recambio vive en la ficha de Recambios.
* ID de sección: `b6b33fdc-34e3-4d42-9e37-71c075016535`
### Incidencias con Recambios [#incidencias-con-recambios]
Incidencia (garantía, defecto, reclamación) sobre un Recambio ya vendido o servido en un desguace: tipo, estado, recambio afectado, pedido/venta/cliente relacionados y su resolución con fecha y días transcurridos. Distinta de "Incidencias" generales y de "Incidencias con Vehículos para desguace".
* ID de sección: `a6a0af8d-e5cb-42e1-9853-ceeaaa0c8a18`
### Incidencias con Vehículos para Desguace [#incidencias-con-vehículos-para-desguace]
Parte de incidencia sobre un vehículo para desguace: descripción, tipo, estado, entidad implicada y resolución con fecha y días transcurridos. Específica del vertical de desguaces; para incidencias generales usar Incidencias, y para incidencias con piezas, Incidencias con Recambios.
* ID de sección: `fd36ffe0-26aa-4152-a1dc-db532724c8ac`
### Modelos de vehículos [#modelos-de-vehículos]
Catálogo maestro de modelos de vehículo (marca + modelo + años de fabricación + foto). Referencia estática que consumen Vehículos de la empresa y Vehículos para desguace; no representa ningún vehículo físico concreto.
* ID de sección: `ff65b90b-8d89-4c82-8064-3aada2a3913c`
### Recambios [#recambios]
Pieza de recambio individual extraída (o dada de alta manualmente) para su venta, típicamente procedente de un vehículo para desguace. Cada registro es UNA pieza física con estado, ubicación, precios de venta/compra y reserva. No confundir con "Detalles de Recambios" (catálogo de definiciones) ni "Tipos de recambios" (clasificación).
* ID de sección: `f120b0e9-e2b7-4069-9d2b-d25e78f69c27`
### Residuos [#residuos]
Registro individual de un residuo generado: qué es (tipo, código LER), cuánto (cantidad y peso) y su estado de tratamiento. Para trazabilidad medioambiental; no confundir con Códigos LER (catálogo) ni con inventario de productos.
* ID de sección: `a691a568-8ac4-4bbe-a08a-1359ee01fe3b`
### Vehículos de la empresa [#vehículos-de-la-empresa]
Ficha comercial de un vehículo propiedad de la empresa: matrícula, tipo, estado, precios de compra y venta con margen calculado. Es el vehículo como activo/mercancía vendible; sus datos técnicos viven en Detalles vehículos de empresa y los vehículos a despiezar en Vehículos para desguace.
* ID de sección: `ce73e331-3d68-4926-b20f-91355e9009a1`
### Vehículos para desguace [#vehículos-para-desguace]
Vehículo físico que entra en un centro de desguace para ser despiezado: matrícula, bastidor, titulares, estado, ubicación en almacén y precios de compra/venta. Distinto de "Detalles de Vehículos para desguace" (la versión/ficha técnica del modelo) y de "Recambios" (las piezas extraídas de él).
* ID de sección: `80145d3a-9d1b-430a-b900-212345985efe`
# Catálogo de secciones del núcleo (/docs/desarrollo/recursos/secciones-nucleo)
Toda instancia de Dinaup trae de fábrica un núcleo de secciones: los "planos" sobre los que trabajan los módulos Ready to Go, la API y el SDK. Este catálogo las lista todas con una descripción que responde la pregunta clave al integrar: **¿qué sección uso para esto?**
Los **IDs de sección son idénticos en todas las instancias** — puedes usarlos tal cual en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o con el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente) sin descubrirlos primero. Las secciones de Estados y Tipos (auxiliares de cada sección principal) no se listan: se descubren desde su sección madre.
## Antes de escribir en una sección [#antes-de-escribir-en-una-sección]
Cuatro comportamientos de la plataforma que afectan a cualquier escritura (el detalle, con ejemplos, en [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts)):
1. **El orden de los campos importa**: escribir un campo dispara los autorrellenados que dependen de él.
2. **Autorrellenado «Siempre» copia incondicionalmente**: también vacío, y al deseleccionar el origen se vacía el destino.
3. **Con scripts activados, la lógica interna se ejecuta también por API**: totales, validaciones y filtros — como en la interfaz.
4. **Los campos auto-gestionados no se envían**: fechas, autor, calculados... los pone el servidor.
## Los dominios [#los-dominios]
Ventas, presupuestos, pedidos, cobros, cajas, TPV, Verifactu y envíos.
Compras, presupuestos de compra, pagos y sus libros registro.
Asientos, cuadros de cuentas, ejercicios, impuestos, retenciones e inmovilizado.
Cuentas y movimientos bancarios, reglas de clasificación, métodos de pago y monedas.
Productos, almacenes, stock, lotes, movimientos y catálogos.
Entidades, oportunidades, eventos, campañas, anuncios y testimonios.
Empleados, contratos, nóminas, fichajes, turnos, horarios y ausencias.
Proyectos, tareas, tickets de soporte, bonos de horas e incidencias.
Vehículos, recambios, residuos y los códigos del vertical de desguace.
Países, provincias, municipios, códigos postales y zonas horarias.
Webhooks, CRON, logs de API, archivos, anotaciones, agendas y flujos.
# Inventario y productos (/docs/desarrollo/recursos/secciones-nucleo/inventario-y-productos)
Secciones de fábrica del núcleo de Dinaup en el dominio de **inventario y productos**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Almacenes [#almacenes]
Maestro de almacenes físicos de la empresa: tipo, estado, responsable, localización en mapa, huecos por defecto para entradas (generales, de compras y devoluciones de venta) y disponibilidad en TPV y como origen de envíos. Es configuración de inventario, no un movimiento de stock.
* ID de sección: `7eec3e34-fbbd-4f1e-a77b-d4a6145686a3`
### Asignaciones de Objeciones a Productos de Marketing [#asignaciones-de-objeciones-a-productos-de-marketing]
Vínculo N:M entre una objeción del argumentario y un producto de marketing: qué objeciones suelen surgir al vender ese producto. Puro enlace CRM — la objeción y sus respuestas viven en Objeciones; el producto, en Productos (Marketing).
* ID de sección: `e02413e2-7178-4605-9ddc-4706d1734c00`
### Asignaciones de Testimonios de Clientes a Productos de Marketing [#asignaciones-de-testimonios-de-clientes-a-productos-de-marketing]
Tabla puente N:M que vincula un Testimonio de Cliente con un Producto (Marketing): un registro = "este testimonio avala este producto". Solo el enlace, sin atributos propios. No confundir con la asignación de testimonios a otras entidades de marketing (secciones hermanas de asignación).
* ID de sección: `7582818a-2595-497f-8323-64c42df543f0`
### Categorías de productos [#categorías-de-productos]
Catálogo de categorías para agrupar Productos (el artículo del inventario). No confundir con Categorías de Ventas/Compra, que clasifican los importes de documentos, ni con familias de recambios: esta agrupa el maestro de productos.
* ID de sección: `bfa561c0-76b9-4c0d-ac16-b951dd193aec`
### Condiciones de Objetos [#condiciones-de-objetos]
Catálogo de estados de conservación de objetos físicos (nuevo, usado, dañado...): nombre, descripción, valor para integraciones (`ValorAPI`), icono y color. Maestro de clasificación que otras secciones (recambios, recursos) referencian; no registra objetos concretos.
* ID de sección: `2ec65e3c-13d7-46da-9db7-79e03b32dbb8`
### Grupos de Almacenes [#grupos-de-almacenes]
Agrupación lógica de almacenes: un grupo con nombre, tipo y estado cuyas líneas son los almacenes miembros. Sirve para operar o filtrar sobre conjuntos de almacenes; no gestiona stock ni ubicaciones — eso lo hacen Almacenes, Zonas y Huecos.
* ID de sección: `777a913e-b9d3-4d42-b0c1-6d3dab7d280f` · tiene **sección lista** (líneas del documento)
### Historial de cambios de hueco del recurso [#historial-de-cambios-de-hueco-del-recurso]
Log de reubicaciones de un recurso de la empresa: registra a qué hueco de almacén se movió, quién y cuándo. Trazabilidad de recursos (no de recambios ni productos, que tienen sus propios historiales).
* ID de sección: `93408eae-ffe5-419d-970f-4bd3413d4a8f`
### Huecos en almacenes [#huecos-en-almacenes]
Ubicación física concreta dentro de un almacén (estantería/hueco) donde se deposita mercancía: identificador único, zona, tipo, estado y coordenadas en el plano del almacén. Es infraestructura de almacén, no stock — el stock referencia al hueco desde recambios, salidas, etc.
* ID de sección: `f57df204-fb71-4f02-8a04-708d632d9c9e`
### Lotes de productos [#lotes-de-productos]
Lote/partida de un producto gestionado por lotes: identificación (serie, ID interna), fechas de disponibilidad y devolución a proveedor, coste unitario y estado que decide si se puede vender. El stock del lote lo calcula el servidor desde los movimientos internos; no confundir con Stock por Almacén.
* ID de sección: `b0f097d1-6733-4d57-82bb-7c3467764666`
### Marcas comerciales [#marcas-comerciales]
Maestro de marcas (fabricante/marca comercial) con nombre, logo e ID externa. Catálogo simple que otras secciones (productos, recambios, vehículos) referencian para clasificar por marca — no confundir con Modelos de vehículos ni con Actividades de Empresas.
* ID de sección: `81cfe5e7-053b-4572-8204-f1bec2d20e38`
### Productos [#productos]
Ficha maestra de un artículo o servicio que la empresa compra y/o vende: identidad (nombre, código de barras, marca, fabricante), unidades de medida, peso, políticas de stock y lotes, precios medios y alertas. Es el catálogo maestro; los precios pactados viven en Catálogos de compra/venta y el stock en inventario.
* ID de sección: `ddf538c2-6a4e-44f3-abde-d2283ffb9392`
### Productos ( Marketing ) [#productos--marketing-]
Ficha comercial de un producto o servicio para el discurso de marketing/ventas: descripción, imagen, FAQs, tipo y estado, y enlaces a testimonios y objeciones. NO es el producto vendible del catálogo (eso es Productos): es el argumentario.
* ID de sección: `95e028dc-613c-4fd5-9915-64ada3ea18a0`
### Stock por Almacén [#stock-por-almacén]
Proyección del stock de un producto en un almacén concreto: stock físico, disponible y umbrales mínimo/máximo. Un registro único por pareja producto-almacén (Hash). Es tabla de consulta derivada de entradas/salidas — no el sitio donde mover stock.
* ID de sección: `8b34df8a-1ff1-478e-98cc-918b2e2d0173`
### Zonas de Almacén [#zonas-de-almacén]
Zona física dentro de un Almacén (área de picking, recepción, etc.) con tipo, estado y coordenadas en el plano del almacén. Nivel intermedio de organización: el detalle fino de ubicación son los "Huecos en almacenes"; esto delimita áreas.
* ID de sección: `33f0e0f2-a26e-43e7-9dc6-8dce4b80bdc7`
# Maestros y geografía (/docs/desarrollo/recursos/secciones-nucleo/maestros-y-geografia)
Secciones de fábrica del núcleo de Dinaup en el dominio de **maestros y geografía**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Códigos postales [#códigos-postales]
Maestro geográfico de códigos postales: código, nombre de la zona y comunidad autónoma a la que pertenece, con flag Archivado. Se usa como referencia en direcciones y segmentación territorial; no confundir con Provincias, Municipios o Comunidades autónomas (otros niveles del maestro geográfico).
* ID de sección: `12fe99c8-0250-4aae-ab85-21acc131851a`
### Colores [#colores]
Catálogo de colores reutilizable: nombre, código hexadecimal e icono. Tabla maestra para clasificar visualmente registros de otras secciones (vehículos, recambios, productos...), sin lógica propia.
* ID de sección: `4c87305f-053f-47a9-accb-ec8ad8444e71`
### Comunidades autónomas [#comunidades-autónomas]
Maestro geográfico de comunidades autónomas: nombre, código y flag Archivada. Nivel regional del árbol geográfico de Dinaup, referenciado por Códigos postales y Provincias; no confundir con esos otros niveles.
* ID de sección: `1ee1695c-3617-4978-8aff-c236cd829c21`
### Grupos de provincias [#grupos-de-provincias]
Agrupación con nombre de provincias (p. ej. zonas comerciales o de tarifas de envío): el registro es el grupo y sus líneas son las provincias incluidas. Usar cuando algo se aplica por conjunto de provincias, no para dar de alta provincias individuales (eso es Base - Provincias).
* ID de sección: `049c17bd-69ea-4c69-a593-5eb0a8628e3d` · tiene **sección lista** (líneas del documento)
### Municipios [#municipios]
Maestro geográfico de municipios: nombre, provincia (que arrastra el país), comunidad autónoma y códigos oficiales INE y AEAT. Tabla de referencia para direcciones y datos fiscales — no confundir con Códigos postales ni Provincias, que son maestros aparte.
* ID de sección: `9c09b492-e2ab-49bf-b294-cdf8115c7f2f`
### Países [#países]
Catálogo maestro de países: nombre, códigos ISO (alfa-2, alfa-3, numérico de 3 dígitos), prefijo telefónico, bandera y configuración de métodos de envío (Sendcloud). Referencia geográfica base; no confundir con Provincias ni Comunidades autónomas.
* ID de sección: `79018517-bc68-453a-a5e2-eb9dddcf0e28`
### Provincias [#provincias]
Catálogo maestro de provincias: nombre, código de provincia, país y comunidad autónoma. Nivel intermedio de la jerarquía geográfica (País → Comunidad → Provincia → Municipio); no confundir con Municipios ni Grupos de provincias.
* ID de sección: `16b96ccb-26ea-4c46-8a7c-805bf5c864d7`
### Ubicaciones en mapa [#ubicaciones-en-mapa]
Punto geográfico con nombre para pintar en mapas: dirección postal completa, teléfono y coordenadas en texto libre. Es un marcador reutilizable (tiendas, puntos de recogida...), no la dirección fiscal de una entidad ni una dirección de envío.
* ID de sección: `4f4d602c-59ac-4b75-bbb9-1c95f5ad0d35`
### Zonas horarias [#zonas-horarias]
Maestro de zonas horarias: nombre y su WindowsID (identificador de time zone de Windows). Tabla de referencia del sistema para localizar horas; los registros marcados como de sistema quedan bloqueados contra edición.
* ID de sección: `7d2bb3c2-b9b7-4c09-994c-447a8635412b`
# Plataforma y sistema (/docs/desarrollo/recursos/secciones-nucleo/plataforma-y-sistema)
Secciones de fábrica del núcleo de Dinaup en el dominio de **plataforma y sistema**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Administración de Archivos [#administración-de-archivos]
Registro documental de un archivo subido al sistema: fichero binario más metadatos (nombre, extensión, MIME, tamaño, carpeta/categoría, scope). Es el gestor documental genérico de la empresa, no los adjuntos específicos de otras secciones ni los documentos legales.
* ID de sección: `9994737b-9e67-4c8f-9620-f4061717e114`
### Agendas [#agendas]
Calendario con nombre que agrupa eventos: cada agenda es un contenedor (nombre + descripción) al que se asocian Eventos de Agendas y empleados asignados. No contiene los eventos — solo los organiza.
* ID de sección: `2714bac6-a36c-4050-940c-4b4cc3bcdd75`
### Anotaciones internas [#anotaciones-internas]
Notas internas de empleados sobre cualquier registro del sistema: comentario de texto, con flags para mostrarse como comentario público, en documentación o como galería de fotos. Su lista lleva los adjuntos y menciones. Para comunicación interna anclada a un dato, no para eventos CRM ni tickets.
* ID de sección: `bc58c60f-7fe4-4c91-9f54-ed25d19c74e0` · tiene **sección lista** (líneas del documento)
### Archivo de documentos legales [#archivo-de-documentos-legales]
Archivador de documentos legales de la empresa (contratos, escrituras, certificados...): título, tipo, estado, entidad relacionada y notas. Es el índice del documento archivado; no es el log de eventos legales (Logs de Eventos Legales) ni la cola de digitalización (Documentos pendientes de digitalizar).
* ID de sección: `e69873c3-bab1-40af-b992-782a7e617e28`
### Áreas de acceso web [#áreas-de-acceso-web]
Credencial/canal de acceso externo a Dinaup: cada registro define un área con API Key, clave secreta, lista blanca de IPs/objetos y valores por defecto (empresa, ubicación, empleado). Es configuración de integración, no datos de negocio.
* ID de sección: `d62290ec-652d-4afd-933e-695235972ff1`
### Cambios de estados de Recursos de la Empresa [#cambios-de-estados-de-recursos-de-la-empresa]
Historial de cambios de estado de un recurso de la empresa: qué recurso pasó a qué estado, cuándo y por qué empleado. Registro de auditoría append-only — el estado vigente vive en el propio Recurso; aquí queda la traza de cada transición.
* ID de sección: `94f82d39-ce6e-4472-8c37-a44d8fdefb89`
### Categorías de Archivos [#categorías-de-archivos]
Carpeta del gestor documental de Dinaup: nombre en formato ruta ("Archivos/..." o "Sistema/..."), carpeta padre, color e icono, con contadores de archivos y tamaño. Organiza los registros de Administración de Archivos; no guarda ficheros, solo la jerarquía.
* ID de sección: `8f18d18a-c4be-4542-86e4-ead2fc3ff435`
### Correspondencias internas [#correspondencias-internas]
Mensaje interno entre usuarios de la empresa (tipo nota/comunicado con hasta 5 adjuntos), con estado de envío y logs legales de autoría, apertura y lectura del destinatario. Es mensajería interna trazable, no email a clientes ni anotación libre sobre un registro.
* ID de sección: `88ca852c-a4f9-4abe-b6a1-38bb41be2023`
### Dinaup Registros de Componentes [#dinaup-registros-de-componentes]
Log técnico interno de Dinaup: cada registro es una ejecución de un componente/servicio en background (enum) con su duración en segundos e información adicional. Telemetría de plataforma, no datos de negocio; solo lectura para diagnóstico.
* ID de sección: `677500eb-4c50-40d3-abb7-0f8dba9e965a`
### Documentos pendientes de digitalizar [#documentos-pendientes-de-digitalizar]
Bandeja de entrada documental: un archivo (ticket, factura, nómina...) subido a la espera de convertirse en su registro definitivo (Compra/Gasto, Venta/Ingreso o Nómina), con tipo, estado, encargado y JSON de análisis por IA. No es el documento contable final — es su paso previo.
* ID de sección: `c850fb66-2985-4cf3-b845-2be49b3c6d36`
### Empresas administradas [#empresas-administradas]
Ficha de configuración global de cada empresa gestionada en Dinaup: identidad corporativa, datos registrales, y todos los valores por defecto (numeraciones, estados iniciales, métodos de pago, impresiones, políticas de fichaje e inventario) que el resto de secciones consumen al crear registros.
* ID de sección: `8bcba7c2-11b2-4f81-a7a7-35f65de8aa51`
### Eventos de Agendas [#eventos-de-agendas]
Evento de calendario dentro de una agenda: título, inicio y fin en UTC y detalles. Es el bloque genérico de agenda (Base - Agendas); no confundir con Citas (con cliente) ni con Eventos de CRM (actividad comercial).
* ID de sección: `56faa05a-531d-461f-a6f8-0efef0faf9de`
### Flujos de Estado [#flujos-de-estado]
Definición de las transiciones de estado permitidas para una sección concreta: qué estados pueden pasar a qué otros. El documento fija la sección (tipo de estados) y sus líneas son las transiciones origen→destino. Es configuración de flujo, no un registro de cambios de estado (eso son los "Historial de cambios de estado").
* ID de sección: `2faebf06-802e-412c-999c-6d387834be04` · tiene **sección lista** (líneas del documento)
### Flujos de Procesos [#flujos-de-procesos]
Definición de un flujo de estados para registros de un tipo dado: la cabecera identifica el flujo (nombre, tipo de registro, icono) y cada línea es un paso/estado permitido del flujo. Configuración maestra, no un registro operativo.
* ID de sección: `99a9772e-5d98-4461-b602-e0e18f192a8b` · tiene **sección lista** (líneas del documento)
### Historial de Cambios de Estados de Registros [#historial-de-cambios-de-estados-de-registros]
Traza de auditoría genérica: cada registro anota que un registro de otra sección cambió a un Estado de Registros, con fecha, empleado y autor. El registro auditado se vincula por el destinador (solo en alta). No confundir con los historiales específicos (pedidos, recambios, vehículos...).
* ID de sección: `29f928a5-5b25-4344-b401-6cbd553ab55c`
### Historial de ejecucción de Ritmos operativos [#historial-de-ejecucción-de-ritmos-operativos]
Registro de cada ejecución de un Ritmo Operativo: qué ritmo corrió, cuándo, cuánto duró y hasta tres valores numéricos de resultado más observaciones. Es un log append-only para trazar y medir los ritmos; el ritmo en sí (definición y programación) vive en Ritmos Operativos.
* ID de sección: `6b27a8be-7ea0-43f4-88a1-e79a9be9a706`
### HTTP CRON [#http-cron]
Tarea programada que llama periódicamente a una URL externa (HTTP polling): método, bearer opcional, intervalo en segundos y ventana horaria/días de ejecución. Para lanzar peticiones salientes recurrentes; lo inverso (recibir avisos de Dinaup) es Webhook Salientes.
* ID de sección: `2ccf4f1a-ce66-43bd-a49d-b5353343ec13`
### Logs de Eventos Legales [#logs-de-eventos-legales]
Registro inmutable de un evento con relevancia legal (consentimientos, notificaciones, procesos con trazabilidad): quién, cuándo, qué datos y sobre qué entidad. Los campos clave son de solo alta — se escribe una vez y no se retoca. No es log técnico (eso es Registro de Errores API / Actividad API).
* ID de sección: `a6f1de41-d7a4-441d-8857-7ac913db45ee`
### Notificaciones [#notificaciones]
Notificación interna dirigida a un empleado: cuerpo, metadatos y control de lectura (leída sí/no y cuándo). Es la bandeja in-app de avisos del sistema — no es email ni webhook saliente; para integraciones externas existe Webhook Salientes.
* ID de sección: `2a9c17c7-eeea-4113-bb18-a1a2bf85ef96`
### Ordenes de Transportes de recursos [#ordenes-de-transportes-de-recursos]
Orden de mover recursos de la empresa entre dos ubicaciones en mapa, con chofer, vehículo, fechas planificadas/confirmadas y estado calculado (Planificando/Programado/Transportando/Transportado/Cancelado). Admite órdenes "simbólicas" (sin logística real). No confundir con Envíos de paquetería: aquí se transportan recursos internos, no bultos a clientes.
* ID de sección: `49ab5f2d-cdd7-4802-973b-9d2a824b6a9c` · tiene **sección lista** (líneas del documento)
### Recursos de la empresa [#recursos-de-la-empresa]
Activo físico individual identificable (vehículo, maquinaria, objeto único) con ficha de compra/venta, titularidad, estado, localización y almacenaje. Úsala para unidades únicas con matrícula/bastidor y trazabilidad propia; el stock a granel va por Productos e inventario.
* ID de sección: `e01155e9-ddc2-45e3-9093-b86d44a93267`
### Registro de Errores API [#registro-de-errores-api]
Log de errores de la API de Dinaup: qué acceso API falló, desde qué IP y aplicación, en qué función (enum) y con qué detalle de error. Sección de auditoría técnica de solo consulta habitual, no de negocio.
* ID de sección: `d8a97473-ea12-4d17-b88e-b8716b847f00`
### Registros de Actividad API [#registros-de-actividad-api]
Log agregado del uso de la API: por acceso, función, aplicación e IP registra número de peticiones, errores y duraciones total/promedio. Telemetría de consumo, no de fallos individuales (eso es Registro de Errores API).
* ID de sección: `397bc8ec-2a86-4e24-9529-f1688108ccc9`
### Ritmos Operativos [#ritmos-operativos]
Rutina operativa recurrente de la empresa (revisión periódica que alguien debe ejecutar cada N horas), con responsables, departamento, prioridad y última ejecución autocalculada. Es la definición del ritmo; cada ejecución real se registra en Historial de ejecución de Ritmos operativos.
* ID de sección: `9ae0b146-3c92-40b2-89df-75c5702cbcbf`
### Sección de pruebas API [#sección-de-pruebas-api]
Sandbox para probar la API de Dinaup: un campo de cada tipo (booleano, enum, decimal, entero, fechas/horas con y sin segundos, texto, relación, lista) y autorrellenados de ejemplo. Sin significado de negocio — no usarla para datos reales.
* ID de sección: `3aa455c1-c14c-437a-8e85-45bc2521f433` · tiene **sección lista** (líneas del documento)
### Webhook Salientes [#webhook-salientes]
Suscripción webhook: cuando en una sección de Dinaup se crean o modifican registros, el servidor hace POST a la URL configurada (con bearer opcional). Es el push saliente por eventos; para polling saliente periódico usa HTTP CRON.
* ID de sección: `e637e767-f7cd-450c-ab5a-6c3cffe78a94`
# Proyectos, tareas y soporte (/docs/desarrollo/recursos/secciones-nucleo/proyectos-tareas-y-soporte)
Secciones de fábrica del núcleo de Dinaup en el dominio de **proyectos, tareas y soporte**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Actividad en Tareas de Proyectos [#actividad-en-tareas-de-proyectos]
Registro de tiempo/trabajo de un empleado sobre una tarea de proyecto: inicio, fin, tiempo total en minutos y descripción. Es el parte de trabajo (time tracking); no es la tarea ni el fichaje laboral.
* ID de sección: `35d1d661-7e94-432c-951c-a0fee5565743`
### Ampliaciones de horas en Bonos [#ampliaciones-de-horas-en-bonos]
Recarga de un bono de horas existente: añade importe (sin impuestos) a un Bono de horas, con estado de trámite y factura de venta opcional. No crea el bono ni registra su consumo — solo lo amplía.
* ID de sección: `07c7d2d1-a188-4fb2-ad41-17df3b66d439`
### Asignaciones de Tareas a Tareas [#asignaciones-de-tareas-a-tareas]
Vínculo de dependencia entre dos tareas de proyecto (Tarea1 depende/relaciona con Tarea2), con tipo de dependencia y proyecto de contexto. Es la tabla de enlaces del Gantt de proyectos; no es la asignación de personas a tareas (eso es Asignaciones de Empleados) ni de tareas a tickets.
* ID de sección: `fbcbb1d6-dc58-4c55-bc19-c8b3e0208690`
### Asignaciones de Tareas a Tickets & Soporte [#asignaciones-de-tareas-a-tickets--soporte]
Vínculo entre un ticket de soporte y una tarea de proyecto: cada registro ata un ticket a la tarea (de un proyecto concreto) que lo resuelve, con observaciones. Es la tabla puente ticket↔tarea, no el ticket ni la tarea en sí.
* ID de sección: `20a1cf58-77d2-45d9-b838-b54014b8a80c`
### Bonos horas [#bonos-horas]
Bolsa de horas prepagada de un cliente: saldo que se amplía con "Ampliaciones de horas en Bonos" y se consume desde Tareas de Proyectos. El servidor calcula ampliado, gastado y saldo; no es un presupuesto ni una tarifa.
* ID de sección: `8af32d17-67f8-45be-9dba-38da706db680`
### Flujos de Proyectos [#flujos-de-proyectos]
Plantilla de flujo de trabajo para tareas de proyectos: define, para un tipo de tarea, la secuencia ordenada de estados por los que pasa. Es configuración maestra, no una tarea ni un proyecto concretos.
* ID de sección: `fcd970b8-9933-47dd-ae0e-fd4213970628` · tiene **sección lista** (líneas del documento)
### Incidencias [#incidencias]
Incidencia reportada por un cliente: descripción, tipo, estado, resolución y preferencias de recontacto (días de la semana y franjas horarias de mañana/tarde). Distinta de Tickets / Soporte: aquí el foco es el aviso puntual y cuándo localizar al cliente.
* ID de sección: `48106f20-46bd-4d92-823c-c5dea5fc262e`
### Prioridades en Tickets & Soporte [#prioridades-en-tickets--soporte]
Catálogo de niveles de prioridad para tickets de soporte: número de prioridad, título, color e icono. Solo define la escala — la asignación a cada ticket vive en la sección de Tickets.
* ID de sección: `ad4a3b4f-7366-421b-9c70-9d6efdcfaa89`
### Proyectos [#proyectos]
Proyecto de trabajo con clave única, estado, flujo (kanban/Agile), cliente, equipo y contadores de tareas por fase. Es el contenedor del que cuelgan Tareas de Proyectos, Tickets y asignaciones de entidades; no confundir con Tareas (el trabajo) ni con Procesos de Venta.
* ID de sección: `362caf2d-605b-47dc-a1e2-db9c22f44cb9`
### Resoluciones de Tickets & Soporte [#resoluciones-de-tickets--soporte]
Catálogo de tipos de resolución con los que se cierra un ticket de soporte (resuelto, duplicado, no reproducible...): nombre, descripción e icono. Es el maestro de resoluciones, no el ticket ni su historial.
* ID de sección: `2d949e1c-0881-4aa3-b4da-af115c60f304`
### Respuestas a Tickets de Soporte [#respuestas-a-tickets-de-soporte]
Mensaje del hilo de conversación de un ticket de soporte: contenido, autor y fecha, ligado a su ticket. Un registro = una respuesta; el ticket en sí y su estado viven en Tickets & Soporte.
* ID de sección: `214c08f6-80e3-4479-b159-0100b5b60ba3`
### Roles en Proyectos [#roles-en-proyectos]
Catálogo de roles que una entidad puede desempeñar en un proyecto (jefe de proyecto, desarrollador...), con descripción, funciones, icono y flag de alta automática en el canal de Mattermost. Maestro simple que consumen las asignaciones a proyectos.
* ID de sección: `e9f1e1e2-29b1-4369-b273-bebde330984e`
### Severidad Tickets & Soporte [#severidad-tickets--soporte]
Catálogo de niveles de severidad para tickets de soporte (crítica, alta, media...), con color, orden y descripción. Distinto de Prioridades en Tickets: severidad mide el impacto del problema, no la urgencia de atención.
* ID de sección: `510cfeba-4c88-4814-b2fa-13b95f7d6bc5`
### Tareas [#tareas]
Tarea personal/operativa simple: título, contenido, empleado responsable, tipo, estado, prioridad y fechas de inicio/fin, evaluable en agenda. Para trabajo suelto del día a día — las tareas dentro de un proyecto van en Tareas de Proyectos.
* ID de sección: `22aff5d9-acb9-4fa7-a9e0-1a4e297abfdb`
### Tareas de Proyectos [#tareas-de-proyectos]
Tarea de gestión de proyectos (tipo Jira): clave+resumen, tipo, estado dentro del flujo del proyecto, asignado, progreso, dependencias y tiempo/coste imputado. Siempre pertenece a un Proyecto. No confundir con "Tareas" (tareas generales fuera de proyectos) ni con "Actividad en Tareas de Proyectos" (los registros de tiempo).
* ID de sección: `a14bf5fd-12ae-494f-8aaf-f6537c951c1e`
### Tickets & Soporte [#tickets--soporte]
Ticket de soporte/incidencia de un cliente: asunto, contenido, autor, tipo, estado, prioridad, severidad y resolución, con numeración por serie. Las conversaciones van en "Respuestas a Tickets de Soporte"; esto es la cabecera del caso.
* ID de sección: `8302a305-745b-4047-982b-c6d37b9790c2`
# RRHH y laboral (/docs/desarrollo/recursos/secciones-nucleo/rrhh-y-laboral)
Secciones de fábrica del núcleo de Dinaup en el dominio de **rrhh y laboral**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Asignaciones de Empleados a Agendas [#asignaciones-de-empleados-a-agendas]
Vínculo empleado-agenda: da acceso/suscripción de un empleado a una agenda concreta. Registro puramente relacional con flag Activo; el empleado se toma de la sesión al crear. No confundir con Eventos de Agendas (las citas) ni con la propia sección Agendas.
* ID de sección: `65bae43a-c46c-4f06-a4cc-d518835f4e43`
### Asignaciones de Empleados a Categorías de Archivos [#asignaciones-de-empleados-a-categorías-de-archivos]
Permiso de un empleado sobre una categoría de archivos: qué empleado puede acceder a qué categoría y con qué nivel (campo Permiso). Es la ACL del gestor documental por categorías — la categoría en sí vive en Categorías de Archivos.
* ID de sección: `3e831673-eaf3-4ddc-9b2c-029689a7b300`
### Asignaciones de Empleados a Subdepartamento [#asignaciones-de-empleados-a-subdepartamento]
Vínculo N:M entre un empleado y un departamento/subdepartamento: quién pertenece a qué área organizativa. El empleado lo fija la sesión al crear; el servidor mantiene coherente el par departamento-subdepartamento. No es la ficha del departamento ni del empleado — solo la pertenencia.
* ID de sección: `fca6a52f-5578-4614-9c6d-711320f40fad`
### Asignaciones de Horarios [#asignaciones-de-horarios]
Vincula un horario laboral a un empleado (o agenda) durante un periodo Desde/Hasta, con prioridad para resolver solapes. Es la asignación temporal, no la definición del horario (eso vive en Horarios).
* ID de sección: `02dccb8a-f5aa-4604-b2d9-a1be0bc157c4`
### Ausencias laborales [#ausencias-laborales]
Ausencia de un empleado en un rango de fechas (vacaciones, baja, permiso...), con motivo tipificado, estado de tramitación y duración en días y minutos calculada sola. No es un fichaje ni un turno: es el periodo en que el empleado NO trabaja.
* ID de sección: `eea8a43b-8e0f-4065-90cd-a17c074ee664`
### Cargos de trabajo [#cargos-de-trabajo]
Catálogo de puestos/cargos laborales de la empresa: nombre del cargo y descripción del puesto. Tabla maestra de RRHH que otras secciones (empleados, contratos) referencian; no es el contrato ni el empleado.
* ID de sección: `ad1f835b-6c23-4d9b-bd51-c820e8adb714`
### Contratos laborales [#contratos-laborales]
Contrato laboral de un empleado: vigencia (inicio obligatorio, fin opcional), estado, documento escaneado y política de vacaciones (días anuales y cómputo de fines de semana/festivos). Registro RRHH de condiciones; el empleado en sí vive en la sección Empleados y las ausencias en Ausencias laborales.
* ID de sección: `e1fd361e-cf56-42a0-9da3-dd50ae7b4bd0`
### Definición de jornadas [#definición-de-jornadas]
Plantilla de jornada laboral: define los tramos horarios de trabajo y descanso de un día tipo. El servidor totaliza turnos y duraciones automáticamente. Es la definición reutilizable que consumen horarios y asignaciones — no un registro de fichaje real.
* ID de sección: `eeadf6d0-3ae9-4e04-af8d-975ac34441f6` · tiene **sección lista** (líneas del documento)
### Departamentos [#departamentos]
Unidad organizativa de la empresa: nombre, jefe, misión, color e imagen. Es el nivel superior del organigrama — los Subdepartamentos cuelgan de él y los empleados se vinculan mediante asignaciones, no con un campo directo aquí.
* ID de sección: `2a702caa-795b-4c12-aef0-3e5409cb8ca6`
### Empleados [#empleados]
Ficha de empleado/usuario interno de la empresa: identidad, datos laborales (horario, departamento, cargo, manager), acceso al sistema (rol, 2FA, licencia), permisos de venta/TPV y subcuentas contables. Usar para el personal propio; los clientes y proveedores externos van en Entidades.
* ID de sección: `c6e071c7-776f-4300-aa55-c711fd1da916`
### Festivos [#festivos]
Calendario laboral de festivos: un periodo (Inicio–Fin, normalmente el año natural) cuyas líneas son las fechas festivas concretas. Se usa para cómputos laborales/horarios; no confundir con Ausencias laborales (faltas individuales) ni con Eventos de agendas.
* ID de sección: `683de8f0-13f5-4ce2-88ef-0d32c3adb666` · tiene **sección lista** (líneas del documento)
### Grupos de empleados [#grupos-de-empleados]
Agrupación arbitraria de empleados con nombre, detalles y contador automático de miembros; las líneas de la lista son los empleados que pertenecen al grupo. Úsala para colectivos transversales (equipos, comités, turnos de guardia), no para la estructura orgánica (eso son Departamentos/Subdepartamentos).
* ID de sección: `fb45074f-65e2-41a8-9841-9220e2999069` · tiene **sección lista** (líneas del documento)
### Historial de Descansos [#historial-de-descansos]
Registro de un descanso de jornada de un empleado dentro del control horario: entrada y salida del descanso con evidencia técnica (IP, navegador, URL, fingerprint) y posible anulación supervisada. Complementa a "Registros de fichajes laborales" (jornada completa); aquí solo pausas.
* ID de sección: `b8881637-bab8-494b-ae99-3d6596554bda`
### Horarios [#horarios]
Plantilla semanal de trabajo: un horario con nombre cuyas líneas asignan una jornada (Definición de jornadas) a cada día de la semana. Es el catálogo que luego se asigna a empleados; no registra fichajes ni fechas concretas.
* ID de sección: `5ce545e6-0cfd-4c7a-ba52-fcf42fec001d` · tiene **sección lista** (líneas del documento)
### Motivos de ausencias [#motivos-de-ausencias]
Catálogo de motivos de ausencia laboral (vacaciones, baja, permiso...) con su categoría, si exige justificante y si descuenta del saldo de días. Es el maestro que clasifica las Ausencias laborales; no registra la ausencia en sí.
* ID de sección: `2f263d3e-0828-4cd2-a574-21d0f5673e6d`
### Motivos de horas extras [#motivos-de-horas-extras]
Catálogo de motivos para turnos de horas extra o complementarias: nombre, tipo de turno y flag de fuerza mayor (solo válido en horas extra). Se referencia desde los registros de jornada/fichajes — aquí no se registran horas.
* ID de sección: `39ee21a3-3ad8-45ca-8bbc-0635cc0481b6`
### Nóminas [#nóminas]
Nómina mensual de un empleado: periodo (Desde/Hasta), conceptos en lista (devengos, deducciones, retenciones) y totales calculados por el servidor. Usar para el recibo de salarios individual; no para contratos ni fichajes.
* ID de sección: `48b24e31-ada5-4487-9534-5f15a41c21c2` · tiene **sección lista** (líneas del documento)
### Recursos de departamentos [#recursos-de-departamentos]
Recurso de contacto/operativo asignado a un departamento (y opcionalmente a un subdepartamento): un texto libre `Recurso` (extensión, email, sala, equipo...) clasificado por tipo. Es un dato del organigrama, no un recurso de empresa físico (eso es "Recursos de la empresa").
* ID de sección: `0805950d-ab7c-4ced-8ee1-ea9d751572ce`
### Registros de fichajes laboral [#registros-de-fichajes-laboral]
Fichaje individual de entrada/salida de un empleado con evidencia técnica (IP, navegador, URL, fingerprint) y tiempo trabajado calculado. Es el evento crudo del reloj; el turno consolidado con saldos vive en Turnos de trabajo.
* ID de sección: `c2b312ad-9909-4ef3-a405-14ef72031290`
### Socios / Comuneros [#socios--comuneros]
Registro de los socios o comuneros de la empresa: cada registro vincula una entidad como socio (única) y su lista guarda el histórico de participaciones con porcentaje y vigencia (fecha inicio/fin). Para composición societaria, no para clientes ni empleados.
* ID de sección: `5688dd01-cb38-406b-9fdf-4ae0f9d72d43` · tiene **sección lista** (líneas del documento)
### Subdepartamentos [#subdepartamentos]
Subdivisión organizativa dentro de un Departamento: nombre, jefe, misión, color e imagen. Segundo nivel del organigrama; los empleados se vinculan mediante la sección de asignaciones, no aquí.
* ID de sección: `e553920a-cf2d-4db5-9f4a-1b4394237c55`
### Turnos de trabajo [#turnos-de-trabajo]
Turno individual de un empleado en una fecha: programación (inicio/fin), realización real en tres capas (fichaje, supervisor, sistema), retrasos, horas extra/complementarias y saldos. Es el registro operativo diario del control horario; no confundir con Horarios ni Definición de jornadas, que son las plantillas que lo generan.
* ID de sección: `4709d046-d1c5-49bd-a76b-768c9acc1ceb`
# Tesorería (/docs/desarrollo/recursos/secciones-nucleo/tesoreria)
Secciones de fábrica del núcleo de Dinaup en el dominio de **tesorería**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Cuentas Bancarias [#cuentas-bancarias]
Cuenta bancaria de la empresa: banco, titular, IBAN/CCC, subcuenta contable, estado y saldo autocalculado desde Movimientos bancarios. Es el maestro sobre el que se concilian movimientos y se referencian cobros/pagos; no es la caja de efectivo (eso es Cajas).
* ID de sección: `fa7d1d75-6767-43bd-b411-3f363b5c0ba2`
### Métodos de pago [#métodos-de-pago]
Catálogo de formas de pago/cobro (efectivo, transferencia, tarjeta...): compatibilidad con conciliación bancaria, tramitación automática, depósito asociado e importe mínimo. Maestro que referencian ventas, compras, cobros, pagos y movimientos.
* ID de sección: `a0495ef9-7de0-4f4c-8435-82ee5acca0d0`
### Monedas [#monedas]
Catálogo maestro de divisas: código ISO 4217, símbolo, etiquetas singular/plural con género, icono y color de presentación. Solo define la moneda; no guarda tipos de cambio ni importes.
* ID de sección: `bf47cd77-0008-45b9-933d-e1edf8508520`
### Movimientos bancarios [#movimientos-bancarios]
Apunte de extracto bancario de una cuenta (depósito monetario tipo Cuenta Bancaria): fecha, concepto, importe, saldo y estado de conciliación contra cobros, pagos, otros movimientos o una subcuenta contable. No es el cobro/pago en sí — es el reflejo del banco que se concilia con ellos.
* ID de sección: `3cbdf508-3ad5-4414-b4c3-edc56df1d06a`
### Reglas de clasificación de movimientos bancarios [#reglas-de-clasificación-de-movimientos-bancarios]
Regla automática de conciliación: si el concepto del movimiento bancario contiene un texto, se le asigna tipo y/o entidad. Configuración del clasificador, no un movimiento en sí (eso es Movimientos bancarios).
* ID de sección: `fdca825c-9a30-4e8d-8ac0-4092c20755f4`
# Ventas y cobros (/docs/desarrollo/recursos/secciones-nucleo/ventas-y-cobros)
Secciones de fábrica del núcleo de Dinaup en el dominio de **ventas y cobros**. El ID de sección es idéntico en todas las instancias: úsalo directamente en la [API REST](/docs/desarrollo/integraciones/api-rest-referencia) o el [SDK .NET](/docs/desarrollo/dotnet/sdk/cliente). Cómo se comportan al escribir (autorrellenado, orden de campos, scripts): [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
### Asignaciones de Empleados a Procesos de Venta [#asignaciones-de-empleados-a-procesos-de-venta]
Vínculo N:M que da a un empleado acceso a un Proceso de Venta (pipeline comercial). Un registro = un empleado con acceso a un proceso, con flag Activo. Solo control de acceso; las etapas están en "Fases de Procesos de Venta".
* ID de sección: `63441db9-9488-4c32-a340-9395b1994635`
### Cajas [#cajas]
Caja de efectivo/TPV de la empresa (maestro): punto donde se cobra y se guarda dinero, con saldo calculado desde las transacciones monetarias internas, límites de saldo y subcuenta contable. No registra movimientos — eso son Movimientos de Caja y Cierres de Caja.
* ID de sección: `be9ab2d0-0572-451a-a10f-a53b651ab799`
### Canales de Venta [#canales-de-venta]
Catálogo de canales por los que se vende (tienda física, web propia, marketplace...): nombre, web y entidad dueña del canal, con reglas asociadas en Reglas de Canales de Venta. Solo clasifica el origen de la venta — no procesa pedidos.
* ID de sección: `f932622d-add5-4595-aa4f-40af0c90ecf9`
### Carritos de compra [#carritos-de-compra]
Línea de carrito de e-commerce: un producto o recurso que un visitante/cliente tiene en su carrito web antes de convertirse en Pedido. Registro efímero con caducidad, sesión web, IP y user-agent; no es venta ni pedido todavía.
* ID de sección: `f895b47a-0be9-40cf-a07e-2e069b9ddea0`
### Catálogos de venta [#catálogos-de-venta]
Lista de precios de venta: agrupa productos con precio, descuentos y límites de pedido, aplicable siempre o restringida por ubicación. Úsala para tarifas comerciales de venta; para precios de compra a proveedor existe la sección hermana Catálogos de compra.
* ID de sección: `ff5a07a8-add8-4c23-8bac-530d23cdf82f` · tiene **sección lista** (líneas del documento)
### Categorías de Ventas [#categorías-de-ventas]
Catálogo maestro de categorías para clasificar líneas de venta: nombre, subcuentas contables (ventas y devoluciones), flags de TPV y de servicios. Configuración, no documento; distinta de "Categorías de productos" (marketing/catálogo) y de "Categorías de Compra".
* ID de sección: `f4b84624-1fc2-40cc-88d2-99a227ae7a32`
### Cierres de Caja [#cierres-de-caja]
Arqueo de un depósito monetario en un rango de fechas: saldo inicial, totales de entradas/salidas por cobros de ventas, pagos de compras y otros movimientos, saldo final teórico, importe confirmado contado a mano y diferencia. Es la foto de cuadre de caja, no un movimiento.
* ID de sección: `17d4d716-81ee-4d68-9edf-6b0614492018`
### Cobros de Ventas [#cobros-de-ventas]
Registro de cobro asociado a una Venta / Ingreso: importe cobrado, método de pago, depósito monetario destino, estado (pendiente/tramitado), vencimiento y enlace a movimiento bancario o asiento contable. Es el flujo de dinero entrante de una venta, no la venta en sí.
* ID de sección: `10f52508-2ad5-4afe-9d0b-ef12d5914f10`
### Direcciones de envíos [#direcciones-de-envíos]
Direcciones de entrega guardadas de una entidad (cliente): destinatario, dirección normalizada por código postal/municipio/provincia/país y contacto. Es la libreta de direcciones para envíos de paquetería y pedidos — no la dirección fiscal de la entidad, que vive en su ficha.
* ID de sección: `54fa3578-5509-426a-b96f-e42fdd7bee9d`
### Entradas de inventario [#entradas-de-inventario]
Entrada manual de stock de un producto en un almacén (ajuste de inventario, no compra): producto + cantidad + almacén, con lote y hueco opcionales según el modo de gestión del producto. Genera y gobierna un Movimiento interno de inventario que modifica el stock real y disponible.
* ID de sección: `1f3747d6-5c20-4610-b93b-b1b11c24fad5`
### Entradas de ventas [#entradas-de-ventas]
Entrada de inventario por devolución de cliente ligada a una venta (rectificativa): registra que un producto vendido vuelve a un almacén y aumenta el stock vía movimiento interno. No es una entrada de compra (Entradas de Compra) ni una entrada manual (Entradas de inventario).
* ID de sección: `f4a3773e-6e90-4fa5-b873-dae8fe01c3e9`
### Enumeraciones nativas [#enumeraciones-nativas]
Catálogo de las enumeraciones del motor de Dinaup: cada registro es un enum nativo con su ID de rol de campo, título, descripción y flag de obsoleta. Sus valores concretos viven en Valores enumeraciones nativas. Metacatálogo de sistema, no configuración de negocio del usuario.
* ID de sección: `aa26761b-141d-44be-a783-3ab58d01da93`
### Envíos de paquetería [#envíos-de-paquetería]
Expedición física de bultos a un destinatario: dirección de entrega, transportista/tarifa, código y enlace de seguimiento, peso total y estado de trámite. Se enlaza a la Venta o Pedido que lo origina; sus líneas son los productos, recursos o lotes que van dentro. No es un transporte interno de recursos (eso es Ordenes de Transportes).
* ID de sección: `6520ba88-853b-4732-8d12-74a13dd1a104` · tiene **sección lista** (líneas del documento)
### Fases de Procesos de Venta [#fases-de-procesos-de-venta]
Etapa de un pipeline comercial (Proceso de Venta): título, orden dentro del proceso, color e icono. Configura las columnas del embudo por las que avanzan las oportunidades; no registra el paso de una oportunidad por la fase (eso es el "Historial de cambio de Fases").
* ID de sección: `9ac67dbe-73f4-4d84-866b-5594e8423a07`
### Historial de pagos Redsys [#historial-de-pagos-redsys]
Registro de cada intento de pago en el TPV virtual Redsys: la respuesta cruda de la pasarela (campos Ds\*), importe, estado, pedido y datos de sesión del pagador. Es un log de auditoría de transacciones — la configuración del terminal vive en TPVs Redsys; el cobro contable, en Cobros de Ventas.
* ID de sección: `9183f153-9e75-4c23-a45a-c6bbe035ee84`
### Libros registros de Ventas / Ingresos [#libros-registros-de-ventas--ingresos]
Catálogo maestro: libro registro fiscal al que se adscriben las ventas/ingresos (p. ej. libro de facturas emitidas). Solo nombre, descripción, orden y color; su gemelo para el lado del gasto es Libros registros de Compras / Gastos.
* ID de sección: `8065a1ea-038f-43a0-b8af-bdf571a7ea3f`
### Motivos de Cancelación de Pedido [#motivos-de-cancelación-de-pedido]
Catálogo de motivos por los que se cancela un pedido: cada motivo lleva el estado de pedido cancelado al que mueve, un mensaje para el cliente y un color. Es el maestro de motivos, no el registro de la cancelación de un pedido concreto.
* ID de sección: `3daf107c-d6d1-4796-9639-0ca3a24f668a`
### Movimiento interno de inventario (Compra-Venta) [#movimiento-interno-de-inventario-compra-venta]
Registro espejo que modifica el stock (físico y disponible) de un producto en un almacén/hueco/lote, generado y mantenido por documentos de origen como Entradas de Compra o Salidas de Venta. Casi todo es read-only: no se crea a mano — es la huella contable del inventario.
* ID de sección: `7c7f78fd-56d0-4030-b85a-d57e5ffd98cd`
### Movimientos de Caja [#movimientos-de-caja]
Entrada o retirada de efectivo en una caja (depósito monetario tipo Caja): importe, concepto, estado de tramitación y trazabilidad contable. Para dinero de caja física — no confundir con Movimientos bancarios ni con cobros/pagos de documentos.
* ID de sección: `b2b46811-3ecd-4b1b-947e-06626b029f43`
### Movimientos internos de inventario [#movimientos-internos-de-inventario]
Apunte de ajuste de stock: modifica el inventario y/o el stock disponible de un producto en un almacén (con hueco y lote opcionales), en positivo o negativo. Es el movimiento atómico interno, no una entrada de compra ni una salida de venta.
* ID de sección: `5ae1b0e1-f930-4a05-ba01-f83fba68562a`
### Numeraciones / Series [#numeraciones--series]
Serie de numeración de documentos: clave de serie, separador, contador actual y límites opcionales. La consumen ventas, compras, pedidos, productos, lotes, recambios, tickets... para generar sus códigos secuenciales. Configuración maestra — el contador lo gestiona el servidor.
* ID de sección: `a63e7622-30ca-425b-978e-1dd01c140de8`
### Objetivos de Venta [#objetivos-de-venta]
Objetivo mensual de facturación de un empleado con esquema de comisiones: importe base mensual, % de comisión sobre lo que supere el objetivo y tope mensual de comisión, vigente entre dos fechas que deben ser mes completo. No confundir con Objetivos de campañas de Marketing (metas de campañas, no de comerciales).
* ID de sección: `0adeb595-2d4f-4d49-a3f3-da03adbd5c1d`
### Pedidos [#pedidos]
Documento de pedido de venta: encargo de un cliente aún no facturado, con líneas de productos/recursos, cálculo completo de importes, descuentos e impuestos, estado de trámite y vencimiento. Se distingue de Ventas / Ingresos en que es el paso previo: desde él se genera la venta y el envío.
* ID de sección: `e6c3fd00-6a90-48a5-9ae9-7f6755e5edd9` · tiene **sección lista** (líneas del documento)
### Presupuestos de venta [#presupuestos-de-venta]
Documento comercial previo a la venta: oferta de productos/servicios a un cliente con precios, descuentos e impuestos, sin efecto fiscal ni de facturación. Nace en estado Borrador y puede convertirse en Venta/Ingreso; usar Ventas / Ingresos para la factura real.
* ID de sección: `ff4ea09c-1b83-462f-b782-60b8717d92a9` · tiene **sección lista** (líneas del documento)
### Procesos de Venta [#procesos-de-venta]
Definición de un pipeline comercial del CRM: nombre, descripción, color, fase inicial y quién puede usarlo. Las etapas viven en Fases de Procesos de Venta; los seguimientos de oportunidades se visualizan en kanban por proceso. Es configuración, no un seguimiento concreto.
* ID de sección: `3b4006d3-cc13-49d7-a976-ba0e7eb9a71f`
### Registros Verifactu [#registros-verifactu]
Log de envíos Verifactu a la AEAT: por cada factura (venta) registrada guarda el XML/JSON enviado, la respuesta, el tipo de operación, estado y flag de reintento. Registro técnico de cumplimiento generado por el servidor — la factura en sí vive en Ventas/Ingresos.
* ID de sección: `e2c892d9-431c-4d3f-ab53-1bb2f524a38b`
### Salidas de inventario [#salidas-de-inventario]
Salida manual de stock de un producto desde un almacén (ajuste, merma, consumo...): cantidad, lote y hueco opcionales, con estado (pendiente/completada/anulada) que decide cómo impacta el stock. No es la salida generada por una venta; es el documento de salida directa del módulo de inventario.
* ID de sección: `f09b320f-e100-45c4-a677-0954455471d7`
### Salidas de ventas [#salidas-de-ventas]
Salida física de inventario ligada a una venta: descuenta stock de un producto (con lote/hueco si aplica) desde un almacén al entregarlo al cliente. Distinta de "Salidas de inventario" (salidas genéricas) y de la venta misma: aquí se mueve stock, no dinero.
* ID de sección: `2c7d5f11-1b45-4f3a-85fa-7aefa0699cfa`
### Tarifas de envíos [#tarifas-de-envíos]
Tabla de costes y precios de envío por tramos de peso para una empresa de transporte, con límites por provincias, grupo de entidades o grupo de almacenes. Define cuánto cuesta y a cuánto se cobra el envío; no es el envío en sí (eso es Envíos de paquetería).
* ID de sección: `07bbe1d8-c7ab-4cde-a5e9-6b74ae2870e4` · tiene **sección lista** (líneas del documento)
### TPVs Redsys [#tpvs-redsys]
Configuración de un TPV virtual Redsys: código de comercio (FUC), número de terminal, configuración avanzada de API y estado inicial que recibirán los pagos. Es la pasarela configurada; las transacciones reales viven en Historial de pagos Redsys.
* ID de sección: `b643c685-b404-4c8f-acb8-dd0854af4123`
### Valores enumeraciones nativas [#valores-enumeraciones-nativas]
Cada valor posible de una enumeración nativa de Dinaup: número interno (ValorNativo), título legible, descripción, estilo de texto y flag de obsoleto. Es metacatálogo del sistema (documenta los enums del motor); no es una lista de valores configurable por el usuario para su negocio.
* ID de sección: `53bdcc8e-5c1f-4bd4-9906-5cb86b6992d3`
### Ventas / Ingresos [#ventas--ingresos]
Documento de venta/factura emitida: cabecera fiscal (cliente, impuestos, Verifactu, numeración) con líneas de productos/recursos vendidos. Es la factura real, no la propuesta (Presupuestos de venta) ni el encargo (Pedidos); genera cobros, salidas de inventario y asientos.
* ID de sección: `0ce4c6ac-54aa-488d-b8b8-e3a20d79f7a4` · tiene **sección lista** (líneas del documento)
# Contabilidad (/docs/rtg/pymes/contabilidad)
## Cuadro de cuentas [#cuadro-de-cuentas]
Organiza la estructura contable de la empresa, con las cuentas agrupadas por código y naturaleza. Puedes crear, modificar o importar el plan contable oficial.
### Atajos rápidos [#atajos-rápidos]
* **`43.` + `Enter`**\
Rellena la **próxima subcuenta libre** bajo el grupo 43.\
Ejemplo: si la última era `43000000`, se crea `43000001`.
* **`43.0` + `Enter`**\
Rellena la **primera subcuenta terminada en cero**.\
Ejemplo: crea `43000000` si aún no existe.
> El 43 es solo un ejemplo: sirve con cualquier cuenta.
***
## Asientos contables [#asientos-contables]
Registra y consulta las operaciones económicas de la empresa. Dispones de tres vistas según el nivel de detalle que necesites.
Consulta todos los asientos registrados, fíltralos por fecha o concepto y entra al detalle. Es el historial contable.
Vista para crear o editar un asiento con lo esencial: fecha, concepto y apuntes contables.
Muestra toda la información relacionada del asiento (documentos, registro, origen) y permite editar cada campo con más control. Úsala para revisar o ajustar un asiento al detalle.
***
## Contabilidad automática [#contabilidad-automática]
**Contabilidad automática**, disponible en la Aplicación de Pymes, contabiliza en bloque operaciones frecuentes (ventas, compras, pagos, nóminas). Pulsa `Contabilidad automática` para abrir la herramienta. Trabaja en dos pasos.
### 1. Cuentas contables automáticas [#1-cuentas-contables-automáticas]
Asignas o generas las cuentas contables que se usarán para cada operación.
### 2. Asientos contables automáticos [#2-asientos-contables-automáticos]
Genera los asientos contables de forma masiva a partir de esas operaciones.
# Inmovilizados (/docs/rtg/pymes/contabilidad/inmovilizados)
Da de alta cada activo de la empresa, amortízalo y dale de baja cuando llegue el momento, con su control contable y fiscal.
### Configuración inicial: Tipos y Estados [#configuración-inicial-tipos-y-estados]
Antes de empezar a registrar inmovilizados, conviene definir los tipos que vas a utilizar. Los defines en **Pymes > Configuración > Tipos de inmovilizado**.
### Tipos [#tipos]
Dinaup ya incluye varios tipos de inmovilizado por defecto, que puedes usar directamente o adaptar a tus necesidades:
* Patentes y marcas
* Software y licencias
* Herramientas y utillaje
* Instalaciones técnicas
* Mobiliario de oficina
* Equipos informáticos
* Vehículos
* Maquinaria industrial
* Edificios e inmuebles
> Por defecto, estos tipos vienen sin cuentas contables asociadas. Si vas a utilizar un **plan contable compartido**, tendrás que asignar las cuentas correspondientes a:
>
> * Cuenta de inmovilizado
> * Cuenta de amortización acumulada
> * Cuenta de dotación por amortización
### Estados [#estados]
Desde esta misma sección de configuración puedes definir los **estados** posibles de los inmovilizados. Estos estados permiten hacer seguimiento de la vida útil del activo:
* Planificado
* En pedido
* En uso
* En mantenimiento
* Revisión
* Retirado
* Dado de baja
* Vendido
* Perdido / Robado
### Compra [#compra]
Si vas a registrar la compra del inmovilizado directamente desde Dinaup, selecciona como **categoría de compra** una cuya **subcuenta contable pertenezca al grupo 2** (Inmovilizado).
Esto permite que:
* La compra se contabilice correctamente como activo, no como gasto.
* Dinaup pueda proponer la creación del inmovilizado al vincular la factura.
Por ejemplo, al comprar un vehículo, deberías usar una categoría con subcuenta como `218.0 – Vehículos`, no una del grupo 6 como sería habitual en compras de consumo.
### Registro de inmovilizados [#registro-de-inmovilizados]
Una vez definidos los tipos, puedes registrar tus activos desde el menú **Inmovilizados**, disponible en el lateral izquierdo de la App de Pymes. Aquí ves el listado de inmovilizados registrados y puedes añadir nuevos.
Al pulsar **Nuevo**, se abre el formulario completo para definir el activo. Este incluye:
* **Tipo** y **estado actual** del inmovilizado
* **Naturaleza**, que puede ser:
* Inmovilizado material
* Inmovilizado intangible
* Inversión inmobiliaria
* **Proveedor**, factura y elemento de compra asociado
* **Estado de adquisición**: nuevo o usado
* Cuentas contables asociadas al inmovilizado
* Coste de adquisición, valor residual y vida útil estimada
Puedes además adjuntar documentos, añadir notas y definir la fecha de entrada en funcionamiento del activo.
### Amortización automática [#amortización-automática]
Una vez creado el inmovilizado y definida su vida útil, pulsa el botón `Agregar amortización`: Dinaup genera los asientos contables correspondientes y calcula el importe anual.
Dinaup sigue este criterio:
```
Si la vida útil del activo es mayor que 0:
Amortización anual = (Coste – Valor residual) / Vida útil (en años)
```
Por ejemplo, si registras un vehículo por 100.000 €, con un valor residual de 10.000 € y vida útil de 10 años, el importe anual será:
**(100.000 – 10.000) / 10 = 9.000 € por año**
### Asiento contable generado [#asiento-contable-generado]
Al confirmar la amortización, se crean dos movimientos:
1. **Cargo a la cuenta de dotación por amortización** (grupo 68)
2. **Abono a la cuenta de amortización acumulada** (grupo 28)
Esto se refleja contablemente como:
* Debe: 6XX – Dotación amortización → 9.000 €
* Haber: 2XX – Amortización acumulada → 9.000 €
Ambas cuentas se toman de las que configuraste en el tipo de inmovilizado.
### Baja [#baja]
Cuando un activo llega al final de su vida útil o se vende, puedes darlo de baja desde la pestaña **Baja** dentro del formulario del inmovilizado. Aquí vinculas el asiento de baja correspondiente.
# Clientes (/docs/rtg/pymes/entidades/clientes)
**Clientes** es la lista de las personas y empresas a las que vendes. Cada cliente reúne sus datos de identidad, sus datos fiscales, sus ventas y lo que tiene pendiente de cobro. Cuando emites una factura, eliges el cliente de aquí.
Llegas desde **Pymes → Entidades → Clientes**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La lista de clientes se muestra en una tabla con búsqueda y filtros. Cada columna sale de la ficha del cliente y de sus operaciones. Desde la cabecera de la tabla filtras y ordenas para localizar un cliente concreto.
Un cliente es una **entidad** marcada como tal. La misma persona o empresa puede ser cliente y proveedor a la vez: son dos facetas de la misma ficha.
***
## Qué acciones tienes [#qué-acciones-tienes]
| Acción | Qué hace |
| ----------- | -------------------------------------------------- |
| **Cliente** | Abre la ventana para dar de alta un cliente nuevo. |
El resto de acciones (editar, ver ficha, exportar) están en la propia tabla y en la ficha de cada cliente.
***
## Ventanas [#ventanas]
* **Agregar Cliente**: se abre con el botón **Cliente**. Un alta rápida con los datos personales o de empresa, el NIF/CIF, la dirección y la configuración de venta (tipo de venta e impuesto). Incluye **Comprobar NIF** para validarlo contra la AEAT y **Leer de Documento** para extraer los datos de un archivo con IA.
* **Editar Entidad**: se abre al pulsar un cliente de la lista. Tiene dos pestañas: **General** (datos personales, fiscales, dirección y configuración de cliente y proveedor) y **Estadísticas** (totales facturados, comprados y movimientos, con gráficos por tipo y estado). Desde **Ver ficha completa** saltas al registro entero.
* **Datos fiscales**: la identificación fiscal y la dirección de la entidad. Valida el NIF contra la AEAT y avisa si algún dato no coincide con el de sus facturas. **Forzar guardado** ignora los avisos.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Sí. Cliente y proveedor son la misma ficha de entidad con configuraciones distintas. Una empresa a la que compras y vendes aparece en las dos listas.
En la ficha de datos fiscales de la entidad. El NIF/CIF se comprueba contra la AEAT y se avisa si no coincide con el de sus facturas.
***
→ [Proveedores](/docs/rtg/pymes/entidades/proveedores)
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
→ [Por cobrar](/docs/rtg/pymes/por-cobrar)
# Empleados (/docs/rtg/pymes/entidades/empleados)
**Empleados** es la lista de las personas de tu equipo. Cada empleado guarda sus datos de identidad y su configuración laboral, y es la base de sus [nóminas](/docs/rtg/pymes/nominas). Si trabajas con turnos y horarios, también recoge su actividad.
Llegas desde **Pymes → Entidades → Empleados**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La lista de empleados se muestra en una tabla con búsqueda y filtros. Cada empleado abre su ficha, con los datos personales y la organización interna (departamento, cargo, festivos).
***
## Ventanas [#ventanas]
La ficha del empleado se abre al pulsar una fila y tiene dos pestañas:
* **General**: el título (obligatorio), nombre, apellidos y NIF/CIF, más la configuración laboral: festivos, departamento, subdepartamento, cargo y un interruptor **Activo**.
* **RRHH**: solo si tienes acceso al módulo de Recursos Humanos. Reúne el histórico laboral en varias tablas: **Horarios**, **Vacaciones y ausencias**, **Turnos con retraso**, **Turnos futuros**, **Turnos ausencias**, **Turnos fuera de horario**, **Turnos completados** y **Turnos cancelados**.
Desde **Ver ficha completa** abres el registro entero del empleado.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La nómina se registra sobre un empleado. Para generar la nómina de una persona, esa persona tiene que existir aquí como empleado. Ver Nóminas.
El histórico laboral del empleado: horarios asignados, ausencias y el detalle de sus turnos (con retraso, futuros, completados, cancelados). Solo aparece si tienes activado el módulo de Recursos Humanos.
Que forma parte del equipo en activo. El diagnóstico usa este dato: avisa si hay empleados activos sin contrato vigente o sin nómina del mes.
***
→ [Nóminas](/docs/rtg/pymes/nominas)
→ [Registrar nómina](/docs/rtg/pymes/nominas/registrar-nomina)
# Entidades (/docs/rtg/pymes/entidades)
Una **entidad** es cualquier persona o empresa con la que se relaciona tu negocio. En Pymes se agrupan en tres pantallas según su papel:
A quién le facturas. La lista de clientes con sus ventas.
A quién le compras. La lista de proveedores con sus gastos.
Tu equipo. La lista de empleados y sus datos laborales.
Un cliente y un proveedor comparten la misma ficha de fondo: cambian los datos de venta o de compra que llevan asociados. Sus datos fiscales se mantienen aparte, en los [datos fiscales](/docs/rtg/pymes/mi-empresa) de cada entidad, y se validan contra la AEAT.
# Proveedores (/docs/rtg/pymes/entidades/proveedores)
**Proveedores** es la lista de las personas y empresas a las que compras. Cada proveedor reúne sus datos de identidad, sus datos fiscales y sus compras. Cuando registras una factura recibida o un gasto, eliges el proveedor de aquí.
Llegas desde **Pymes → Entidades → Proveedores**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La lista de proveedores se muestra en una tabla con búsqueda y filtros. Un proveedor es una **entidad** con configuración de compra: su tipo de compra, su impuesto y su categoría por defecto. La misma ficha puede ser a la vez cliente y proveedor.
***
## Qué acciones tienes [#qué-acciones-tienes]
| Acción | Qué hace |
| ------------- | ---------------------------------------------------------------------------------------- |
| **Proveedor** | Abre la ventana para dar de alta un proveedor nuevo. |
| **Revisar** | Abre la revisión de proveedores: audita quién tiene datos incompletos y sugiere valores. |
***
## Ventanas [#ventanas]
* **Agregar Proveedor**: se abre con el botón **Proveedor**. Alta rápida con los datos personales o de empresa, el NIF/CIF, la dirección y la configuración de compra (tipo de compra, impuesto y categoría). Incluye **Comprobar NIF** contra la AEAT y **Leer de Documento** para extraer los datos con IA.
* **Revisión de proveedores**: se abre con **Revisar**. Detecta proveedores sin tipo, sin categoría o sin impuesto y te deja corregirlos en bloque. Tiene KPIs (total, con errores, con avisos, correctos), dos vistas (**por proveedor** y **por problema**), filtros por severidad y un botón **Sugerir con IA** que propone los valores que faltan. Los cambios se aplican con **Guardar**.
* **Editar Entidad**: se abre al pulsar un proveedor de la lista. Pestañas **General** y **Estadísticas**, igual que en un cliente.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Para poner al día tus proveedores de golpe. Localiza los que no tienen tipo de compra, categoría o impuesto asignados (lo que luego descuadra la contabilidad) y te deja completarlos, con sugerencias de IA incluidas.
Sí. En su configuración de compra defines la categoría por defecto, que se aplica a sus gastos y facturas recibidas. Puedes cambiarla en cada operación.
***
→ [Clientes](/docs/rtg/pymes/entidades/clientes)
→ [Gestión de compras y gastos](/docs/rtg/pymes/facturacion/compras/gestion-de-compras-y-gastos)
→ [Categorías de compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra)
# Campos de importe en ventas y compras (/docs/rtg/pymes/facturacion/campos-de-importe)
Una factura no tiene un total: tiene tres, y los tres son correctos. El que se imprime, el que se declara a Hacienda y el que persigue el banco pueden ser tres cifras distintas en la misma factura. Esta página dice cuál es cuál.
## Los tres totales [#los-tres-totales]
| Campo | Qué es | Cuándo es distinto de los otros |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
| **Total** (`ImporteTotal`) | Lo que se imprime en la factura y lo que el cliente te debe. | Siempre que haya retención o suplidos. |
| **Total operación** (`ImporteTotalOperacion`) | El bruto fiscal: bases imponibles + IVA + recargo de equivalencia. Es el importe que se declara. | Si hay retención (aquí no está restada) o suplidos (aquí no están dentro). |
| **Total a cobrar / Total a pagar** (`ImporteTotalACobrar`, `ImporteTotalAPagar`) | El objetivo de cobro o de pago: lo que tiene que entrar o salir del banco. | En compras, si la factura lleva inversión del sujeto pasivo. |
Factura de 1.000 € de base con 21 % de IVA y 15 % de retención:
| | |
| --------------- | -------------- |
| Total operación | 1.210,00 € |
| Retención | −150,00 € |
| **Total** | **1.060,00 €** |
El cliente transfiere 1.060 €. A Hacienda se declaran 1.210 €.
## De dónde sale cada uno [#de-dónde-sale-cada-uno]
El cálculo va en este orden, y cada paso tiene su campo:
1. **Suma** (`ImporteSuma`) — precio por unidades de todas las líneas, sin descuentos. Es un dato informativo: no es la base de nada.
2. **Descuentos** (`ImporteTotalDescuentos`) — el de cada línea más los porcentajes generales de la cabecera. Los porcentajes generales **se suman entre sí**, no se encadenan.
3. **Subtotal** (`ImporteSubtotal`) — la suma de las bases imponibles, ya con los descuentos restados. Esta sí es la base.
4. **Impuestos** (`ImporteTotalImpuestos`) — las cuotas de IVA **más** las de recargo de equivalencia.
5. **Retención** (`ImporteTotalRetencion`) — el porcentaje de la ficha de retención aplicado sobre el **Subtotal**.
6. **Total** — total operación, más los suplidos, menos la retención.
`ImporteTotalImpuestos` lleva dentro el recargo de equivalencia. En un cliente con recargo, ese campo no es el IVA repercutido y no cuadra con el modelo 303. Para el IVA, usa las cuotas de cada base.
## Qué campo usar para cada cosa [#qué-campo-usar-para-cada-cosa]
| Quieres… | Usa | No uses |
| ----------------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------- |
| El importe que se declara a la AEAT o va en VeriFactu | `ImporteTotalOperacion` | `ImporteTotal`: ya lleva la retención restada |
| Saber si la factura está cobrada o pagada | `ImporteTotalACobrar` / `ImporteTotalAPagar` | `ImporteTotal`: en una factura con retención nunca llegará a cubrirse |
| La base imponible | `ImporteSubtotal` | `ImporteSuma`: no lleva los descuentos restados |
| Sumar descuentos de varias facturas | `ImporteTotalDescuentosSinImpuestos` | `ImporteTotalDescuentos`: cambia de significado según cómo se teclearan los precios |
| El tipo de IVA de cada base | La referencia al impuesto de esa base | La posición 1, 2 o 3 |
Las tres bases se reordenan de mayor a menor porcentaje cada vez que se recalcula la factura. La base 1 es el tipo más alto **de esa factura**, no el 21 %. Un informe que dé por hecho lo contrario cambia de resultado cuando borras una línea.
## Retención [#retención]
Se calcula sobre el **Subtotal**, no sobre el total. Dos consecuencias prácticas: los suplidos no retienen nunca, y cualquier descuento baja también la retención.
El importe se guarda en positivo y la factura lo muestra restando. En una rectificativa sale negativo. El porcentaje no se congela en la factura: sale de la ficha de retención cada vez que se recalcula, así que cambiarlo ahí afecta a toda factura que se vuelva a tocar.
→ [Retenciones](/docs/rtg/pymes/configuracion/retenciones)
## Suplidos [#suplidos]
Un suplido es dinero que adelantas por cuenta de otro y le refacturas. Pasa por el banco, pero no es ni ingreso ni gasto tuyo.
* Se marca en la **línea**, con el tipo de línea `Suplido`.
* No entra en ninguna base imponible ni en la retención.
* Sí está dentro de `ImporteTotal` y de `ImporteTotalSuplidos`, con sus impuestos si los lleva.
* No está dentro de `ImporteTotalOperacion`.
Por eso, en una factura con suplidos, `Subtotal + impuestos` no da el Total: falta el suplido.
## Ventas y compras no son espejo [#ventas-y-compras-no-son-espejo]
Los pares equivalentes se llaman distinto:
| Ventas | Compras |
| --------------------- | -------------------- |
| `ImporteTotalACobrar` | `ImporteTotalAPagar` |
| `ImporteTotalCobrado` | `ImporteTotalPagado` |
Y hay dos diferencias que no son de nombre:
* **`ImporteTotalAPagar` no es el reflejo de `ImporteTotalACobrar`.** En compras, además, resta las cuotas de los impuestos con inversión del sujeto pasivo, porque ese IVA no se paga al proveedor. Y vale 0 si la compra está marcada como gasto suplido en otra factura.
* **El descuento de la ficha de la entidad** entra en las dos, pero en compras lo hereda del proveedor. Si un proveedor tuyo es también cliente, revisa qué porcentaje se está aplicando.
## Lo que ya está cobrado [#lo-que-ya-está-cobrado]
`ImporteTotalCobrado` y `ImporteTotalPagado` los mantiene el sistema: se actualizan solos con cada cobro o pago, no se teclean.
**El pendiente no es un campo.** Es la resta entre el objetivo (`ImporteTotalACobrar`) y lo acumulado (`ImporteTotalCobrado`). Si haces esa resta en un informe, hazla contra el objetivo y no contra el total de la factura: con retención te saldría pendiente para siempre justo el importe retenido.
Una factura puede estar cobrada del todo y su cobro seguir sin puntear contra el extracto del banco. Son dos estados distintos y se ven en sitios distintos.
***
→ [La ventana de factura](/docs/rtg/pymes/facturacion/ventas/ventana-de-factura)
→ [VeriFactu](/docs/rtg/pymes/facturacion/ventas/verifactu)
→ [Leer datos con QuickQuery](/docs/desarrollo/dotnet/sdk/quickquery)
# Facturación (/docs/rtg/pymes/facturacion)
La facturación se separa en dos flujos según la dirección del documento.
Facturas recibidas de proveedores y gastos.
Facturas emitidas a clientes y otros ingresos.
# Libros Registros de Venta (/docs/rtg/pymes/libros-registros-de-venta)
Los **libros registro de venta** en Dinaup permiten agrupar y clasificar las facturas emitidas según su tipo: nacionales, simplificadas, intracomunitarias, exportaciones, etc.\
Cada factura se vincula sola a un libro en función del **tipo de venta** que se utilice. Así organizas la contabilidad, mantienes la trazabilidad y exportas los datos para tus declaraciones de IVA.
## Ejemplos [#ejemplos]
libro-de-ventas-simplificadas-tickets.md
libro-de-ventas-nacionales.md
libro-de-ventas-intracomunitarias.md
libro-de-ventas-exportaciones.md
# Libro de Ventas Exportaciones (/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-exportaciones)
En Dinaup, las **exportaciones** son operaciones de venta realizadas **a clientes fuera de la Unión Europea**. Estas operaciones están **exentas de IVA**, según el **artículo 21 de la Ley del IVA**, siempre que puedas acreditar que los bienes han salido efectivamente del territorio aduanero de la UE.
No deben confundirse con:
* Las **ventas intracomunitarias**, que se hacen dentro de la UE y están exentas si el cliente está en el VIES.
* Las **ventas nacionales**, que sí llevan IVA español.
* Las **ventas OSS**, que aplican solo a consumidores dentro de la UE bajo un régimen especial.
## Gestión de Libros [#gestión-de-libros]
Desde la **Aplicación de Pymes**, accede a **Configuración > Ventas / Ingresos > Libros**
Ahí verás el listado de libros existentes. De forma predeterminada, Dinaup ya incluye uno llamado **“Exportaciones”**, que sirve para **clasificar este tipo de operaciones.**
Este libro no requiere apenas configuración. Su función principal es **agrupar las exportaciones** para facilitar su control y exportación.
## Agregar Factura [#agregar-factura]
Para registrar una factura de exportación, sigue esta guía:
## Exportación [#exportación]
Haz clic en el botón **`“Exportaciones”`** dentro del bloque de **Libros de Facturas Emitidas**. El sistema te pide seleccionar un **periodo concreto** y te genera un **Excel con todas las operaciones** registradas bajo ese libro.
***
*Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Libro de Ventas Intracomunitarias (/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-intracomunitarias)
En Dinaup, las **ventas intracomunitarias** son, por defecto, **entregas o servicios realizados a clientes de la UE que están dados de alta en el VIES**.
No deben confundirse con:
* Las [**ventas OSS**](/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-oss), que aunque se hagan a países de la UE, **siguen un régimen distinto** y se declaran aparte.
* Las **ventas a particulares (B2C)** en la UE, cuando el cliente **no tiene NIF-IVA intracomunitario**. En estos casos, la operación se **registra como nacional**, aplicando el **IVA español**.
## Gestión de Libros [#gestión-de-libros]
Desde la **Aplicación de Pymes**, accede a **Configuración > Ventas / Ingresos > Libros**
Ahí verás el listado de libros existentes. De forma predeterminada, Dinaup ya incluye uno llamado **“Intracomunitarias”**, que sirve como **clasificación para identificar las ventas intracomunitarias**.\
No requiere apenas configuración adicional, ya que su objetivo es agrupar este tipo de operaciones.
## Agregar Factura [#agregar-factura]
Para dar de alta una venta intracomunitaria, sigue esta guía:
## Exportación [#exportación]
Haz clic en el botón **`“INTRACOMUNITARIAS”`** dentro del bloque de **Libros de Facturas Emitidas**. El sistema te pide seleccionar un **periodo concreto** y te genera un **Excel con todas las operaciones** registradas bajo ese libro.
***
*Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Libro de Ventas Nacionales (/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-nacionales)
En Dinaup, las **ventas nacionales** son, por defecto, aquellas realizadas a clientes establecidos en España, ya sea a empresas, profesionales o particulares. Estas operaciones **llevan IVA español**, salvo que estén exentas por algún motivo legal.
No deben confundirse con:
* Las **ventas intracomunitarias**, que están exentas si el cliente está en el VIES.
* Las **ventas OSS**, que aplican a consumidores finales en la UE y siguen un régimen diferente.
## Gestión de Libros [#gestión-de-libros]
Desde la **Aplicación de Pymes**, accede a **Configuración > Ventas / Ingresos > Libros**
Ahí verás el listado de libros existentes. De forma predeterminada, Dinaup ya incluye uno llamado **“Nacionales”**, que sirve como clasificación para identificar las ventas realizadas dentro del territorio nacional.
No requiere apenas configuración adicional, ya que su objetivo es **agrupar estas operaciones por tipo de venta**.
## Agregar Factura [#agregar-factura]
Para registrar una venta nacional, sigue esta guía:
## Exportación [#exportación]
Haz clic en el botón **`“NACIONALES”`** dentro del bloque de **Libros de Facturas Emitidas**. El sistema te pide seleccionar un **periodo concreto** y te genera un **Excel con todas las operaciones** registradas bajo ese libro.
***
*Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Libro de Ventas Simplificadas / Tickets (/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-simplificadas-tickets)
En Dinaup, las **facturas simplificadas** son aquellas operaciones documentadas sin identificar al cliente, normalmente para **ventas al por menor**, **tickets de TPV** o **servicios sin necesidad de facturación nominativa**. Estas operaciones están **sujetas al IVA correspondiente**, igual que una factura completa.
## Gestión de Libros [#gestión-de-libros]
Desde la **Aplicación de Pymes**, accede a **Configuración > Ventas / Ingresos > Libros**
Ahí verás el listado de libros existentes. De forma predeterminada, Dinaup ya incluye uno llamado **“Simplificadas”**, que sirve para **clasificar este tipo de operaciones** (TPV, tickets, albaranes sin datos de cliente, etc.).
Este libro no requiere apenas configuración. Su función principal es **agrupar las ventas simplificadas** para facilitar su control y exportación.
## Agregar Factura [#agregar-factura]
Para registrar una factura simplificada, sigue esta guía:
## Exportación [#exportación]
Haz clic en el botón **`“SIMPLIFICADAS”`** dentro del bloque de **Libros de Facturas Emitidas**. El sistema te pide seleccionar un **periodo concreto** y te genera un **Excel con todas las operaciones** registradas bajo ese libro.
***
*Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Nóminas (/docs/rtg/pymes/nominas)
Una nómina en Dinaup es un registro con un **empleado**, un **periodo** y una lista de **conceptos** (salario base, pluses, retenciones, cuota patronal). Puedes registrarla a mano o dejar que la IA la lea desde el PDF de tu gestoría. Al guardar, Dinaup calcula los totales y la deja lista para contabilizar.
## Qué encuentras en Pymes → Nóminas [#qué-encuentras-en-pymes--nóminas]
| Pestaña | Qué contiene |
| ---------------------- | --------------------------------------------------------------------------------------- |
| **Nóminas** | El listado de nóminas registradas, con el botón **Nuevo** para el alta manual. |
| **Archivos** | La cola de digitalización: subes los PDF, la IA los analiza y tú los revisas. |
| **Tipos de Conceptos** | El catálogo de conceptos: define cómo calcula y contabiliza cada línea. |
| **Tipos de Nóminas** | Catálogo de tipos de nómina (mensual, paga extra, finiquito). |
| **Estados de Nóminas** | Catálogo de estados para seguir el ciclo de cada nómina (pendiente, tramitada, pagada). |
## Tipo y estado de cada nómina [#tipo-y-estado-de-cada-nómina]
Al registrar una nómina eliges su **tipo** y su **estado** en la cabecera, junto al empleado y el periodo.
El **tipo de nómina** clasifica el recibo. Un catálogo habitual:
| Tipo de nómina | Cuándo se usa |
| ------------------- | ------------------------------------------------ |
| Mensual ordinaria | La nómina de cada mes |
| Paga extraordinaria | Junio y diciembre, cuando no van prorrateadas |
| Finiquito | Liquidación al terminar el contrato |
| Atrasos de convenio | Diferencias de una subida con efecto retroactivo |
El **estado** sigue el ciclo de la nómina. Un catálogo habitual:
| Estado | Qué significa |
| --------- | --------------------------- |
| Pendiente | Registrada, aún sin revisar |
| Tramitada | Revisada y lista para pagar |
| Pagada | Ya abonada al trabajador |
En **Configuración del negocio → RRHH** fijas el **estado inicial**, que la nómina toma sola al crearse, para no elegirlo cada vez.
## Lo que Dinaup calcula en cada nómina [#lo-que-dinaup-calcula-en-cada-nómina]
Al guardar una nómina, el servidor recorre sus conceptos y rellena los totales según el tipo de cada uno:
| Total | Qué suma |
| -------------------------------- | -------------------------------------------------------------------------- |
| **Total devengos** | Todo lo que gana el trabajador |
| **Deducciones del empleado** | Anticipos y otras deducciones que se le restan |
| **Retenciones del empleado** | IRPF y cuota obrera que se retienen e ingresan |
| **Retenciones de empresa** | Cuota patronal y demás costes a cargo de la empresa |
| **Líquido a percibir** | Devengos que afectan al neto, menos deducciones y retenciones del empleado |
| **Coste de empresa** | Devengos más retenciones de empresa: lo que la nómina te cuesta de verdad |
| **Pago en especie** | Los devengos marcados como especie |
| **Pago a TGSS, AEAT y terceros** | Las retenciones agrupadas por su destino de ingreso |
## Digitalización con IA [#digitalización-con-ia]
Sube el PDF de una nómina y la IA extrae el empleado (por su NIF), el periodo y cada concepto con su importe, distinguiendo devengos, retenciones del trabajador y aportaciones de la empresa. Tú revisas el resultado con el PDF al lado y guardas. El coste por documento se muestra antes de analizar.
## Contabilidad [#contabilidad]
Cada tipo de concepto lleva su **Cuenta Debe** y su **Cuenta Haber**: cada línea de la nómina anota contra ellas. Desde **Contabilidad automática** generas en bloque los asientos de las nóminas del periodo que aún no lo tienen, y cada nómina queda enlazada a su asiento. Si el empleado tiene sus subcuentas configuradas (640, 460, 465), el asiento usa la subcuenta del trabajador.
## Configuración a nivel de empresa [#configuración-a-nivel-de-empresa]
En **Configuración del negocio → RRHH** defines los ajustes generales del ciclo de nómina:
* **Estado inicial de nóminas** y **estado de nóminas pagadas**: los estados de tu catálogo con los que sigues el ciclo.
* **Instrucciones IA para procesamiento de nóminas**: texto libre que guía a la IA al clasificar los conceptos de tus PDF.
## Quién ve las nóminas [#quién-ve-las-nóminas]
El acceso al módulo se controla por permisos de sección: quien tiene lectura sobre la sección Nóminas ve el listado y la cola de archivos. Concede ese permiso solo a quien lleve la administración de personal.
***
# Registrar Nómina (/docs/rtg/pymes/nominas/registrar-nomina)
## El tipo de concepto, campo a campo [#el-tipo-de-concepto-campo-a-campo]
Los conceptos se dan de alta en **Pymes → Nóminas → Tipos de Conceptos**. Cada uno se define una vez y se reutiliza en todas las nóminas.
| Campo | Qué define |
| ------------------------------ | --------------------------------------------------------------------------- |
| **Nombre** | Cómo aparece el concepto (ej. Salario base) |
| **Tipo** | `Devengo`, `Deducción empleado`, `Retención empleado` o `Retención empresa` |
| **Destino pago retención** | A quién se ingresa: `TGSS`, `AEAT` o `Terceros` |
| **Afecta al neto** | Si el devengo entra en el líquido a percibir |
| **Especie** | Retribución en especie; se acumula en su propio total |
| **Aplica a todas las nóminas** | Concepto que va siempre (salario base, IRPF) |
| **Cuenta Debe / Cuenta Haber** | Las cuentas contables contra las que anota cada línea |
| **Anotaciones para IA** | Pistas para el lector de PDF (ej. "va tras II. DEDUCCIONES") |
Al elegir el tipo de concepto en una línea de nómina, el servidor copia y bloquea en esa línea su clasificación, sus cuentas y su destino de retención: el usuario solo elige el concepto y teclea el importe.
## El editor de nómina [#el-editor-de-nómina]
Se abre con **Nuevo** (alta manual), al abrir una nómina del listado (edición) o al pulsar **Revisar** en la cola (precargado por la IA, con el PDF al lado).
| Elemento | Qué hace |
| ------------------------- | --------------------------------------------------------------------------------------------- |
| **Empleado** | Buscador sobre tu plantilla. Obligatorio. |
| **Desde / Hasta** | El periodo de liquidación, normalmente el mes natural. |
| **Fecha contable** | La fecha con la que la nómina entra en informes y contabilidad. Obligatoria. |
| **Tipo de nómina** | Mensual, paga extra, finiquito, atrasos. |
| **Estado** | El punto del ciclo (pendiente, tramitada, pagada). Llega con el estado inicial configurado. |
| **Conceptos** | Una línea por concepto: tipo, descripción e importe. Siempre queda una fila libre al final. |
| **Líquido (orientativo)** | El neto estimado según los tipos elegidos. El cálculo oficial lo hace el servidor al guardar. |
En una línea sin tipo, el botón **+** junto al selector crea el concepto en el catálogo sin salir de la nómina.
Reglas del editor:
* Los **importes van en positivo**; el tipo ya dice si suman o restan. Solo devoluciones o regularizaciones van en negativo.
* Toda línea con contenido necesita su **tipo**: sin él no entra en los totales ni en el asiento, y el editor bloquea el guardado hasta que lo asignes.
* Al elegir un tipo en una línea sin descripción, la descripción hereda el nombre del tipo.
## La cola de archivos (digitalización IA) [#la-cola-de-archivos-digitalización-ia]
En **Pymes → Nóminas → Archivos** viven los PDF pendientes de convertir en nómina.
| Estado | Qué significa | Acciones |
| ------------- | ---------------------------------------------------------------- | ----------------------------------------- |
| **Pendiente** | Subido, sin analizar | **Analizar** · **Rechazar** |
| **Analizada** | La IA ya extrajo los datos; falta tu revisión | **Revisar** · **Rechazar** |
| **Procesada** | Revisada y convertida en nómina; el PDF queda anclado a la ficha | Consultar desde la pestaña **Procesadas** |
| **Rechazada** | Descartada (duplicado, ilegible, no procede) | Consultar desde la pestaña **Rechazadas** |
* La subida admite **PDF, PNG y JPG hasta 20 MB**, en lote. Los archivos repetidos se detectan y no se duplican.
* **Analizar N** procesa el lote completo con el nivel de IA que elijas: **Rápido** (0,05 € por nómina), **Equilibrado** (0,10 €, recomendado) o **Profundo** (0,15 €).
* Cada tarjeta analizada muestra empleado, periodo, los primeros conceptos y el importe estimado.
* El buscador filtra por nombre de archivo o de empleado.
## Contabilizar [#contabilizar]
Abre la nómina guardada, busca el campo **Asiento contable** y pulsa el **+**. Se abre el asiento rellenado sin guardar: una vista previa de cómo Dinaup lo arma según las cuentas de tus conceptos. Revísalo y guarda.
**Pymes → Contabilidad → Contabilidad automática**, pestaña **Nóminas**: lista las nóminas del periodo sin asiento. Marca y pulsa **Procesar** para generarlos en bloque.
El procedimiento completo está en [Contabilidad Automática](/docs/rtg/pymes/procesos/contabilidad-automatica).
El how-to con los tres flujos (conceptos, alta y contabilización) está en [Gestión de nóminas](/docs/guias/nominas).
# Agregar facturas expedidas por otro software (/docs/rtg/pymes/preguntas-frecuentes/agregar-facturas-expedidas-por-otro-software)
Cuando tu empresa emite facturas en una plataforma externa (por ejemplo, **Stripe**) conviene registrarlas en Dinaup para que la información contable y fiscal quede unificada.
### Crea un Tipo de Venta [#crea-un-tipo-de-venta]
1. Ve a **Pymes → Configuración → Ventas / Ingresos → Tipos**.
2. Crea un **nuevo Tipo de Venta** y nómbralo, por ejemplo, *Stripe*.
3. Marca el campo `Factura emitida con otro Software (Importada)`.
4. Guarda el registro.
### Agregar Factura [#agregar-factura]
En **Pymes → Ventas / Ingresos**, pulsa sobre el tipo que deseas agregar.
# Preguntas frecuentes (/docs/rtg/pymes/preguntas-frecuentes)
Dudas frecuentes de fiscalidad, tipos de venta y precios. Las dudas de inventario y stock tienen su propio bloque en la [FAQ general](/docs/rtg/preguntas-frecuentes) y su explicación completa en [Cómo funciona el stock](/docs/guias/como-funciona-el-stock). Si no encuentras la respuesta, escribe a `soporte@dinaup.com` o abre el chat de ayuda en [play.dinaup.com](https://play.dinaup.com).
***
## Fiscalidad [#fiscalidad]
No, **IVA 0% y exento no son lo mismo**. El **IVA 0%** significa que la operación está **sujeta al impuesto** pero se aplica un tipo del 0%, como en exportaciones o entregas intracomunitarias, y **permite deducir el IVA soportado**. En cambio, una operación **exenta** está **fuera del ámbito del IVA**, como ocurre con comisiones bancarias o servicios médicos, y puede **limitar el derecho a deducción**. Aunque ambas resultan en "sin IVA en la factura", fiscalmente tienen efectos diferentes y deben declararse por separado.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
Para registrar facturas exentas en Dinaup, lo ideal es **crear o seleccionar un** [tipo de compra](/docs/rtg/pymes/facturacion/compras) **o** [tipo de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) **ya configurado como "exento"**, de modo que al seleccionarlo, la factura se registre correctamente sin aplicar IVA. También puedes marcar manualmente la opción "exenta" dentro de la propia factura, pero esto es más tedioso y propenso a errores. Usar tipos predefinidos agiliza el proceso y evita equivocaciones en la contabilidad y las declaraciones fiscales.
***
## Facturación [#facturación]
Para incorporar en Dinaup las facturas generadas en un sistema externo (por ejemplo, **Stripe**) basta con crear un nuevo **Tipo de Venta** desde **Pymes → Configuración → Ventas / Ingresos → Tipos** y activar el campo **Factura emitida con otro Software (Importada)**.
***
## Precios de productos [#precios-de-productos]
Los precios en Dinaup se gestionan con **catálogos**. Un [Catálogo de Venta](/docs/rtg/pymes/inventario-y-precios) fija los precios de venta de tus productos; puedes tener **varios catálogos** para distintos clientes o canales, así que un cliente VIP puede llevar su propia tarifa sin que dupliques el producto. Lo mismo del lado de la compra con los [Catálogos de Compra](/docs/rtg/pymes/inventario-y-precios), uno por proveedor.
Cuando abres una venta o una compra y eliges al cliente o proveedor, se aplica el catálogo que le corresponde y los precios se rellenan solos.
→ [Inventario y Precios](/docs/rtg/pymes/inventario-y-precios)
Eso no lo decide el producto, lo decide el **tipo de venta** con su opción **Inclusión de impuestos**: determina si la factura se confecciona con los importes con impuestos incluidos o sin ellos. Así, un mismo producto puede facturarse "IVA incluido" en un escenario (típico de TPV / ticket) y "base + IVA" en otro, según el tipo de venta que uses.
→ [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
Los descuentos se aplican en la propia factura, **por línea** (a un producto concreto) o **global** (a toda la venta). Esto es independiente del precio de catálogo: partes del precio de tarifa y aplicas el descuento encima al confeccionar la venta o el presupuesto.
Sí, desde el **tipo de venta**. Su campo **Impuesto** sobrescribe el IVA configurado en los productos. El caso típico: aunque tus productos estén al 21 %, defines un tipo de venta intracomunitario con impuesto al 0 % para clientes dados de alta en VIES, y no tienes que cambiar el IVA de cada producto.
→ [Tipo de Venta Intracomunitaria (VIES)](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-intracomunitaria-vies)
No si trabajas con catálogos. Como el precio vive en el [Catálogo de Venta](/docs/rtg/pymes/inventario-y-precios) y no en cada factura, editar el catálogo deja listos los nuevos precios para las próximas ventas. Para tarifas distintas (un canal más caro, un cliente con condiciones especiales) usas catálogos separados en lugar de reescribir precios uno a uno.
***
## Tipos de venta [#tipos-de-venta]
Elige según el contexto fiscal de la operación. Estos son los escenarios habituales, cada uno con su página de detalle:
| Situación | Tipo de venta |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Venta dentro de España con IVA | [Nacional](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-nacional) |
| Ticket / venta de mostrador sin datos de cliente | [Simplificada](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-simplificada) |
| Venta a empresa de la UE con NIF-IVA | [Intracomunitaria (VIES)](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-intracomunitaria-vies) |
| Venta a particular de la UE | [OSS](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-oss) |
| Venta fuera de la UE | [Exportación](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion) |
| Venta a Canarias, Ceuta o Melilla | [Exportación Canarias / Ceuta / Melilla](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion-canarias-ceuta-y-melilla) |
| Bienes usados (régimen especial) | [REBU](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-reb) |
| Hostelería en TPV táctil | [TPV Hostelería](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-tpv-hosteleria) |
→ [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
Son dos clasificaciones distintas que conviven en la misma factura:
* El **tipo de venta** responde a "¿cómo se factura esto?": decide el IVA, las retenciones, las validaciones de NIF y la numeración.
* La **categoría de venta** responde a "¿de qué es esta venta?": agrupa los ingresos por línea de negocio (Servicios, Productos, Cursos…) para los informes y la contabilización automática.
Una factura intracomunitaria (tipo) puede ser de "Servicios" (categoría). No mezcles los conceptos: el tipo es fiscal, la categoría es analítica.
→ [Categorías de Venta](/docs/rtg/pymes/facturacion/ventas/categorias-de-venta)
El **tipo de venta** es lo que enlaza cada factura con su **libro registro**: cada factura se vincula automáticamente al libro que corresponde según el tipo (nacionales, simplificadas, intracomunitarias, exportaciones…), lo que deja tu facturación lista para Hacienda y para tus declaraciones de IVA. El tipo también fija el IVA aplicado (incluido forzar un 0 % en VIES) y la serie de numeración.
→ [Libros Registro y Tipos de Venta](/docs/rtg/pymes/facturacion/ventas/libros-registro-y-tipos-de-venta) · [Libros Registros de Venta](/docs/rtg/pymes/libros-registros-de-venta)
Con un tipo de venta marcado como **Es un ingreso sin factura**. El sistema lo trata como un ingreso contable sin factura asociada (y por tanto sin numeración de factura). Las **Sugerencias inteligentes** de Dinaup detectan la palabra "Ingresos" en el nombre del tipo y te orientan hacia esta configuración.
→ [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
Porque cada tipo tiene una casilla **Disponible en TPV**. En la app de **Pymes** se ven todos los tipos (está pensada para usuarios avanzados); en el **TPV** solo aparecen los marcados como disponibles, ya que está pensado para ventas rápidas y sencillas (normalmente simplificadas en mostrador, supermercado, hostelería). Si un tipo no sale en el TPV, revisa esa casilla.
Con la opción **Países permitidos** del tipo de venta. Defines una lista de países en formato ISO 3166-1 alfa-2 (`ES,FR,IT`) y una política **Incluir** (solo esos) o **Excluir** (todos menos esos). Incluso puedes afinar por provincia (`ES[Ceuta]`, `ES[!Canarias]`). Así un tipo de exportación, por ejemplo, solo se podrá usar con destinos válidos.
→ [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
***
## Inventario y stock [#inventario-y-stock]
En dos sitios, según lo que busques:
* **Dudas rápidas** (por qué no baja el stock, sobreventa, lotes, ajustes): bloque de inventario de la [FAQ general](/docs/rtg/preguntas-frecuentes).
* **El modelo completo** (disponible vs físico, estados de una salida, FIFO/FEFO, cuarentena): [Cómo funciona el stock](/docs/guias/como-funciona-el-stock).
# Contabilidad Automática (/docs/rtg/pymes/procesos/contabilidad-automatica)
### Abre la Herramienta de Contabilización automática [#abre-la-herramienta-de-contabilización-automática]
En la Aplicación de Pymes navega hacia Pymes -> Contabilidad -> Contabilidad Automática.
Se abre la herramienta, que te permite:
1. Crear Cuentas
2. Crear Asientos
### Crear cuentas Contables [#crear-cuentas-contables]
En esta ventana verás una cuadrícula de tarjetas con los datos sobre los que se pueden crear cuentas contables.
1. Clientes: se pueden crear cuentas del grupo 430
2. Categorías de Venta: se pueden crear cuentas del grupo 700
# Exportación (/docs/rtg/pymes/procesos/exportacion)
Desde el **Centro de Exportación** generas los registros de la empresa: libros de facturas emitidas y recibidas, y extractos bancarios.
# Procesos (/docs/rtg/pymes/procesos)
Los procesos más habituales en Pymes:
* [Emisión de Facturas](/docs/rtg/pymes/procesos/emision-de-facturas): cómo emitir facturas según el tipo de operación.
* [Exportación](/docs/rtg/pymes/procesos/exportacion): generar y exportar libros y extractos.
* [Contabilidad Automática](/docs/rtg/pymes/procesos/contabilidad-automatica): generar cuentas y asientos contables sin hacerlos a mano.
# Auditoría de reglas y clasificación de movimientos (/docs/rtg/pymes/tesoreria/auditoria-de-reglas-y-clasificacion-de-movimientos)
Dinaup te permite auditar la clasificación bancaria desde la propia ficha de cada cuenta. Podrás revisar qué reglas se han aplicado, detectar movimientos sin clasificar y asegurarte de que todo encaja.
### Accede a la ventana de auditoría [#accede-a-la-ventana-de-auditoría]
Ve a `Pymes` > `Cuentas bancarias`, selecciona la cuenta que quieras auditar y pulsa el botón `Clasificación extracto`.
### Filtra el periodo que quieres revisar [#filtra-el-periodo-que-quieres-revisar]
En la parte superior, elige el **año** y el **trimestre** que quieras auditar (o selecciona `*` para ver todo el año).
### Navega por las pestañas [#navega-por-las-pestañas]
La ventana tiene 4 pestañas que te ayudarán a revisar el estado de la clasificación:
#### 1. Sin reglas [#1-sin-reglas]
Movimientos que no se han clasificado automáticamente. Úsalo para detectar patrones que podrían convertirse en una nueva regla.
***
#### 2. Con reglas [#2-con-reglas]
Movimientos que ya ha clasificado una regla. Aquí puedes comprobar rápidamente si la clasificación está funcionando.
***
#### 3. Reglas [#3-reglas]
Listado de reglas aplicadas en el periodo, con la cantidad de movimientos que han clasificado. Muy útil para validar si tus reglas están activas y en uso.
***
#### 4. Integridad [#4-integridad]
Muestra movimientos que **deberían haber sido clasificados** según las reglas actuales, pero que no lo fueron en el momento de la importación (porque las reglas no existían aún o fueron modificadas después).
> Por seguridad, Dinaup **solo aplica reglas en el momento de importar el extracto**, no retroactivamente.
# Bancos (/docs/rtg/pymes/tesoreria/bancos)
Un **banco** es la **entidad financiera** con la que trabaja tu empresa: el banco como tal (su nombre, su marca). De cada banco cuelgan una o varias [cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias), que son los depósitos concretos con IBAN donde se mueve el dinero.
Distinguir el banco de la cuenta es lo primero que conviene tener claro en tesorería: el banco es la **entidad**, la cuenta es el **depósito**.
***
## Banco frente a cuenta bancaria [#banco-frente-a-cuenta-bancaria]
No son lo mismo, aunque van de la mano. El banco es el "paraguas"; la cuenta es lo que cuelga de él.
| | Banco (entidad) | [Cuenta bancaria](/docs/rtg/pymes/tesoreria/cuentas-bancarias) (depósito) |
| ------------------- | ---------------------------------------- | ------------------------------------------------------------------------- |
| Qué es | La entidad financiera con la que operas | El depósito de dinero, identificado por su IBAN |
| Tiene IBAN | No | Sí |
| Tiene saldo | No, es solo la entidad | Sí, refleja el dinero disponible |
| Tiene movimientos | No directamente | Sí: cobros, pagos y el extracto importado |
| Cuántos por empresa | Uno por cada entidad con la que trabajas | Una o varias por cada banco |
Una misma entidad puede tener **varias cuentas** colgando: por ejemplo, una cuenta de operativa diaria y otra de ahorro, ambas bajo el mismo banco.
***
## Para qué sirve dar de alta el banco [#para-qué-sirve-dar-de-alta-el-banco]
Tener la entidad registrada ordena tu tesorería y te ahorra trabajo después:
* **Agrupa tus cuentas por entidad.** Ves qué cuentas tienes en cada banco, en vez de una lista plana de IBAN sueltos.
* **Identifica y clasifica los movimientos.** Al saber a qué entidad pertenece cada cuenta, los cobros, pagos y movimientos del extracto quedan correctamente atribuidos.
* **Reutilización.** Una vez creado, el banco está disponible para asociarlo a todas las cuentas que abras en esa entidad, sin volver a teclear sus datos.
Si solo trabajas con una única cuenta y un único banco, igualmente te interesa darlo de alta: es el paso previo para crear la cuenta y empezar a importar extractos.
***
## Crear un banco [#crear-un-banco]
### Abre tu tesorería [#abre-tu-tesorería]
Ve a **Pymes → Tesorería**. Ahí gestionas tanto las entidades bancarias como las cuentas que cuelgan de ellas.
### Da de alta la entidad [#da-de-alta-la-entidad]
Crea un banco nuevo e indícale un nombre que identifique la entidad con claridad (el nombre del banco). Este registro representa a la entidad, todavía sin IBAN ni saldo.
### Asóciale sus cuentas [#asóciale-sus-cuentas]
Con el banco creado, crea una o varias [cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias) y enlázalas a esa entidad. Cada cuenta aporta su IBAN y es la que recoge el saldo y los movimientos.
El orden natural es **primero el banco y después la cuenta**: así, al crear la cuenta, eliges la entidad de una lista en lugar de escribirla de nuevo.
***
## Relación con las cuentas y la conciliación [#relación-con-las-cuentas-y-la-conciliación]
El banco por sí solo no se mueve: no tiene saldo ni extracto. Toda la actividad vive en las **cuentas** que cuelgan de él. Sobre cada cuenta importas el extracto, registras cobros y pagos y haces la [conciliación](/docs/rtg/pymes/tesoreria/conciliacion-bancaria).
Por eso, cuando trabajes el día a día de tesorería, lo harás siempre desde la cuenta. El banco es el dato de fondo que mantiene todo ordenado y bien clasificado por entidad.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El banco es la entidad financiera (su nombre); la cuenta bancaria es el depósito con IBAN que cuelga de esa entidad y donde se mueve el dinero. Un banco puede tener varias cuentas.
Es lo recomendable. Si das de alta primero la entidad, al crear la cuenta solo tienes que seleccionarla de la lista en vez de escribir sus datos de nuevo.
Sí. De una misma entidad pueden colgar varias cuentas (por ejemplo, una de operativa y otra de ahorro), cada una con su propio IBAN y su saldo.
No. El saldo, el extracto y los movimientos viven en cada cuenta bancaria. El banco es solo la entidad que las agrupa.
***
→ [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias)
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
→ [Cajas](/docs/rtg/pymes/tesoreria/cajas)
# Cajas (/docs/rtg/pymes/tesoreria/cajas)
Una **caja** es un depósito de efectivo dentro de tu tesorería: representa el dinero físico que entra y sale de un punto concreto del negocio, como el mostrador, una sucursal o la caja fuerte. Es el hermano de la [cuenta bancaria](/docs/rtg/pymes/tesoreria/cuentas-bancarias): ambos son **depósitos monetarios**, pero la caja guarda billetes y monedas, no saldo en el banco.
***
## Caja frente a cuenta bancaria [#caja-frente-a-cuenta-bancaria]
Las dos viven juntas bajo el mismo concepto de depósito, y en cualquier proceso de tesorería (como un cierre) eliges una u otra como origen del dinero. La diferencia es de dónde sale ese dinero y cómo cuadra.
| | Caja (efectivo) | [Cuenta bancaria](/docs/rtg/pymes/tesoreria/cuentas-bancarias) |
| ------------------ | ----------------------------------------------- | ------------------------------------------------------------------------------------------ |
| Qué contiene | Dinero físico (billetes y monedas) | Saldo en una entidad bancaria |
| Movimientos | Ingresos y salidas de efectivo que registras tú | Cobros, pagos y movimientos del extracto |
| Cómo se cuadra | Contando el dinero físicamente | [Conciliando](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) contra el extracto bancario |
| Vínculo con bancos | Ninguno | Asociada a un [banco](/docs/rtg/pymes/tesoreria/bancos) |
Si cobras con **datáfono**, el dinero de tarjeta no entra en la caja: va a la cuenta bancaria. La caja solo recoge el efectivo.
***
## Cuándo usar una caja [#cuándo-usar-una-caja]
Crea una caja siempre que el negocio mueva efectivo y quieras saber cuánto hay y de dónde viene. Casos típicos:
* **Mostrador o sucursal**: cada punto donde recibes cobros en efectivo tiene su propia caja, para controlar el dinero por ubicación.
* **Caja fuerte o fondo fijo**: el efectivo que guardas fuera del cajón del día a día.
* **Cobros y pagos directos en metálico**: cuando cobras una venta o pagas un gasto sin pasar por el banco.
Si todo tu dinero pasa por el banco y nunca tocas efectivo, no necesitas cajas: te basta con [cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias).
***
## Crear una caja [#crear-una-caja]
### Abre tus depósitos de tesorería [#abre-tus-depósitos-de-tesorería]
Ve a **Pymes → Tesorería**. Ahí conviven tus cajas y tus cuentas bancarias como depósitos monetarios.
### Añade una caja nueva [#añade-una-caja-nueva]
Crea un depósito de tipo **caja** y dale un nombre claro que identifique el punto de efectivo (por ejemplo, el mostrador o la sucursal). Así sabrás a qué dinero se refiere cada movimiento y cada cierre.
### Empieza a registrar movimientos [#empieza-a-registrar-movimientos]
Con la caja creada, ya puedes anotar las entradas y salidas de efectivo y, al final del día, hacer su cierre.
***
## Cómo funcionan los movimientos [#cómo-funcionan-los-movimientos]
Una caja se mueve con dos tipos de apuntes:
* **Ingresos de efectivo**: dinero que entra (un cobro en metálico, una aportación de fondo).
* **Salidas de efectivo**: dinero que sale (un pago directo, una retirada, un gasto pagado en mano).
Cada apunte suma o resta sobre el saldo de la caja, igual que en una cuenta bancaria los cobros y pagos modifican el saldo. La diferencia es que en la caja **el saldo real lo confirmas contando el dinero físico**, no comparándolo con un extracto.
Apunta los movimientos de efectivo en el momento. Una caja al día es la única forma de que el cierre cuadre sin sorpresas.
***
## Relación con el TPV [#relación-con-el-tpv]
Si usas el **TPV**, no tienes que registrar a mano cada cobro en metálico: los **cierres de caja del TPV alimentan la caja de tesorería**. Cuando cierras la caja en el punto de venta, ese cierre vuelca al depósito de efectivo el resultado del periodo (entradas, salidas y el importe contado).
En el cierre eliges precisamente el **depósito** que quieres cerrar (tu caja de efectivo o tu cuenta bancaria) y el sistema calcula saldo inicial y final, total de entradas y salidas, el importe que confirmas contando físicamente y la **diferencia** entre lo esperado y lo real. Esa diferencia es la que te avisa de un descuadre.
Si en el mismo punto cobras en efectivo y con tarjeta, haz **dos cierres separados**: uno para la caja (el efectivo) y otro para la cuenta bancaria (la tarjeta). Cada depósito se cuadra por su lado.
→ [Cómo hacer un cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
***
## Relación con la conciliación [#relación-con-la-conciliación]
La **conciliación es cosa de las cuentas bancarias**, no de las cajas. Una cuenta bancaria se cuadra contra el extracto que importas, y Dinaup te sugiere a qué cobro o pago corresponde cada movimiento. Una caja, en cambio, no tiene extracto: se cuadra **contando el efectivo** en el cierre.
Por eso, cuando piensas en cuadrar tu tesorería, separa los dos mundos: el banco se [concilia](/docs/rtg/pymes/tesoreria/conciliacion-bancaria), la caja se cierra.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La caja guarda efectivo (billetes y monedas) y se cuadra contando el dinero. La cuenta bancaria refleja el saldo en una entidad y se cuadra conciliando el extracto. Ambas son depósitos monetarios de tu tesorería.
No. Los cierres de caja del TPV alimentan automáticamente la caja de tesorería con las entradas, salidas y el importe contado del periodo.
No. La conciliación trabaja con extractos bancarios. Una caja se cuadra haciendo su cierre y confirmando el efectivo contado físicamente.
Las que necesites. Lo habitual es una caja por cada punto donde manejas efectivo (mostrador, sucursal, caja fuerte), para controlar el dinero por ubicación.
***
→ [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias)
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
→ [Bancos](/docs/rtg/pymes/tesoreria/bancos)
→ [Cierre de caja (TPV)](/docs/rtg/tpv/procesos/cierre-de-caja)
# Cómo importar Extractos Bancarios (/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios)
### Prepara tu Extracto Bancario [#prepara-tu-extracto-bancario]
1. Entra en la web de tu banco y descarga el extracto.
2. Dinaup admite `.xls` `.xlsx` y `.CSV`.
3. Asegúrate de que la primera fila del archivo sea la cabecera. Evita encabezados, títulos o logotipos.
### Accede a tu Cuenta Bancaria en Dinaup [#accede-a-tu-cuenta-bancaria-en-dinaup]
1. Entra en `play.dinaup.com` > `Pymes`
2. En el menú lateral izquierdo, haz clic en **Cuentas Banco**.
3. Elige la cuenta bancaria y haz clic para entrar.
### Sube el Archivo del Extracto [#sube-el-archivo-del-extracto]
1. Pulsa el botón **Importar**.
2. Selecciona el archivo `.CSV` , `.XLS`, `.XLSX` desde tu ordenador.
3. Asegúrate de que las columnas se detecten correctamente.
### Haz clic en Importar [#haz-clic-en-importar]
El extracto se procesa y queda reflejado en la cuenta bancaria en Dinaup.
**¿Importas años de histórico pero solo quieres conciliar lo reciente?** Pon una fecha en el campo **Conciliar desde** (pestaña Registro de la cuenta): los apuntes anteriores se conservan en el historial, pero quedan fuera de la conciliación. Más en [Cuentas bancarias](/docs/rtg/pymes/tesoreria/cuentas-bancarias#conciliar-desde-la-fecha-de-corte-de-la-conciliacion).
# Conciliación avanzada (/docs/rtg/pymes/tesoreria/conciliacion-avanzada)
La **conciliación avanzada** es la versión con IA de la [conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria). Coge los movimientos del extracto de una cuenta y clasifica cada uno (tipo y entidad). Después agrupa los que se parecen y los empareja con la factura, cobro o pago que les corresponde. Tú revisas y confirmas. Por cada propuesta el sistema te explica por qué la ha hecho y te deja deshacerla.
***
## En qué se diferencia de la conciliación básica [#en-qué-se-diferencia-de-la-conciliación-básica]
Las dos cuadran la misma cuenta bancaria contra tus operaciones reales. La diferencia es cuánto trabajo hace el sistema y cuánta visibilidad te da de ese trabajo.
| | [Conciliación básica](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) | Conciliación avanzada |
| -------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Emparejado automático | Sugerencias por importe y fecha | Sugerencias + clasificación + agrupación con IA |
| Clasificar los sin asignar | A mano o con [reglas](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios) | La IA propone tipo y entidad, y hasta nuevas reglas |
| Visión de conjunto | Movimiento a movimiento | Panel con totales por estado y por entidad |
| Trazabilidad | — | Registro de todo lo que hizo el sistema, con motivo y deshacer |
La conciliación avanzada no sustituye a las [reglas de movimientos](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios): las aprovecha. Cuanto mejores sean tus reglas y más historial tenga la cuenta, menos te tocará tocar a ti.
***
## Cómo se abre [#cómo-se-abre]
Entra en la ficha de la [cuenta bancaria](/docs/rtg/pymes/tesoreria/cuentas-bancarias) que quieras cuadrar y abre la herramienta de **conciliar**. Trabaja siempre sobre una cuenta concreta y sobre sus movimientos pendientes de conciliar.
Nada más abrirla, el sistema ya ha hecho una primera pasada automática antes de que toques nada (ver más abajo).
***
## El panel de estado [#el-panel-de-estado]
En la parte superior verás cuatro indicadores que resumen en qué punto está la cuenta:
* **Listos**: movimientos que ya tienen una pareja encontrada y solo esperan tu confirmación.
* **Sin operación**: movimientos con entidad asignada pero sin factura, cobro o pago que les case todavía.
* **Sin clasificar**: movimientos de los que aún no se sabe a qué cliente o proveedor pertenecen.
* **Confirmados**: los que ya has dado por buenos.
A medida que confirmas y clasificas, estos números se mueven. El objetivo es vaciar los tres primeros.
***
## Lo que el sistema hace solo (y cómo deshacerlo) [#lo-que-el-sistema-hace-solo-y-cómo-deshacerlo]
Al abrir la herramienta, antes de pedirte nada, el sistema intenta cuadrar lo evidente:
* Si el **número de factura aparece en el concepto** del movimiento y el **importe coincide** (con la factura emitida antes del cobro/pago y dentro de un margen de pocos días), lo clasifica solo.
* Aplica las **reglas** que tengas activas para esa cuenta.
Todo esto queda registrado en un panel desplegable, **"Qué hizo el sistema automáticamente"**. Por cada movimiento te dice:
* **Qué fuente** lo decidió: una regla, la coincidencia de nº de factura + importe, o la IA.
* **El motivo concreto** (por ejemplo, el patrón de la regla, o el número de factura y los días de diferencia).
* **Qué tipo y entidad** le asignó.
Ves exactamente qué se ha hecho automáticamente y por qué. Si algo no te cuadra, el botón **Deshacer** revierte de golpe toda esa tanda de asignaciones automáticas y los movimientos vuelven a su estado anterior.
***
## Sin clasificar: agrupar con IA [#sin-clasificar-agrupar-con-ia]
Esta es la pestaña donde la IA aporta más. Son los movimientos de los que no se sabe quién es el cliente o proveedor.
Pulsa **Agrupar con IA** y el sistema:
1. Lee los conceptos de los movimientos pendientes.
2. Los **agrupa por categoría** (por ejemplo, software, impuestos, nóminas, comisiones bancarias).
3. **Sugiere tipo y entidad** para cada uno, dejándolos ya rellenos en sus desplegables.
4. Cuando detecta un patrón repetido, te propone **crear una regla** para que esos movimientos se clasifiquen solos la próxima vez.
Tú revisas grupo a grupo. Puedes ajustar cualquier tipo o entidad antes de guardar, y luego aplicar con **Aplicar todo** o confirmar un grupo cada vez. Nada se guarda hasta que tú lo aplicas.
Las **reglas sugeridas** que aparecen al pie de los grupos no se crean solas: cada una tiene un botón **Crear** que abre el formulario de la regla ya prerrellenado, para que la revises antes de guardarla. Más sobre esto en [Reglas de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios).
***
## Sin operación: asociar con IA [#sin-operación-asociar-con-ia]
Aquí están los movimientos que ya tienen entidad pero les falta la factura, cobro o pago que los justifique. Se muestran **agrupados por entidad**, con sus movimientos a un lado y las operaciones disponibles de esa entidad al otro.
Pulsa **Asociar con IA** (general, o por grupo de entidad) y el sistema busca qué operación encaja con cada movimiento, comparando importes en valor absoluto y buscando el número de factura dentro del concepto. Sus propuestas aparecen marcadas para que las revises.
Al seleccionar operaciones para un movimiento verás en directo:
* Cuánto suman las operaciones elegidas frente al importe del movimiento, en porcentaje.
* Si el cuadre es **exacto** o queda una **diferencia**.
* Un aviso de **fuera de rango** si la fecha de la operación se aleja demasiado de la del movimiento.
Un mismo movimiento puede saldar **varias facturas** a la vez: vas añadiendo operaciones hasta cuadrar el importe y pulsas **Conciliar**.
Esto es justo lo que ocurre con las **liquidaciones de pasarelas y marketplaces** (Stripe, Amazon…): un único ingreso que paga muchas ventas. Si su [tipo de movimiento](/docs/rtg/pymes/tesoreria/tipos-de-movimiento) lleva marcada la casilla **Liquidación de varias operaciones**, queda identificado como una liquidación que agrupa varias operaciones; aquí lo asocias contra esas varias operaciones como de costumbre.
Si no aparece ninguna operación que valga, desde aquí puedes **buscarla** en ventas, compras, cobros o pagos, o **crear** directamente la venta o el gasto que falta. También tienes la opción de **Investigar** la entidad para entender de dónde viene el descuadre cruzando sus movimientos con sus ventas y compras.
***
## Confirmar: las parejas listas [#confirmar-las-parejas-listas]
Las **parejas encontradas automáticamente** (comparando entidad, importe y fecha) se agrupan por entidad esperando tu visto bueno. A la izquierda el movimiento bancario, a la derecha la factura, cobro o pago que coincide.
Cada pareja muestra los **días de diferencia** entre las dos fechas y, si el importe no es idéntico, la **diferencia** exacta. Revisa que el emparejamiento sea correcto y confirma de uno en uno, por grupo o **todos a la vez**.
Confirmar **vincula los dos registros de forma permanente**. Revisa las parejas antes de darle a confirmar todos: es una conciliación real, no un borrador.
***
## Residuos: las diferencias pequeñas [#residuos-las-diferencias-pequeñas]
Cuando un movimiento casa con una operación pero queda una **diferencia pequeña**, ese sobrante aparece como residuo. Suelen ser **comisiones bancarias, redondeos o diferencias de cambio**. No requieren acción inmediata; están ahí para que tengas visibilidad de por qué un cuadre no fue exacto al céntimo.
***
## Acciones rápidas sobre un movimiento [#acciones-rápidas-sobre-un-movimiento]
Con el botón derecho sobre cualquier movimiento se abre un menú para resolverlo al vuelo:
* **Puntear**: marcarlo como conciliado sin vincularlo a ninguna factura. Útil para ajustes o remanentes que ya cuadraste por otro lado.
* **Crear regla con IA**: extrae una palabra clave del concepto y abre una regla nueva con ella.
* **Crear gasto** o **Crear ingreso** a partir del movimiento.
* **Asignar un tipo** habitual de un toque (comisión bancaria, transferencia interna, nómina, IVA, etc.).
También puedes **seleccionar un trozo del concepto** con el ratón: aparece un atajo para **crear una regla** con ese texto exacto.
**Puntear no toca tus facturas.** Si el movimiento tenía una factura asociada, esa factura seguirá apareciendo como pendiente y podría emparejarse por error con un movimiento futuro. Úsalo solo cuando sepas que ya está cuadrado por otro lado. Por eso pide confirmación antes de hacerlo.
***
## Conocimiento: enseñar a la IA [#conocimiento-enseñar-a-la-ia]
La conciliación avanzada mejora cuanto más sabe de tu cuenta. En la pestaña de **conocimiento** tienes dos palancas:
* **Reforzar aprendizaje**: el sistema repasa el historial de movimientos ya clasificados de la cuenta y extrae los patrones que identifican a cada entidad (cómo aparece su nombre, sus referencias de factura, los textos que añade el banco). Ese resumen es el que usa la IA para acertar mejor con los movimientos nuevos.
* **Indicaciones personales**: un texto libre donde le das instrucciones que se aplican en cada análisis. Por ejemplo, decirle cómo tratar un cobro recurrente concreto o qué considerar siempre una transferencia interna.
Cuanto mejor sea este contexto, más movimientos clasificará bien sola y menos tendrás que corregir.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La avanzada añade IA encima de la conciliación de siempre: clasifica los movimientos sin asignar (tipo y entidad), los agrupa por categoría, propone reglas nuevas y empareja con las operaciones automáticamente. Además te muestra todo lo que hizo el sistema, con su motivo, y te deja deshacerlo.
La primera pasada automática al abrir (nº de factura + importe exacto, y tus reglas) sí se aplica, pero queda registrada y la puedes deshacer entera con un botón. Las sugerencias de la IA al agrupar o asociar no se guardan hasta que tú las aplicas o confirmas.
Sí. El panel "Qué hizo el sistema automáticamente" lista cada asignación con su motivo y trae un botón para revertir toda la tanda. Los movimientos vuelven a su estado anterior.
No. Igual que la conciliación básica, trabaja con extractos de cuentas bancarias. Una [caja](/docs/rtg/pymes/tesoreria/cajas) se cuadra contando el efectivo en su cierre, no conciliando.
No es obligatorio, pero ayuda. Las reglas resuelven lo repetitivo gratis y la IA se centra en lo nuevo. De hecho, la herramienta te propone reglas a partir de los patrones que detecta.
***
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
→ [Reglas de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios)
→ [Auditoría de reglas y clasificación de movimientos](/docs/rtg/pymes/tesoreria/auditoria-de-reglas-y-clasificacion-de-movimientos)
# Conciliación Bancaria (/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
## Qué hace la conciliación [#qué-hace-la-conciliación]
La herramienta de conciliación relaciona los movimientos bancarios con operaciones reales como cobros, pagos, ingresos extraordinarios o devoluciones.
Dinaup analiza tus extractos y busca coincidencias con ventas, compras u otras operaciones. Cuando encuentra una coincidencia, te la muestra como **sugerencia de conciliación**, para que la confirmes, la rechaces o la gestiones a mano.
## Conciliar una cuenta [#conciliar-una-cuenta]
### Crea tus reglas [#crea-tus-reglas]
Antes de importar el extracto, crea reglas básicas para automatizar la clasificación. Así, Dinaup podrá reconocer conceptos como proveedores, bancos o servicios recurrentes.
[Ver artículo: Reglas de clasificación automática](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios)
### Importa el extracto bancario [#importa-el-extracto-bancario]
Desde la ficha de cada cuenta bancaria, sube tu archivo (CSV o Excel). El sistema detecta automáticamente importes, fechas y conceptos, y aplica las reglas configuradas en el momento.
[Ver artículo: Importar extractos bancarios](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios)
### Revisa las reglas con la herramienta de clasificación [#revisa-las-reglas-con-la-herramienta-de-clasificación]
Consulta qué movimientos se han clasificado y cuáles no. Puedes ajustar, mejorar o crear nuevas reglas directamente desde la herramienta.
[Ver artículo: Clasificación de movimientos](/docs/rtg/pymes/tesoreria/auditoria-de-reglas-y-clasificacion-de-movimientos)
### Abre la ventana de conciliación y acepta sugerencias [#abre-la-ventana-de-conciliación-y-acepta-sugerencias]
Recorre los distintos tipos de movimientos (cobros, pagos, ingresos, etc.) y acepta, corrige o rechaza las sugerencias que el sistema te ofrece.
## Opciones de la vista de conciliación [#opciones-de-la-vista-de-conciliación]
En cada sugerencia, verás dos columnas:
* A la izquierda: el **movimiento bancario**
* A la derecha: la **operación registrada** (compra, venta, etc.)
### 1. Cambia la entidad asociada haciendo clic en el icono [#1-cambia-la-entidad-asociada-haciendo-clic-en-el-icono]
Haz clic en el icono de la izquierda (en el movimiento bancario, columna izquierda) para **editar o cambiar la entidad asociada** fácilmente. (Cliente, Proveedor... )
***
### 2. Agrega comentarios explicativos [#2-agrega-comentarios-explicativos]
Puedes dejar comentarios internos en cualquier movimiento bancario para aclaraciones, validaciones o seguimiento en equipo. O para informar a tu asesor.
### 3. Opciones de reglas rápidas [#3-opciones-de-reglas-rápidas]
Desde el menú `⋮` de cada movimiento puedes:
1. **Aplicar mismo concepto**\
Asigna la misma entidad y tipo a todos los movimientos con el mismo texto.
2. **Crear regla general**\
Aplica a todas las cuentas bancarias.
3. **Crear regla para esta cuenta**\
Solo se aplica a la cuenta donde estás trabajando.
### 4. Conciliación manual (avanzada) [#4-conciliación-manual-avanzada]
Si no hay sugerencias o decides rechazar una, puedes pulsar **“Manual”** o **“No”** para abrir la ventana de **conciliación avanzada**.
Desde ahí puedes:
* Etiquetar el movimiento con categoría y entidad.
* Buscar manualmente operaciones existentes.
* Crear una nueva operación (venta, compra, etc.)
* Usar **punteo rápido** si ya sabes que encaja.
# Cuentas bancarias (/docs/rtg/pymes/tesoreria/cuentas-bancarias)
Una **cuenta bancaria** es un depósito monetario que refleja en Dinaup el saldo que tienes en una entidad bancaria. Es el hermano de la [caja de efectivo](/docs/rtg/pymes/tesoreria/cajas): ambos son depósitos de tu tesorería, pero la cuenta guarda saldo en el banco en lugar de billetes y monedas. Cada cuenta está asociada a un [banco](/docs/rtg/pymes/tesoreria/bancos) y se identifica por su **IBAN**.
Sus movimientos son los **cobros**, los **pagos** y los apuntes que llegan en el **extracto** que importas. Y se cuadra de una forma muy concreta: importando ese extracto y [conciliándolo](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) contra tus operaciones.
***
## Cuenta bancaria frente a caja [#cuenta-bancaria-frente-a-caja]
Las dos viven juntas bajo el mismo concepto de depósito, y en cualquier proceso de tesorería eliges una u otra como origen o destino del dinero. La diferencia está en dónde vive ese dinero y en cómo se cuadra.
| | [Cuenta bancaria](/docs/rtg/pymes/tesoreria/cuentas-bancarias) | [Caja (efectivo)](/docs/rtg/pymes/tesoreria/cajas) |
| ------------------ | --------------------------------------------------------------------------------------- | -------------------------------------------------- |
| Qué contiene | Saldo en una entidad bancaria | Dinero físico (billetes y monedas) |
| Identificador | IBAN | Nombre del punto de efectivo |
| Movimientos | Cobros, pagos y apuntes del extracto | Ingresos y salidas que registras tú |
| Cómo se cuadra | Importando el extracto y [conciliando](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) | Contando el dinero en el cierre |
| Vínculo con bancos | Asociada a un [banco](/docs/rtg/pymes/tesoreria/bancos) | Ninguno |
Si cobras con **datáfono**, ese dinero de tarjeta no entra en la caja: llega a la cuenta bancaria. La caja solo recoge el efectivo en mano.
***
## Cuándo usar una cuenta bancaria [#cuándo-usar-una-cuenta-bancaria]
Crea una cuenta bancaria por cada IBAN con el que opera tu negocio. Casos típicos:
* **Cuenta operativa**: por donde entran los cobros de clientes y salen los pagos a proveedores.
* **Cuenta de ahorro o reserva**: el saldo que mantienes apartado.
* **Cobros con tarjeta**: el dinero del datáfono o de la pasarela de cobro acaba en una cuenta bancaria, nunca en la caja.
Si manejas también efectivo, ese dinero va aparte en una [caja](/docs/rtg/pymes/tesoreria/cajas). Banco y efectivo se cuadran por separado.
***
## Crear una cuenta bancaria [#crear-una-cuenta-bancaria]
### Abre tus depósitos de tesorería [#abre-tus-depósitos-de-tesorería]
Ve a **Pymes → Cuentas Bancarias**. Ahí conviven tus cuentas y tus cajas como depósitos monetarios de la tesorería.
### Asóciala a un banco [#asóciala-a-un-banco]
Crea la cuenta y vincúlala a un [banco](/docs/rtg/pymes/tesoreria/bancos). Si la entidad todavía no está dada de alta, créala primero en **Bancos**: ese vínculo es lo que permite identificar y clasificar bien las comisiones y los movimientos de cada entidad.
### Identifícala por su IBAN [#identifícala-por-su-iban]
Dale un nombre claro e introduce el **IBAN** de la cuenta. Así sabrás a qué cuenta se refiere cada cobro, cada pago y cada importación de extracto.
### Importa su extracto [#importa-su-extracto]
Con la cuenta creada, ya puedes [importar su extracto](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios) y empezar a [conciliar](/docs/rtg/pymes/tesoreria/conciliacion-bancaria). A partir de ahí, los cobros y pagos cuadran contra los apuntes reales del banco.
***
## Cómo funcionan los movimientos [#cómo-funcionan-los-movimientos]
Una cuenta bancaria se mueve con dos orígenes que conviven sobre el mismo saldo:
* **Cobros y pagos** que registras desde tus facturas de venta y de compra.
* **Apuntes del extracto** que importas desde el banco: cada línea del extracto es un movimiento con su fecha, importe y concepto.
El objetivo es que esos dos mundos casen: que cada cobro y cada pago tuyo se corresponda con un apunte real del banco. Esa correspondencia es la **conciliación**, y es lo que te confirma que el saldo de Dinaup coincide con el del banco.
A diferencia de una caja, el saldo de una cuenta bancaria **no lo confirmas contando dinero**: lo confirmas comparándolo con el extracto. Por eso importar el extracto al día es clave para que todo cuadre.
***
## Importar el extracto [#importar-el-extracto]
El extracto es la lista de movimientos reales tal y como los ve el banco. Importarlo es lo que da a Dinaup la "verdad" contra la que cuadrar tus cobros y pagos.
Desde la ficha de la cuenta, pulsas **Importar** y subes el archivo que descargaste de tu banca electrónica. Dinaup detecta automáticamente importes, fechas y conceptos de cada línea.
Asegúrate de que la **primera fila del archivo sea la cabecera**: sin títulos, logotipos ni filas en blanco por encima. Así las columnas se detectan bien.
→ [Cómo importar extractos bancarios](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios)
***
## Cuadrar la cuenta: conciliación [#cuadrar-la-cuenta-conciliación]
Una vez importado el extracto, toca **conciliar**: relacionar cada apunte del banco con la operación real que le corresponde (un cobro de cliente, un pago a proveedor, un gasto, una transferencia).
Dinaup analiza los movimientos y te muestra **sugerencias** para que solo tengas que confirmarlas, corregirlas o rechazarlas. Cuando un apunte se concilia con una factura, esa factura queda marcada como cobrada o pagada.
Esto es exclusivo de las cuentas bancarias: una [caja](/docs/rtg/pymes/tesoreria/cajas) no tiene extracto, así que se cuadra contando el efectivo en su cierre, no conciliando.
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
***
## Conciliar desde: la fecha de corte de la conciliación [#conciliar-desde-la-fecha-de-corte-de-la-conciliación]
En la pestaña **Registro** de la cuenta tienes el campo **Conciliar desde**. Fija la fecha a partir de la cual Dinaup concilia esa cuenta: todo lo anterior queda fuera de la conciliación.
El caso típico: importas el extracto de los últimos años para tener el histórico completo, pero solo quieres cuadrar desde el último trimestre. Pones esa fecha en **Conciliar desde** y trabajas solo con lo reciente, sin arrastrar años de apuntes pendientes.
Con la fecha puesta, quedan fuera de la conciliación:
* Los **apuntes del extracto** con fecha anterior: no aparecen como pendientes de clasificar ni de conciliar, y no cuentan en los indicadores de la pantalla de conciliación.
* Las **operaciones antiguas** (ventas, compras, cobros y pagos anteriores a la fecha): no se ofrecen como pareja de los apuntes nuevos.
**Conciliar desde no borra nada.** Los apuntes anteriores siguen en el extracto y en el historial de la cuenta; simplemente dejan de contar como trabajo pendiente de conciliación. Si borras la fecha, vuelven a entrar todos.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La cuenta bancaria refleja el saldo en una entidad y se identifica por su IBAN; se cuadra importando el extracto y conciliando. La caja guarda efectivo físico y se cuadra contando el dinero. Ambas son depósitos monetarios de tu tesorería.
El vínculo con el banco permite identificar la entidad y clasificar correctamente sus movimientos y comisiones. Si la entidad no existe todavía, créala antes en la sección Bancos.
Sí. El extracto es la referencia real del banco contra la que se concilian tus cobros y pagos. Sin él, el saldo de Dinaup no puede compararse con el del banco.
No. El dinero de datáfono o pasarela llega a la cuenta bancaria. La caja solo recoge el efectivo en mano.
Las que necesites. Lo habitual es una cuenta por cada IBAN con el que opera tu negocio (operativa, ahorro, cobros con tarjeta).
No. Pon en el campo **Conciliar desde** (pestaña Registro de la cuenta) la fecha desde la que quieres cuadrar. Los apuntes anteriores se conservan en el historial, pero dejan de aparecer como pendientes de conciliación.
***
→ [Cajas](/docs/rtg/pymes/tesoreria/cajas)
→ [Bancos](/docs/rtg/pymes/tesoreria/bancos)
→ [Cómo importar extractos bancarios](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios)
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
# Tesorería (/docs/rtg/pymes/tesoreria)
La tesorería de Dinaup está conectada con tus cobros, pagos, ventas, compras y movimientos bancarios. Desde aquí importas extractos, concilias movimientos y controlas el efectivo en caja.
### 1. Importar extractos bancarios [#1-importar-extractos-bancarios]
Para [importar extractos bancarios](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios) necesitas un archivo en formato compatible (CSV o Excel) y seleccionar la cuenta correspondiente.
***
### 2. Conciliación bancaria [#2-conciliación-bancaria]
Desde la [herramienta de conciliación](/docs/rtg/pymes/tesoreria/conciliacion-bancaria) revisas los movimientos bancarios y los asignas a cobros, pagos o ingresos extraordinarios. Si hay coincidencias, el sistema sugiere la asignación. Si no, usas la **Conciliación Avanzada** para asignar a mano o crear reglas.
***
### 3. Reglas de clasificación automática [#3-reglas-de-clasificación-automática]
Puedes [crear reglas](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios) que identifiquen movimientos por nombre o patrones. Por ejemplo, todos los movimientos que incluyan `Microsoft` se pueden asociar automáticamente a esa empresa y al tipo `Factura recibida`.
Estas reglas no se aplican retroactivamente, por seguridad. Pero puedes revisarlas y supervisarlas con el **Asistente de Reglas**, disponible en cada cuenta bancaria.
***
### 4. Supervisión por cuenta bancaria [#4-supervisión-por-cuenta-bancaria]
Al abrir una cuenta concreta, verás un cuadro llamado **Clasificación automática**. Desde ahí puedes:
* Ver qué reglas se han aplicado.
* Crear nuevas reglas específicas para esa cuenta.
* Usar herramientas de auditoría para asegurar la integridad de los datos.
***
### 5. Gestión de cajas y cierres [#5-gestión-de-cajas-y-cierres]
Además de bancos, también puedes registrar entradas y salidas de efectivo en caja. El sistema permite hacer [cierres de caja](/docs/rtg/tpv/procesos/cierre-de-caja), validar cuadrantes y controlar los movimientos reales frente a los registrados.
# Reglas de Movimientos Bancarios (/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios)
Una regla detecta si el concepto del movimiento contiene una palabra o patrón específico (por ejemplo: `CHATGPT`, `MICROSOFT`...) y asigna automáticamente:
* El `Tipo de movimiento` (`factura recibida`, `factura emitida`, `pago impuestos`...)
* La `entidad correspondiente` (proveedor, cliente, empresa).
* Y opcionalmente, puede aplicarse solo a una **cuenta bancaria concreta**.
### ¿Y luego qué? [#y-luego-qué]
Una vez creada, la regla se aplicará automáticamente en el momento de importar el extracto.\
Esto garantiza que los movimientos se clasifiquen correctamente desde el primer momento.
Si cobras por una pasarela o marketplace que te ingresa en bloque (Stripe, Amazon…), crea una regla que detecte su concepto y le asigne un [tipo de movimiento](/docs/rtg/pymes/tesoreria/tipos-de-movimiento) marcado como **Liquidación de varias operaciones**. Así esos ingresos quedan clasificados solos como liquidaciones en cuanto importas el extracto.
**¿Ya tienes reglas creadas y quieres revisarlas?**\
Consulta [Auditoría de reglas y clasificación de movimientos](/docs/rtg/pymes/tesoreria/auditoria-de-reglas-y-clasificacion-de-movimientos)
# Tipos de movimiento bancario (/docs/rtg/pymes/tesoreria/tipos-de-movimiento)
Un **tipo de movimiento bancario** describe de qué es un apunte del extracto: una venta, una compra, una comisión, una nómina, un impuesto… Es la pieza que decide **contra qué se puede conciliar** ese movimiento y **con qué entidad**.
Los gestionas desde cada cuenta bancaria, junto a las [reglas de clasificación](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios).
## Pestaña General [#pestaña-general]
| Campo | Para qué sirve |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| **Nombre** *(obligatorio)* | El nombre del tipo, tal y como aparece al clasificar (p. ej. "Comisión bancaria", "Cobro de cliente", "Nómina"). |
| **Imagen** y **Color** | Identifican el tipo en las listas de movimientos. |
| **Tipo de Compra / Gasto** y **Categoría Compra / Gasto** | Si los rellenas, el movimiento muestra un botón para **dar de alta el gasto** desde el propio apunte, ya clasificado con ese tipo y categoría. |
| **Tipo de Venta / Ingreso** y **Categoría Venta** | Igual para los **ingresos**: un botón que crea la venta o el ingreso desde el movimiento, con su tipo y categoría puestos. |
| **Entidad** | Entidad que se asigna por defecto a los movimientos de este tipo. |
| **Contrapartida** | Cuenta de contrapartida asociada al tipo. |
| **Descripción** | Texto libre para anotar cuándo usar este tipo. |
Muchos apuntes del banco no tienen factura detrás: el pago del IVA, el impuesto de sociedades, la Seguridad Social, las comisiones bancarias… Quizá no los has registrado como gasto en el sistema. Si su tipo de movimiento lleva **Tipo y Categoría de gasto** (o de ingreso), Dinaup te pone un botón para crearlo **desde el propio movimiento**. Así ese gasto entra en tu **informe de ingresos y gastos** sin que tengas que ir a registrarlo aparte.
## Contra qué busca para conciliar [#contra-qué-busca-para-conciliar]
Las casillas **Buscar en…** definen entre qué operaciones se rastrea la coincidencia de un movimiento de este tipo:
* **Buscar en Compras / Gastos**
* **Buscar en Ventas / Ingresos**
* **Buscar en Presupuestos**
* **Buscar en Pedidos**
Activar **Buscar en Presupuestos** o **Buscar en Pedidos** no concilia contra el presupuesto ni el pedido en sí: los usa para llegar a **la venta que salió de ellos**. Si ese presupuesto o pedido aún no tiene venta, el movimiento no se podrá conciliar.
Hay ingresos que no se corresponden con una sola venta, sino con muchas a la vez: es el caso típico de las pasarelas de pago y los marketplaces (Stripe, Amazon…), que cobran a tus clientes y te liquidan en bloque. Para esos, marca **Liquidación de varias operaciones** en el tipo, de modo que quede señalado que ese único ingreso agrupa varias operaciones. Lo habitual es combinarlo con una [regla de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios) que asigne este tipo automáticamente a esos ingresos por su concepto. Para asociarlas, ver [Conciliación avanzada](/docs/rtg/pymes/tesoreria/conciliacion-avanzada).
## Pestaña Avanzado [#pestaña-avanzado]
| Campo | Para qué sirve |
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **No requiere conciliar** | Marca los movimientos de este tipo como cuadrados sin necesidad de enlazarlos a una operación (p. ej. comisiones o ajustes que das por buenos). |
| **Filtrar a Clientes / Proveedores / Bancos / Empleados** | Limita las entidades que se pueden asignar a este tipo al grupo marcado, para que no se mezclen al clasificar. |
## La pestaña Registro [#la-pestaña-registro]
Es la pestaña de auditoría estándar del sistema: muestra quién creó o modificó el tipo y cuándo. No tiene campos que configures tú.
***
→ [Reglas de movimientos bancarios](/docs/rtg/pymes/tesoreria/reglas-de-movimientos-bancarios)
→ [Conciliación bancaria](/docs/rtg/pymes/tesoreria/conciliacion-bancaria)
→ [Configura la conciliación bancaria (guía)](/docs/guias/configurar-conciliacion-bancaria)
# Almacenes (/docs/rtg/pymes/inventario-y-precios/almacenes)
Un **almacén** representa cualquier lugar desde el que tu empresa gestiona stock o realiza operaciones: un depósito, una tienda física o una sucursal. Cada almacén guarda su propio inventario, así que sabes en todo momento cuántas unidades hay y dónde están.
Puedes tener tantos almacenes como necesites. Trabajan en paralelo: el mismo producto puede estar repartido entre varios y cada uno lleva su cuenta por separado.
***
## Para qué sirven [#para-qué-sirven]
* **Controlas el inventario por ubicación.** Sabes qué hay en cada depósito, tienda o sucursal sin mezclarlo todo en un único montón.
* **Asignas cada venta a su punto de origen.** Cada operación queda ligada al almacén que la generó, así comparas resultados entre tiendas.
* **Asocias un almacén a un empleado** para que todas las ventas que haga queden vinculadas a ese punto.
* **Decides qué almacén ve cada usuario y cada TPV**, para que cada persona trabaje solo con el stock que le corresponde.
Si solo tienes un punto de venta y no necesitas separar el stock por ubicación, te basta con un único almacén. Los almacenes adicionales sirven cuando manejas varias tiendas, depósitos o sucursales.
***
## Crear y gestionar almacenes [#crear-y-gestionar-almacenes]
Los almacenes se dan de alta desde la configuración de Pymes. Una vez creados, aparecen en la pantalla de **Almacenes**, donde gestionas el inventario de todos a la vez.
### Crea el almacén [#crea-el-almacén]
Ve a la configuración de Pymes y añade un almacén nuevo. Dale un nombre claro que identifique el punto (por ejemplo, el de la tienda, el depósito central o cada sucursal). Ese nombre es el que verás en cada movimiento y en cada listado de stock.
### Decide si vende en el TPV [#decide-si-vende-en-el-tpv]
Marca el almacén como **disponible en TPV** si quieres que su stock pueda venderse desde el punto de venta. Si lo dejas como uso interno, el almacén sigue controlando inventario pero no aparece como origen de venta en el TPV.
### Empieza a mover stock [#empieza-a-mover-stock]
Con el almacén creado, ya puedes registrar entradas y salidas, crear [lotes](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos) y repartir tus productos entre las distintas ubicaciones.
***
## La pantalla de almacenes [#la-pantalla-de-almacenes]
Desde la pantalla de **Almacenes** controlas el inventario de toda la empresa. Arriba ves un resumen con los indicadores clave:
* **Almacenes:** cuántos tienes dados de alta.
* **Referencias con stock:** cuántos productos distintos tienen existencias.
* **Unidades disponibles:** el total de unidades repartidas entre todos los almacenes.
* **Referencias agotadas:** productos sin stock en ningún almacén, candidatos a reponer.
* **Valor de inventario:** lo que vale tu stock a precio de venta.
Debajo, eliges un almacén de la lista y ves **su stock**: qué productos tiene, en qué [lotes](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos), cuántas unidades hay disponibles y cuántas físicas. Cada almacén indica con una etiqueta si su stock está **disponible en el TPV** o es **solo interno**.
**Disponible** es lo que puedes vender ahora mismo; **físico** es lo que hay realmente en la estantería. Pueden no coincidir cuando hay unidades reservadas o comprometidas.
***
## Stock por almacén [#stock-por-almacén]
Como el mismo producto puede estar en varios almacenes a la vez, Dinaup te ofrece una **matriz de stock por almacén**: una tabla con tus productos en las filas y tus almacenes en las columnas. En cada celda ves cuántas unidades hay de ese producto en ese almacén, y al final de cada fila, el total sumando todos.
Es la forma rápida de responder a "¿dónde está este producto y cuántos quedan en cada sitio?" sin entrar uno a uno.
El stock de cada almacén se mueve registrando entradas y salidas: cuando compras, das de alta inventario; cuando vendes, lo descuentas; y cuando regularizas, ajustas el recuento a la realidad. Cada uno de estos movimientos suma o resta sobre el almacén concreto que elijas.
→ [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
***
## Acceso a almacenes: quién ve qué [#acceso-a-almacenes-quién-ve-qué]
No todo el mundo tiene por qué ver todos los almacenes. El acceso controla **qué almacenes puede usar cada empleado desde el TPV**, para que cada persona venda solo del stock que le corresponde.
Para que un empleado pueda vender de un almacén en el punto de venta se tienen que cumplir **dos condiciones**:
1. **El almacén está marcado como disponible en TPV.** Si es de uso solo interno, no aparece como origen de venta para nadie.
2. **El empleado tiene acceso a ese almacén.** El acceso se gobierna a través de los grupos de almacén asignados al empleado.
Si falta cualquiera de las dos, ese almacén le aparecerá como **sin acceso** y no podrá vender de él.
En la propia pantalla de almacenes, al seleccionar uno ves quién **trabaja ahí** y quién tiene **acceso configurado**, para detectar huecos de configuración.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Los que necesites. Lo habitual es un almacén por cada punto donde guardas o mueves stock (tienda, depósito, sucursal), para controlar el inventario por ubicación.
Sí. El mismo producto puede repartirse entre varios almacenes y cada uno lleva su propio recuento. La matriz de stock por almacén te muestra cuántas unidades hay en cada sitio y el total.
Porque no está marcado como disponible en TPV, o porque el empleado no tiene acceso a él. Hacen falta las dos cosas: que el almacén venda en TPV y que el empleado tenga asignado el grupo de almacén correspondiente.
El disponible es lo que puedes vender en este momento; el físico es lo que hay realmente en el almacén. Pueden diferir cuando hay unidades reservadas o comprometidas en operaciones pendientes.
Asociando ese almacén al empleado. A partir de entonces, todas las ventas que haga quedan vinculadas a ese punto, sin que tenga que elegirlo cada vez.
***
→ [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
→ [Gestión de pedidos](/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos)
# Inventario y Precios (/docs/rtg/pymes/inventario-y-precios)
Productos, almacenes y catálogos de precios.
* [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
* [Lotes de Productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
* [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
* [Gestión de Pedidos](/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos)
# Lotes de Productos (/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
Un **lote** es una partida concreta de un producto: un conjunto de unidades que comparten origen, fecha y características. Trabajar con lotes te da **trazabilidad**: sabes de qué partida salió cada unidad, cuándo caduca y en qué estado está. Es la base para controlar caducidades, devoluciones a proveedor y stock real por almacén.
***
## Para qué sirven los lotes [#para-qué-sirven-los-lotes]
Activa lotes cuando necesites algo más que un número total de existencias:
* **Caducidad.** Productos con fecha límite (alimentación, farmacia, cosmética) en los que no da igual qué unidad vendes primero.
* **Trazabilidad de origen.** Saber de qué partida o proveedor viene cada unidad para gestionar una incidencia o una devolución.
* **Control por estado.** Separar lo que está disponible para vender de lo retenido, reservado o agotado.
* **Stock fino por almacén.** Ver cuántas unidades de cada partida hay en cada [almacén](/docs/rtg/pymes/inventario-y-precios/almacenes), no solo un total global.
Si tu producto no necesita ese detalle, no tienes que usar lotes: te basta con el [producto](/docs/rtg/pymes/inventario-y-precios/productos) y su stock.
***
## Anatomía de un lote [#anatomía-de-un-lote]
Al crear o abrir un lote trabajas sobre tres bloques de información.
### Datos del lote [#datos-del-lote]
* **Producto.** El producto al que pertenece la partida. Es obligatorio. Una vez creado el lote, el producto queda fijo y no se cambia.
* **Código / referencia.** El identificador de la partida (por ejemplo, el número de lote impreso por el fabricante o tu propia referencia interna). Es lo que te permite rastrear la partida.
* **Tipo.** Clasifica el lote según tus categorías. Si no eliges nada, parte de un tipo estándar.
* **Estado.** En qué situación está el lote (disponible, retenido, etc.). El estado es la base del resumen de **lotes por estado**.
### Fechas del lote [#fechas-del-lote]
Todas son opcionales, pero son las que dan valor a la trazabilidad:
* **Inicio de disponibilidad.** Desde cuándo el lote se considera operativo.
* **Caducidad.** Fecha límite de uso o venta de la partida.
* **Límite de devolución a proveedor.** Hasta cuándo puedes devolver esas unidades al proveedor.
### Venta y observaciones [#venta-y-observaciones]
* **Aviso al vender.** Un texto que sirve como recordatorio asociado a la venta de ese lote (por ejemplo, una condición o una advertencia sobre la partida).
* **Observaciones.** Notas internas libres sobre el lote.
***
## Crear un lote [#crear-un-lote]
Los lotes se gestionan desde **Pymes → Almacenes**, donde tienes el botón **Crear lote**.
### Abre el formulario de lote [#abre-el-formulario-de-lote]
En **Almacenes**, pulsa **Crear lote**. Se abre la ventana de creación.
### Elige el producto y dale una referencia [#elige-el-producto-y-dale-una-referencia]
Selecciona el **producto** de la partida (obligatorio) y escribe su **código / referencia** para poder rastrearla. Ajusta el **tipo** y el **estado** si lo necesitas.
### Añade las fechas que apliquen [#añade-las-fechas-que-apliquen]
Rellena **caducidad**, **inicio de disponibilidad** o **límite de devolución a proveedor** según el producto. Déjalas vacías si no aplican.
### Guarda el lote [#guarda-el-lote]
Pulsa **Crear lote**. La partida queda registrada y lista para recibir existencias.
**Un lote recién creado nace sin stock.** Crear el lote solo da de alta la partida con sus datos; las unidades llegan después, cuando registras una entrada sobre ese lote.
***
## Cómo se asigna stock a un lote [#cómo-se-asigna-stock-a-un-lote]
El lote es el "qué" (la partida); el stock es el "cuántas unidades y dónde". Las dos cosas se conectan al **mover inventario**: una entrada mete unidades en el lote dentro de un almacén, y una salida las descuenta.
Desde un lote ya creado tienes dos acciones directas:
* **Agregar entrada.** Suma unidades a la partida (una compra, una producción, un ajuste de alta).
* **Agregar salida.** Descuenta unidades (una venta, una merma, una baja).
Cada lote muestra dos cifras de existencias:
| Cifra | Qué representa |
| -------------- | --------------------------------------------------------------------------------------- |
| **Disponible** | Unidades libres para vender o usar. |
| **Físico** | Unidades realmente presentes en el almacén (incluye lo disponible más lo comprometido). |
Al **vender** un producto que trabajas por lotes, la salida se imputa a un lote concreto, de modo que el descuento de stock queda trazado hasta la partida de la que salió la unidad.
***
## Resumen de lotes por estado [#resumen-de-lotes-por-estado]
En la pantalla de **Almacenes** tienes una vista de conjunto, **Lotes por estado**, que reparte tu inventario según el estado de cada lote. Te muestra, para los lotes con existencias físicas:
* **Unidades por estado.** Cuántas unidades hay en cada estado.
* **Número de lotes por estado.** Cuántas partidas distintas hay en cada estado.
Es la forma rápida de ver cuánto de tu stock está realmente disponible frente a lo retenido o en otra situación. En el listado de stock de cada almacén, cada lote aparece además marcado como **En stock** o **Agotado** según le queden unidades disponibles.
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Los lotes son para productos en los que importa la trazabilidad: caducidad, origen de la partida o control por estado. Si no necesitas ese detalle, gestiona el producto con su stock normal.
Porque crear el lote solo da de alta la partida con sus datos. El stock entra después: registra una entrada sobre ese lote para darle existencias.
El físico son las unidades que están realmente en el almacén. El disponible son las que quedan libres para vender o usar. Si parte del stock está comprometido, el disponible será menor que el físico.
No. El producto queda fijado al crear el lote. Sí puedes editar después su referencia, tipo, estado, fechas y observaciones.
***
→ [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
# Movimientos de inventario (/docs/rtg/pymes/inventario-y-precios/movimientos-de-inventario)
Un **movimiento de inventario** es un ajuste manual de stock: añades o retiras unidades de un producto sin que medie una compra o una venta. Sirve para que tu inventario refleje la realidad cuando esta cambia por motivos internos, no por una operación comercial. Por ejemplo: cuentas el almacén y no cuadra, una caja se rompe, consumes material para uso propio o fabricas algo.
Cada movimiento es de uno de dos sentidos:
* **Entrada**: suma stock. Inventario inicial, ajuste de un recuento al alza, producción interna.
* **Salida**: resta stock. Merma, rotura, consumo interno, pérdida.
***
## Para qué sirve [#para-qué-sirve]
Las compras y las ventas ya mueven el stock por su cuenta. Los movimientos de inventario cubren todo lo demás, lo que pasa "puertas adentro":
* **Inventario inicial**: cargas el stock de partida de un producto cuando empiezas a controlarlo en Dinaup.
* **Ajuste de recuento**: cuentas físicamente el almacén y el número no coincide con lo que dice el sistema. Registras la diferencia (entrada si sobra, salida si falta) para cuadrarlo.
* **Merma, rotura o pérdida**: producto que se estropea, se rompe o desaparece. Una salida lo descuenta del stock.
* **Consumo interno**: material que gastas para tu propia operación y no vendes. Una salida lo refleja.
* **Producción interna**: fabricas o montas unidades que pasan a estar disponibles. Una entrada las añade.
Si la pérdida o el sobrante viene de una operación comercial (una venta, una devolución, una compra), no uses un movimiento manual: registra esa operación. Los movimientos de inventario son para ajustes que **no** tienen una compra o venta detrás.
***
## Qué indica cada movimiento [#qué-indica-cada-movimiento]
Al registrar un movimiento defines:
| Dato | Para qué |
| ------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **Producto** | El artículo cuyo stock ajustas. Obligatorio. |
| **Almacén** | La ubicación donde entra o sale el stock. Obligatorio. |
| **Hueco** | La posición concreta dentro del almacén, si trabajas con huecos. Opcional. |
| **Lote** | El lote afectado, si el producto se controla por lotes. Puedes elegir uno existente o crearlo en el momento. Opcional. |
| **Cantidad** | Las unidades que añades (entrada) o retiras (salida). |
En una **salida**, Dinaup te muestra el **stock disponible en el almacén** para ese producto y no te deja retirar más unidades de las que hay. Así evitas dejar el stock en negativo por error.
→ Más sobre estos conceptos: [Productos](/docs/rtg/pymes/inventario-y-precios/productos), [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes), [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos).
***
## Registrar un movimiento [#registrar-un-movimiento]
### Abre el formulario de movimiento [#abre-el-formulario-de-movimiento]
Desde **Pymes → Inventario**, inicia un nuevo movimiento de inventario. Se abre la ventana **Movimiento de inventario**.
### Elige el sentido: entrada o salida [#elige-el-sentido-entrada-o-salida]
Arriba tienes el selector **Entrada / Salida**. Elige **Entrada** para sumar stock o **Salida** para restarlo. El formulario te recuerda los motivos típicos de cada sentido.
### Indica el tipo de movimiento [#indica-el-tipo-de-movimiento]
En **Tipo de movimiento**, elige el motivo concreto (el ajuste, la merma, la producción, etc.). Es la etiqueta con la que después identificarás por qué se hizo ese cambio de stock.
### Selecciona producto, almacén y, si aplica, lote [#selecciona-producto-almacén-y-si-aplica-lote]
Elige el **producto** y el **almacén**. Si trabajas con huecos o lotes, indica también el **hueco** y el **lote**; si el lote aún no existe, créalo desde el mismo formulario.
### Pon la cantidad y registra [#pon-la-cantidad-y-registra]
Escribe las **unidades a añadir** o **a retirar**. En una salida, no podrás superar el stock disponible que se muestra. Pulsa **Registrar movimiento** y el stock queda actualizado.
Registra los movimientos en el momento en que ocurren. Un inventario al día es la única forma de que un recuento futuro cuadre sin sorpresas.
***
## Traspasos entre almacenes [#traspasos-entre-almacenes]
Mover stock de un almacén a otro es la combinación de dos movimientos: una **salida** en el almacén de origen y una **entrada** en el de destino, por las mismas unidades y del mismo producto.
### Salida en el almacén de origen [#salida-en-el-almacén-de-origen]
Registra una **salida** indicando el almacén desde el que sale el stock y las unidades que mueves.
### Entrada en el almacén de destino [#entrada-en-el-almacén-de-destino]
Registra una **entrada** del mismo producto y las mismas unidades, esta vez en el almacén de destino.
El resultado: el stock total no cambia, pero ahora está repartido según la ubicación real. Si el producto se controla por lotes, usa el **mismo lote** en la salida y en la entrada para no perder su trazabilidad al cambiarlo de sitio.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Usa un movimiento manual cuando el stock cambia por un motivo interno (recuento, merma, rotura, consumo propio, producción) que no tiene una compra ni una venta detrás. Si hay una operación comercial, regístrala como tal y el stock se moverá solo.
Registra la diferencia: una entrada si has contado más unidades de las que decía el sistema, una salida si has contado menos. Así el inventario queda cuadrado con la realidad.
No. En una salida, Dinaup te muestra el stock disponible en ese almacén y no te permite retirar más unidades de las que hay.
Haz dos movimientos: una salida en el almacén de origen y una entrada en el de destino, por las mismas unidades. Si el producto va por lotes, usa el mismo lote en ambos.
***
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
→ [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
→ [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
# Precios (/docs/rtg/pymes/inventario-y-precios/precios)
**Precios** reúne tus catálogos de tarifas: a cuánto vendes y a cuánto compras cada producto. Un mismo producto puede tener varios precios según el catálogo (por cliente, por proveedor o por campaña), y Dinaup aplica el que corresponde en cada factura, pedido o presupuesto.
Llegas desde **Pymes → Inventario → Precios**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La pantalla separa las tarifas en dos pestañas:
| Pestaña | Qué contiene |
| ---------- | --------------------------------------------------------------------- |
| **Venta** | Los catálogos de precios de venta: a cuánto vendes cada producto. |
| **Compra** | Los catálogos de precios de compra: a cuánto te cuesta cada producto. |
La pestaña **Compra** solo aparece con la licencia de Pymes y permiso sobre los catálogos de compra. Cada pestaña es un listado con su propia barra de herramientas para crear y editar tarifas.
Las tarifas de venta y de compra son **independientes**. El precio al que vendes no tiene por qué guardar relación con el precio al que compras: cada uno vive en su catálogo.
***
## Cómo se aplican los precios [#cómo-se-aplican-los-precios]
Un catálogo es una lista de precios que asocias a un producto. Al crear una venta o una compra, Dinaup toma el precio del catálogo que aplique al contexto de esa operación (el cliente, el proveedor o la campaña). Así defines el producto una vez y mantienes varias tarifas sin duplicar la ficha.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Sí. Para eso están los catálogos: cada uno guarda su propia tarifa del producto. Dinaup aplica el catálogo que corresponde según el cliente, el proveedor o la campaña de la operación.
Porque requiere la licencia de Pymes y permiso sobre los catálogos de compra. Sin eso solo trabajas con las tarifas de venta.
***
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
# Productos (/docs/rtg/pymes/inventario-y-precios/productos)
En Dinaup, un **producto** representa cualquier artículo o servicio que tu empresa **compra, vende o controla en inventario**.
### Para qué crear productos [#para-qué-crear-productos]
Crear productos sirve para:
* **Mejorar las estadísticas** de ventas y compras.
* **Automatizar categorías** contables y fiscales.
* **Asociar reglas contables** que se aplican solas.
* **Usar catálogos de compra y venta** y fijar precios en el TPV.
* **Gestionar el inventario** por lotes.
***
### Gestión de Inventario [#gestión-de-inventario]
En Dinaup, el inventario se gestiona mediante **lotes**: cada lote controla el stock, la caducidad y la trazabilidad de una partida de producto.
#### Qué permite un lote [#qué-permite-un-lote]
* Controlar la caducidad y el coste real del producto.
* Distribuir el stock en **diferentes almacenes**.
* Asignar productos a **ubicaciones específicas** dentro del almacén.
#### Formas de gestionar los lotes [#formas-de-gestionar-los-lotes]
Existen dos maneras principales de gestionar los lotes según el nivel de control que necesites:
**1. Lote predeterminado**
En la ficha del producto puedes definir un lote por defecto. Esto significa que Dinaup utilizará **un único lote** para todo el stock de ese producto.
Útil si solo necesitas saber **cuánto stock tienes** sin preocuparte por almacenes, ubicaciones o caducidades.
**2. Lotes individuales**
Si trabajas con varios almacenes o necesitas más control, puedes crear **lotes por separado**.
Opciones:
* **Un lote por almacén**: Simplifica la gestión básica por ubicación.
* **Un lote por bulto o unidad**: Te permite registrar **caducidades, huecos concretos o referencias internas**.
Puedes crear y asignar lotes directamente al registrar una entrada de inventario.
# Reposición (/docs/rtg/pymes/inventario-y-precios/reposicion)
**Reposición** te dice qué comprar y cuánto, sin que tengas que revisar producto por producto. Dinaup vigila el stock de cada almacén y, cuando un producto cae por debajo de su **stock mínimo**, te lo marca como pendiente de reponer. También te calcula las unidades a pedir para volver a dejarlo a punto.
***
## Cuándo aparece un producto aquí [#cuándo-aparece-un-producto-aquí]
Un producto entra en la lista de reposición cuando se cumplen las dos condiciones a la vez **en un almacén concreto**:
* Ese producto tiene definido un **stock mínimo** mayor que cero.
* Sus **unidades disponibles** en ese almacén están **por debajo** de ese mínimo.
Si nunca fijas un stock mínimo, el producto no se vigila y no aparecerá aquí. El mínimo es el umbral que le dice a Dinaup "por debajo de esto, avísame".
El mínimo y el máximo se definen en la ficha del producto. Configúralos en aquellos artículos que no puedes permitirte que se agoten. → [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
***
## Cuántas unidades te propone pedir [#cuántas-unidades-te-propone-pedir]
Para cada producto bajo mínimo, Dinaup calcula las unidades a pedir para llevarlo de su nivel **disponible** actual hasta su **objetivo**:
* Si el producto tiene un **stock máximo** definido, el objetivo es ese máximo. Repones para llenar.
* Si no hay máximo, el objetivo es el **mínimo**. Repones lo justo para volver a estar en el umbral.
La cantidad a pedir es la diferencia entre ese objetivo y lo que tienes disponible. Por eso conviene definir el máximo: marca hasta dónde quieres reponer, no solo a partir de dónde.
***
## Los indicadores de cabecera [#los-indicadores-de-cabecera]
Nada más abrir **Reposición** ves tres indicadores que resumen la situación de todo tu inventario:
| Indicador | Qué te dice |
| ----------------------- | ------------------------------------------------------------------------------------------------- |
| **Productos a reponer** | Cuántos artículos distintos están por debajo de mínimo en algún almacén. |
| **Unidades a comprar** | El total de unidades a pedir, sumando todos los productos y almacenes, para dejarlo todo a punto. |
| **Almacenes afectados** | En cuántos almacenes hay al menos un producto bajo mínimo. |
Debajo, dos vistas te dejan mirar la reposición desde dos ángulos: por producto o por almacén.
Si todo tu inventario está por encima de mínimos, Dinaup te lo dice con un **"Todo en orden"**: ningún producto está por debajo de su stock mínimo en ningún almacén. No hay nada que pedir.
***
## Vista global: qué comprar de cada producto [#vista-global-qué-comprar-de-cada-producto]
La pestaña **Vista global** responde a la pregunta del comprador: *"¿cuántas unidades pido de cada producto en total?"*
Es la **necesidad global de compra**: las unidades totales a comprar de cada producto para abastecer todos los almacenes que estén bajo mínimo. Cada fila te muestra:
* El **producto**.
* Las **unidades a comprar** en total (sumando todos los almacenes que lo necesitan).
* En cuántos **almacenes** hace falta.
Esta vista es la que usas para **lanzar el pedido al proveedor**: pides el total de cada artículo de una sola vez, sin trocearlo por ubicación.
### Ver el reparto por almacén [#ver-el-reparto-por-almacén]
Para saber cuántas de esas unidades van a cada sitio, **expande la fila** del producto: verás el **reparto por almacén**, con las unidades que corresponden a cada almacén bajo mínimo. Útil cuando el pedido llega a un punto central y luego tienes que distribuirlo.
***
## Por almacén: qué falta en cada ubicación [#por-almacén-qué-falta-en-cada-ubicación]
La pestaña **Por almacén** le da la vuelta a la información y responde a *"¿qué le falta a esta tienda o depósito?"*.
Verás una tarjeta por cada almacén con productos bajo mínimo, y dentro una tabla con el detalle de cada artículo:
| Columna | Qué muestra |
| -------------- | ---------------------------------------------------------- |
| **Producto** | El artículo que está bajo mínimo en ese almacén. |
| **Disponible** | Las unidades que hay ahora mismo en ese almacén. |
| **Mínimo** | El umbral por debajo del cual hay que reponer. |
| **Máximo** | El nivel hasta el que conviene reponer (si está definido). |
| **Pedir** | Las unidades a pedir para ese almacén concreto. |
Esta vista es la que usas cuando gestionas las compras **almacén por almacén**, o cuando quieres revisar la salud de stock de una tienda o sucursal en particular.
→ [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
***
## Cómo planificar tus compras con Reposición [#cómo-planificar-tus-compras-con-reposición]
### Define mínimos y máximos en tus productos [#define-mínimos-y-máximos-en-tus-productos]
Reposición solo vigila lo que le dices que vigile. En la ficha de cada producto que no puedas dejar agotar, fija su **stock mínimo** y, si quieres controlar hasta dónde reponer, su **stock máximo**.
### Abre Reposición y mira los indicadores [#abre-reposición-y-mira-los-indicadores]
Entra en la herramienta. Los tres indicadores de arriba te dan la foto: cuántos productos, cuántas unidades y cuántos almacenes necesitan atención.
### Decide el ángulo: por producto o por almacén [#decide-el-ángulo-por-producto-o-por-almacén]
Usa la **Vista global** si vas a lanzar un pedido único al proveedor. Usa **Por almacén** si gestionas las compras o las reposiciones ubicación por ubicación.
### Prepara el pedido con las unidades propuestas [#prepara-el-pedido-con-las-unidades-propuestas]
Apóyate en la columna de unidades a comprar (o a pedir) para preparar tu pedido de compra. Dinaup ya ha hecho el cálculo de cuánto falta hasta el objetivo de cada artículo.
### Repón y vuelve a comprobar [#repón-y-vuelve-a-comprobar]
Cuando entren las compras y se actualice el stock, recarga la herramienta. Los productos que ya hayan superado su mínimo desaparecen de la lista.
Reposición es una herramienta de **decisión, no de ejecución**: te dice qué y cuánto comprar. El pedido de compra y la entrada de stock los registras tú en tu flujo de compras habitual.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Porque no tiene un stock mínimo definido (o es cero). Reposición solo vigila los productos con un umbral mínimo configurado en su ficha. Si quieres que un artículo se controle, fíjale un mínimo.
Toma el objetivo del producto y le resta lo que tienes disponible. Si el producto tiene stock máximo, el objetivo es ese máximo (repones para llenar). Si no, el objetivo es el mínimo (repones lo justo para volver al umbral).
La Vista global suma las necesidades de cada producto en todos los almacenes: ideal para lanzar un pedido único al proveedor. Por almacén desglosa qué le falta a cada ubicación: ideal para reponer tienda por tienda. Es la misma información vista desde dos ángulos.
No. Reposición te dice qué comprar y cuánto, pero el pedido lo preparas tú. Es la herramienta de planificación que te ahorra revisar el inventario producto a producto.
***
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
→ [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
# Stock por almacén (/docs/rtg/pymes/inventario-y-precios/stock-por-almacen)
El **stock por almacén** es la vista que cruza tus productos con tus almacenes y te dice cuántas unidades hay de cada referencia en cada ubicación. No introduces este número a mano: Dinaup lo **calcula sumando los movimientos** (compras, ventas, ajustes de inventario) que han pasado por cada [lote](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos).
Es el panel al que vas cuando necesitas responder "¿cuánto me queda de esto y dónde está?" sin abrir producto por producto.
***
## De dónde sale el número [#de-dónde-sale-el-número]
Tú nunca tecleas el stock. Cada movimiento de inventario suma o resta unidades sobre un lote, y cada lote vive en un almacén concreto. La cifra que ves es el resultado de esa cuenta:
* Una **compra** o una **entrada** suma unidades al lote (y por tanto al almacén).
* Una **venta** o una **salida** las resta.
* Un **ajuste de inventario** corrige el lote para que cuadre con la realidad física.
Si un número no te cuadra, no lo edites en esta pantalla: corrige el [movimiento](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos) o haz un ajuste de inventario. El stock siempre es el reflejo de los movimientos, nunca un dato suelto.
***
## Disponible frente a físico [#disponible-frente-a-físico]
A lo largo de la vista verás dos cantidades para el mismo producto, y conviene no confundirlas:
| | Disponible | Físico (inventario) |
| -------------- | --------------------------------------- | --------------------------------------------- |
| Qué es | Lo que puedes vender o usar ahora mismo | Lo que hay realmente en la estantería |
| Para qué sirve | Saber qué puedes comprometer | Saber qué tienes que contar al hacer recuento |
En la mayoría de casos coinciden. Se separan cuando hay unidades reservadas o pendientes que están físicamente en el almacén pero ya no puedes disponer de ellas.
***
## Los indicadores de cabecera [#los-indicadores-de-cabecera]
En la parte superior de la pantalla tienes una fila de tarjetas con el resumen de todo tu inventario. Te sirven para tomar el pulso antes de entrar al detalle:
* **Almacenes**: cuántas ubicaciones tienes dadas de alta.
* **Referencias con stock**: cuántos productos distintos tienen al menos una unidad disponible.
* **Unidades disponibles**: el total de unidades que puedes vender o usar, sumando todos los almacenes.
* **Referencias agotadas**: productos que se han quedado **sin stock disponible en ningún almacén**. Son tus candidatos a reponer. Esta tarjeta se pone en color de aviso cuando hay alguno.
* **Valor de inventario**: cuánto vale lo que tienes en stock, calculado como **precio de venta × unidades disponibles**.
**Referencias agotadas** es el indicador que mirar a diario: te dice qué productos necesitas comprar antes de quedarte vendiendo lo que no tienes.
***
## La matriz de stock por almacén [#la-matriz-de-stock-por-almacén]
El corazón de la vista es una tabla con los **productos en las filas** y los **almacenes en las columnas**. Cada celda es la cantidad disponible de ese producto en ese almacén, y la última columna es el **total** sumando todas las ubicaciones.
Cómo se lee:
* Una celda con número **en negrita** significa que ahí hay stock.
* Una celda en **gris** significa cero: ese producto no está en ese almacén.
* La columna **Producto** queda fija al desplazarte en horizontal, para no perder de vista qué referencia estás mirando cuando tienes muchos almacenes.
Puedes **ordenar** la tabla pulsando en una columna: por ejemplo, ordenar por la columna de un almacén para ver qué tiene más existencias, o por **Total** para detectar tus productos con más y con menos stock.
La matriz solo muestra productos que tienen stock en algún almacén. Si una referencia no aparece, es que no hay ningún lote con existencias para ella.
***
## Ver el detalle de un almacén [#ver-el-detalle-de-un-almacén]
Además de la matriz general, puedes **seleccionar un almacén concreto** para verlo en detalle. Al elegirlo, Dinaup te muestra:
* Cuántas **referencias** distintas tiene y cuántas **unidades** disponibles en total.
* Si ese almacén **vende en el TPV** o es solo de uso interno.
* La lista de **lotes con stock** de ese almacén, con su producto, el lote, su estado (en stock o agotado) y las cantidades **disponible** y **física**.
* Quién **trabaja** en ese almacén y quién tiene **acceso** a él.
Es la forma de pasar del "cuánto hay en total" al "qué hay exactamente en esta tienda".
***
## Reparto de lotes por estado [#reparto-de-lotes-por-estado]
La vista incluye también un resumen gráfico del **reparto del inventario por estado de lote**, contando solo los lotes con stock físico. Te ayuda a ver en qué situación está tu mercancía (cuántas unidades y cuántos lotes hay en cada estado) sin tener que repasar la lista lote a lote.
***
## Registrar movimientos desde aquí [#registrar-movimientos-desde-aquí]
Desde la cabecera de la vista puedes lanzar directamente los movimientos que cambian el stock, sin salir a otra pantalla:
* **Inventario**: registra un ajuste para cuadrar las existencias con un recuento físico.
* **Compra**: da entrada a mercancía que recibes.
* **Venta**: registra una salida de unidades.
* **Crear lote**: da de alta una nueva partida de producto.
En cuanto confirmas cualquiera de estos movimientos, los indicadores y la matriz se recalculan solos con el nuevo stock.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Porque el stock no es un dato que se teclee: es el resultado de sumar tus movimientos de inventario. Para cambiarlo, registra una compra, una venta o un ajuste de inventario, y la cifra se actualiza sola.
El stock disponible es lo que puedes vender o usar ahora mismo. El físico (inventario) es lo que hay realmente en la estantería. Normalmente coinciden; se separan cuando hay unidades reservadas o pendientes que siguen en el almacén pero ya no puedes comprometer.
Los productos que se han quedado sin stock disponible en ningún almacén. Son tus candidatos a reponer: si una referencia aparece aquí, te has quedado sin existencias en todas tus ubicaciones.
Multiplicando el precio de venta de cada producto por sus unidades disponibles, y sumando el resultado de todas las referencias.
Porque no tiene stock en ningún almacén. La tabla solo lista referencias con existencias; si no hay ningún lote con unidades para ese producto, no se muestra.
***
→ [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
→ [Lotes de productos](/docs/rtg/pymes/inventario-y-precios/lotes-de-productos)
→ [Productos](/docs/rtg/pymes/inventario-y-precios/productos)
# Cierre de Caja (/docs/rtg/tpv/procesos/cierre-de-caja)
### Accede a Cierres de Caja [#accede-a-cierres-de-caja]
* Navega hacia `play.dinaup.com` > `TPV`
* En el menú lateral izquierdo, entra en `Cierres de Caja`.
### Crea un nuevo cierre [#crea-un-nuevo-cierre]
1. Pulsa el botón verde **`+ NUEVO`**.
2. Se abrirá un formulario donde debes rellenar los siguientes campos obligatorios:
* **Depósito:** selecciona la cuenta o caja que quieres cerrar.
* **Desde y Hasta:** indica el rango de fechas que quieres cerrar. Por defecto, puedes poner desde las 00:00 hasta las 23:59:59 del día actual, si haces el cierre al final de la jornada.
* **Responsable:** la persona que ha estado encargada del dinero durante el periodo.
3. Pulsa el botón azul **RECALCULAR** para que el sistema sume todas las entradas, salidas, cobros y pagos del periodo.
4. Antes de confirmar el cierre, **revisa los datos**. Esto te permite detectar errores como un cero de más o un importe mal registrado. Si ves alguna diferencia, corrige el importe confirmado o ajusta los datos necesarios.
5. Comprueba los siguientes datos, que el sistema calcula solo:
* Saldo inicial y final
* Total entradas y salidas
* Importe confirmado (rellénalo manualmente con el dinero contado físicamente o en el banco)
* Diferencia (el sistema la calcula)
6. Pulsa **GUARDAR** para confirmar el cierre.
Si usas **una caja y una cuenta bancaria** porque cobras con **datáfono**, debes hacer **dos cierres separados**: uno para la caja (efectivo) y otro para la cuenta bancaria (tarjeta).
# Cobrar en el TPV (/docs/rtg/tpv/procesos/cobro)
Cobrar es el último paso de una venta en el TPV: eliges cómo paga el cliente, confirmas el importe y decides qué entregas (ticket o factura simplificada). Dinaup admite **varias formas de pago** y deja que combines más de una en una misma venta.
Cada forma de pago aterriza en un sitio distinto de tu tesorería: el **efectivo entra en la caja**, la **tarjeta va a la cuenta bancaria**. Tenerlo claro es lo que hace que tus cierres cuadren al final del turno.
***
## Formas de pago [#formas-de-pago]
Cuando abres el cobro, eliges la forma de pago de la venta:
| Forma de pago | Cuándo usarla | Dónde aterriza el dinero |
| ---------------- | --------------------------------------- | ------------------------ |
| **Efectivo** | Cobro en metálico en el mostrador | Caja de efectivo |
| **Tarjeta** | Pago con datáfono, presencial | Cuenta bancaria |
| **Link de pago** | Cobro remoto o sin datáfono delante | Cuenta bancaria |
| **Pago mixto** | El cliente paga con dos formas a la vez | Cada parte a su sitio |
También puedes dejar parte de la venta **pendiente de cobro** (cobro parcial), o no cobrar nada todavía y dejarla por cobrar.
El dinero de tarjeta y de link de pago **no entra en la caja**: va a tu cuenta bancaria. La caja solo recoge el efectivo. Por eso, si en el mismo punto cobras de las dos maneras, al cerrar harás un cierre por la caja y otro por la cuenta bancaria.
***
## Cobrar en efectivo [#cobrar-en-efectivo]
El cobro en metálico calcula el cambio por ti, para que no tengas que hacer cuentas de cabeza.
### Elige efectivo [#elige-efectivo]
En la pantalla de cobro, marca **Efectivo** como forma de pago.
### Introduce el importe recibido [#introduce-el-importe-recibido]
Con el teclado táctil, teclea el dinero que te entrega el cliente. Dinaup calcula solo el **cambio** que tienes que devolver.
### Confirma el cobro [#confirma-el-cobro]
Acepta para dar la venta por cobrada. Ese efectivo se suma a la caja del punto de venta.
Si tienes un **cajón portamonedas** conectado, se abre solo al cobrar en efectivo.
***
## Cobrar con tarjeta [#cobrar-con-tarjeta]
El cobro con tarjeta funciona de dos maneras, según tengas o no el datáfono conectado a Dinaup.
### Elige tarjeta [#elige-tarjeta]
Marca **Tarjeta** como forma de pago. Dinaup queda a la espera del datáfono.
### Cobra con el datáfono [#cobra-con-el-datáfono]
* **Datáfono integrado**: Dinaup envía el importe al datáfono y este cobra solo. No tecleas nada en el TPV.
* **Datáfono manual**: operas el datáfono por tu cuenta y, cuando el pago se aprueba, confirmas el cobro en Dinaup.
El importe de tarjeta se anota contra la **cuenta bancaria**, no contra la caja.
***
## Cobrar con link de pago [#cobrar-con-link-de-pago]
Cuando el cliente no está delante o no tienes datáfono, genera un enlace de pago y deja que pague desde su móvil.
### Genera el link [#genera-el-link]
Elige el cobro con **link de pago**. Dinaup crea un enlace seguro para esa venta.
### Envíaselo al cliente [#envíaselo-al-cliente]
Hazle llegar el enlace por el canal que prefieras (por ejemplo, mensajería o correo). El cliente abre el link y paga con tarjeta.
### La venta se marca cobrada al confirmarse el pago [#la-venta-se-marca-cobrada-al-confirmarse-el-pago]
Cuando el pago queda confirmado, la venta pasa a cobrada sola. Ese importe va a tu cuenta bancaria.
***
## Cobro parcial o pendiente [#cobro-parcial-o-pendiente]
No hace falta cobrar el total de golpe. Puedes cobrar una parte ahora y dejar el resto **pendiente**.
* Indica cuánto cobras en este momento (por ejemplo, una entrega).
* El importe restante queda como **por cobrar** asociado al cliente.
Así puedes vender a crédito: cobras lo que el cliente paga hoy y el resto queda registrado para liquidarlo más adelante.
***
## Pago mixto [#pago-mixto]
Un pago mixto combina **varias formas de pago en una misma venta**. Es habitual, por ejemplo, cuando el cliente paga una parte en efectivo y el resto con tarjeta.
* Reparte el total entre las formas de pago que use el cliente (por ejemplo, una parte en efectivo y otra con tarjeta).
* Cada parte aterriza donde corresponde: el efectivo en la caja, la tarjeta en la cuenta bancaria.
Esto mantiene la trazabilidad de cada euro: aunque la venta sea una sola, sabes cuánto entró en metálico y cuánto por banco.
***
## Después de cobrar: ticket o factura [#después-de-cobrar-ticket-o-factura]
Una vez cobrada la venta, decides qué documento entregas.
| Documento | Cuándo | Qué incluye |
| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Ticket** | Venta normal de mostrador | Resumen de la compra con tu logo y datos de pie. Se imprime al cobrar (configurable) y puedes reimprimirlo desde el histórico. |
| **Factura simplificada** | El cliente pide factura | Convierte el ticket en factura con datos fiscales y número correlativo. Puedes enviarla por correo. |
Si el cliente te pide factura después de haberle dado el ticket, no repites la venta: conviertes ese ticket en factura simplificada y queda con su número fiscal.
***
## Del cobro al cierre [#del-cobro-al-cierre]
Todo lo que cobras a lo largo del turno se acumula en tu tesorería: el efectivo en la **caja** y la tarjeta y los links de pago en la **cuenta bancaria**. Al final del turno, el cierre suma esos movimientos y te dice si todo cuadra.
Como el efectivo y la tarjeta aterrizan en depósitos distintos, lo normal es hacer **dos cierres separados**: uno por la caja (el efectivo, que cuadras contando el dinero) y otro por la cuenta bancaria (la tarjeta y los links).
→ [Cómo hacer un cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. El efectivo entra en la caja y la tarjeta (igual que los links de pago) va a la cuenta bancaria. Por eso, si cobras de las dos maneras en el mismo punto, haces un cierre para la caja y otro para la cuenta bancaria.
Sí, con el pago mixto. Repartes el total entre las formas que use el cliente (por ejemplo, efectivo y tarjeta) y cada parte aterriza en su depósito.
Sí. Cobras una parte y dejas el resto como pendiente; ese importe queda como "por cobrar" asociado al cliente para liquidarlo después.
Conviertes el ticket en factura simplificada. Dinaup le asigna número fiscal y puedes enviarla por correo, sin repetir la venta.
No. Si tienes datáfono integrado, Dinaup cobra solo. Si no, operas el datáfono aparte y confirmas el cobro en Dinaup. También puedes usar un link de pago.
***
→ [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
# Configuración TPV (/docs/rtg/tpv/procesos/configuracion-tpv)
### Accede a la APP de TPV [#accede-a-la-app-de-tpv]
Inicia sesión en [play.dinaup.com](https://play.dinaup.com/) y navega hacia la **App de TPV**
### Configura un Tipo de Venta [#configura-un-tipo-de-venta]
Es recomendable crear un [tipo de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) específico para el TPV. Esto permite diferenciar claramente las ventas realizadas en caja (normalmente con cobro inmediato) del resto de operaciones comerciales del negocio.
Para crear un [tipo de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) navega hacia \
`Apps` > `Pymes` > `Configuración` > `Ventas / ingresos` > `Tipos de Venta`
1. Crea una Numeración para ventas ordinarias.
2. Crea una Numeración para ventas rectificativas.
3. Asegúrate que los prefijos no se repitan para evitar números repetidos
4. Si el TPV se va a utilizar en un monitor táctil en el **Tipo de venta** activa `TPV Modo Táctil`
5. En el caso de que aplique un límite como Facturas simplificadas, rellena el campo de `Importe máximo`.
### Configura tipo predeterminado de Venta [#configura-tipo-predeterminado-de-venta]
Para darle mejor experiencia de uso, puedes configurar el botón `Iniciar` del TPV para que arranque la venta con el tipo que acabas de crear.
1. Navega hacia `Apps` > `Pymes` > `Configuración` > `Empresa Administradas`
2. Abre tu empresa
3. Navega hacia la pestaña `Compra - Venta`
4. Selecciona el Tipo en `Tipo predeterminado de venta`
### Da de Alta las Cuentas Bancarias [#da-de-alta-las-cuentas-bancarias]
Si se va a permitir cobrar con Tarjeta desde las Cajas, se debe dar de alta la cuenta bancaria hacia donde va el dinero.
* Navega hacia `Apps` > `Pymes` > `Cuentas Bancarias`
* Da de alta la cuenta bancaria.
### Da de Alta las Cajas [#da-de-alta-las-cajas]
Para aceptar cobro en efectivo debes dar de alta las cajas.
* Navega hacia `Apps` > `TPV` > `Cajas`
* Da de alta las cajas.
Debes asociar la cuenta bancaria asociada al datafono el campo `Cuenta bancaria (Pago con tarjeta)`
### Da de Alta las Categorías de Venta [#da-de-alta-las-categorías-de-venta]
Especialmente si el TPV se va a utilizar en modo táctil deberás crear categorías de Venta y asociar una imagen.
1. Navega hacia `Apps` > `Pymes` > `Configuración` > `Ventas / Ingresos` > `Categorías de Venta`.
2. Da de alta las Categorías que vas a utilizar.
3. Asegúrate de que tengan imágenes.
4. Asegúrate de que tengan marcada la opción `Mostrar en TPV Modo Táctil` .
### Da de alta los productos [#da-de-alta-los-productos]
Navega hacia `Apps` > `Pymes` > `Productos` y pulsa sobre `+ Nuevo` para Da de alta los [productos](/docs/rtg/pymes/inventario-y-precios/productos).
1. `Texto principal`: Nombre del producto
2. Medida: Unidades
3. `Evaluar Stock`: En este ejemplo no se evalúa stock porque está pensado para hostelería.
4. En la pestaña `Compra - Venta`: Rellena las categorías de compra y de Venta.
### Configura el Precio de los Productos [#configura-el-precio-de-los-productos]
Para asignar los precios, puedes consultar la [Guía de gestión de precios](/docs/rtg/pymes/inventario-y-precios).
### Oculta Categorías de venta [#oculta-categorías-de-venta]
TPV está pensado para vendedores, no para administrativos. Para evitar errores y hacer más ágil el trabajo diario, puedes ocultar todas las categorías de venta que un comercial no necesite. Ejemplo: `Suplidos` o categorías usadas solo por Administración.
Para ocultar o mostrar una categoría de venta en el TPV: \
Navega a **Pymes > Configuración > Ventas > Categorías**\
Dentro de cada categoría, activa o desactiva la casilla `Disponible en TPV`.
### Oculta Impuestos [#oculta-impuestos]
Muchas empresas prefieren mostrar solo los impuestos habituales en su operativa diaria. Puedes ocultar aquellos que no utilice el equipo comercial.\
Ejemplo:
* `Inversión del sujeto pasivo`, que suele usar Administración.
* `Impuestos de otros países`, si las operaciones intracomunitarias o exportaciones las gestiona otro departamento.
Para ocultar o mostrar un impuesto en el TPV:\
Ve a **Apps > Pymes > Configuración > Impuestos**\
Edita el impuesto y usa la casilla `Disponible en TPV` para decidir si debe mostrarse en el terminal de venta.
### Oculta Retenciones [#oculta-retenciones]
Si las retenciones no se gestionan desde TPV, puedes ocultarlas para simplificar la interfaz de ventas. Esto ayuda a evitar distracciones o errores por parte del equipo comercial.
Para ocultar o mostrar retenciones en el TPV:\
Ve a **Apps > Pymes > Configuración > Retenciones**\
Dentro de cada retención, puedes activar o desactivar la opción `Disponible en TPV` según sea necesario.
### Oculta Tipos de Venta [#oculta-tipos-de-venta]
Desde el TPV, lo habitual es trabajar con operaciones sencillas y rápidas. Puedes mostrar solo los tipos de venta más usados por el equipo comercial, como:
* **Simplificadas**
* **Nacionales**
Así se reduce el riesgo de errores y se facilita el trabajo al vendedor. Tipos más complejos, como **intracomunitarias** o **exportaciones**, suelen gestionarse desde Administración.
Para gestionar los tipos de venta disponibles en el TPV:\
Ve a **Apps > Pymes > Configuración > Tipos de venta**\
Activa solo los que utilice el equipo comercial, como **Nacionales** o **Simplificadas**, y desactiva el resto mediante la opción `Disponible en TPV`.
### Bloqueo de Precios [#bloqueo-de-precios]
En la pestaña `Políticas` se pueden configurar los valores `Sí/No`.
* **Impedir editar Precios**: Si está activo, impide modificar el precio de venta.
* **Impedir editar Descuentos**: Si está activo, impide modificar los campos de descuento.
* **Impedir editar Impuestos**: Si está activo, impide modificar los campos de Impuestos.
# Configurar y Vincular una Caja (/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja)
Para poder cobrar ventas desde la aplicación de TPV es necesario vincular una caja al puesto de trabajo actual.
### Accede a Ready to Go TPV [#accede-a--ready-to-go-tpv]
Inicia sesión en [play.dinaup.com](https://play.dinaup.com) y dirígete a la App **TPV**
### Alta y Configuración de Caja [#alta-y-configuración-de-caja]
* **Da de alta la caja**
* **Vinculación Cuenta Bancaria.**\
Dentro de la ficha de cada caja encontrarás un campo para asignar una **Cuenta Bancaria**.\
Esto es esencial para que, al cobrar con tarjeta, el dinero se registre correctamente en la cuenta vinculada.
### Vincula la Caja desde el Navegador Web [#vincula-la-caja-desde-el-navegador-web]
Para que el sistema detecte la caja, pulsa el botón **Vincular Caja**. Esto asocia la caja con el navegador actual.
# Procesos (/docs/rtg/tpv/procesos)
Guías para configurar y operar el TPV:
* [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv)
* [Configurar y vincular una caja](/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja)
* [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
* [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
# Pedidos y Delivery (/docs/rtg/tpv/procesos/pedidos-y-delivery)
Cuando tu negocio no solo cobra en el mostrador, sino que **prepara pedidos** (una cocina) o los **lleva a domicilio** (reparto), el TPV deja de ser solo una caja: pasa a ser una **cola de trabajo**. Esta página explica cómo seguir cada pedido (y cada cosa que hay que preparar dentro de él) desde que entra hasta que se entrega.
***
## Modos de negocio: hostelería y delivery [#modos-de-negocio-hostelería-y-delivery]
El TPV se adapta al tipo de operación de tu local. Además del modo tienda clásico, tienes dos modos pensados para preparar y repartir:
| Modo | Para qué sirve |
| -------------- | ------------------------------------------------------------------------------------------------------------- |
| **Hostelería** | El pedido se **prepara** antes de entregarse (cocina, barra). Vas viendo en qué punto está cada comanda. |
| **Delivery** | El pedido se **lleva a domicilio** o se recoge. Añades dirección, tarifa de envío y hora estimada de entrega. |
Eliges el modo al configurar el TPV, y **puedes combinarlos**: un local que sirve en mesa y además reparte usa los dos a la vez.
Si solo vendes en el mostrador con cobro inmediato, no necesitas esta vista: te basta con la [venta rápida](/docs/rtg/tpv/procesos/venta-rapida) del TPV. El tablero de pedidos es para cuando hay un tiempo de preparación o un reparto de por medio.
→ [Configuración del TPV](/docs/rtg/tpv/procesos/configuracion-tpv)
***
## El tablero kanban de pedidos [#el-tablero-kanban-de-pedidos]
Todos los pedidos en marcha viven en un **tablero kanban**: columnas que representan en qué punto está cada uno, y tarjetas que avanzan de izquierda a derecha a medida que progresan. Ves en la misma pantalla qué está pendiente, qué se está preparando y qué falta por entregar.
### Las columnas son tus estados, no un menú fijo [#las-columnas-son-tus-estados-no-un-menú-fijo]
Las columnas del tablero son los **estados de pedido** que tú defines. No es una lista cerrada: creas los que necesite tu negocio, les pones nombre e icono y los ordenas de izquierda a derecha. Un local sencillo puede tener tres (*Pendiente → En preparación → Entregado*); una cocina con más pasos puede añadir los suyos.
Si el tablero aparece vacío y te avisa de que **faltan estados**, primero configura los estados de pedido. Sin estados no hay columnas por las que mover las tarjetas.
### Qué muestra cada tarjeta [#qué-muestra-cada-tarjeta]
Cada pedido del tablero es una **tarjeta** con la información que necesitas para atenderlo sin abrirlo:
* El **empleado** que lo atiende (con su foto) y el **canal de venta** por el que entró.
* El **cliente**: su nombre, o el nombre de la empresa si es un cliente de empresa.
* El **número de pedido** y el **importe**.
* El **teléfono**, si lo hay, como enlace directo para llamar con un toque.
* Las **notas** y **anotaciones** del pedido, con cualquier indicación para prepararlo.
Las tarjetas llevan además un **distintivo de color** según lo que llevan esperando. Un pedido reciente se ve neutro; según pasa el tiempo cambia a un aviso suave y, si supera el ciclo de vida que esperas para un pedido, se marca en rojo como **urgente** con los días que lleva. Así los pedidos que llevan demasiado tiempo cantan sin que tengas que buscarlos.
### Indicadores del tablero [#indicadores-del-tablero]
Sobre las columnas tienes un resumen en vivo de lo que estás mirando, que se recalcula con los filtros aplicados:
* **Pedidos**: cuántos hay en el tablero.
* **Total** y **Promedio**: el importe sumado y el ticket medio.
* **Urgentes**: cuántos llevan esperando más de la cuenta (solo aparece si hay alguno).
* **Ticket alto**: cuántos están entre los de mayor importe.
Cada columna muestra también su propio **contador** de tarjetas y el **total** acumulado en ese estado.
### Mover un pedido de estado [#mover-un-pedido-de-estado]
### Localiza la tarjeta [#localiza-la-tarjeta]
Busca el pedido en la columna donde está ahora. Si tienes muchos, usa el buscador o los filtros (más abajo).
### Arrástralo a la siguiente columna [#arrástralo-a-la-siguiente-columna]
Con **arrastrar y soltar**, lleva la tarjeta a la columna del nuevo estado. Al soltarla, el pedido cambia de estado al instante y todo el equipo lo ve.
### Repite hasta cerrarlo [#repite-hasta-cerrarlo]
Avanza el pedido columna a columna hasta el último estado. El ciclo queda cerrado y registrado.
Para ver o editar el detalle de un pedido, **haz clic en su tarjeta**: se abre la ficha completa con sus líneas y datos.
### Encontrar un pedido entre muchos [#encontrar-un-pedido-entre-muchos]
Cuando el tablero se llena, tienes herramientas para centrarte en lo que importa:
* **Buscador**: escribe parte del nombre del cliente, el número de pedido o una anotación y el tablero se queda solo con lo que coincide.
* **Filtro por almacén**: muestra los pedidos de un punto o almacén concreto.
* **Filtro por canal de venta**: aísla los pedidos que entraron por un canal.
* **Filtro por empleado**: ve los pedidos de una persona del equipo. El desplegable muestra a cada empleado con cuántos pedidos lleva y su peso sobre el total.
Si una columna acumula muchas tarjetas, el tablero muestra primero las más relevantes y un botón **Ver más** para desplegar el resto sin saturar la pantalla.
Si el cliente tiene activado el aviso, recibe una **notificación** en cuanto su pedido cambia de estado. Así no tienes que avisarle a mano.
***
## Vista por conceptos: qué hay que preparar [#vista-por-conceptos-qué-hay-que-preparar]
Además de seguir el pedido entero, puedes mirar el trabajo **por concepto**: cada línea de cada pedido (cada plato, cada artículo a preparar) como una tarjeta propia en su tablero kanban. Es la vista de quien está en la estación de preparación y no le importa de qué pedido viene cada cosa, sino **qué tiene en cola y en qué punto está**.
Funciona igual que el tablero de pedidos, pero a nivel de línea:
* Las **columnas** son los **estados de concepto** que defines (por ejemplo, *Por hacer → Cocinando → Emplatado*), independientes de los estados del pedido.
* Cada **tarjeta** muestra el concepto, la **cantidad** (las unidades a preparar) y su **importe**. Si tiene un vencimiento u hora de compromiso, lo verás en la tarjeta.
* **Arrastras** una tarjeta de columna a columna para mover ese concepto de estado, sin tocar el resto del pedido.
* Al **hacer clic** en un concepto se abre el pedido al que pertenece.
Arriba tienes el resumen de la vista: cuántos **conceptos** hay, las **unidades** totales y el **total** en importe. Un **buscador** te deja filtrar por el nombre del concepto.
Las dos vistas son complementarias. La de **pedidos** sirve a quien coordina y entrega (ve el pedido completo y al cliente). La de **conceptos** sirve a quien prepara (ve la cola de cosas a hacer). Cada una tiene sus propios estados, así que un pedido puede ir avanzando mientras sus conceptos se cocinan a su ritmo.
***
## Datos de un pedido a domicilio [#datos-de-un-pedido-a-domicilio]
Cuando el pedido es **delivery**, además de los productos registras los datos de la entrega. Esto le dice al repartidor a dónde va y al cliente cuánto paga y cuándo llega.
* **Dirección de entrega**: a dónde se lleva el pedido. Si el cliente ya tiene una dirección guardada, **se autocompleta**; si no, la introduces (incluye provincia y código postal).
* **Tarifa de envío**: el coste del reparto, **calculado por zona**. Según el destino, se aplica la tarifa correspondiente y se suma al total del pedido.
* **Hora estimada de entrega**: cuándo prevés que llegue, para que todo el equipo tenga claro el compromiso con el cliente.
Guardar la dirección en la ficha del cliente te ahorra reescribirla en cada pedido: la próxima vez se rellena sola.
***
## Cómo gestionar la cola de pedidos [#cómo-gestionar-la-cola-de-pedidos]
El tablero está pensado para trabajar en equipo sin pisarse. Unas pautas para que la cola fluya:
* **Empieza por la izquierda.** Lo que está en el primer estado es lo que aún no ha tocado nadie: dale prioridad para que ningún pedido se quede esperando.
* **Mantén las tarjetas en su columna real.** Mueve el pedido en el momento en que cambia de estado. Un tablero al día es la única forma de que cocina, barra y reparto sepan qué pasa sin preguntar.
* **Vigila los urgentes.** Los pedidos marcados en rojo llevan demasiado tiempo esperando. Que no se acumulen.
* **Cierra el ciclo.** Lleva cada pedido hasta su último estado. Lo que se queda parado en mitad del tablero es una señal de que algo no salió.
El pedido y su cobro son cosas distintas. Preparar y entregar un pedido lo gestionas en el tablero; **el cobro se hace en el TPV** como cualquier otra venta. Asegúrate de [cobrar](/docs/rtg/tpv/procesos/cobro) el pedido además de avanzarlo de estado.
***
## Preguntas frecuentes [#preguntas-frecuentes]
En hostelería el pedido se prepara antes de entregarse (lo sigues por el tablero). En delivery, además, se lleva a domicilio: añades dirección, tarifa de envío por zona y hora estimada de entrega. Puedes usar los dos modos a la vez.
Los que necesites. Las columnas son los estados de pedido que defines tú, con su nombre, icono y orden. No es una lista cerrada: creas los pasos que sigue tu negocio.
La vista de pedidos sigue cada pedido completo (cliente, importe, estado del pedido). La de conceptos sigue cada línea por separado (cada plato o artículo a preparar) con su propia cola de estados. Una sirve para coordinar y entregar; la otra, para preparar en la estación.
Arrastra su tarjeta a la columna del nuevo estado dentro del tablero kanban. El cambio se aplica al instante y lo ve todo el equipo.
Porque ese pedido lleva esperando más tiempo del que esperas para un pedido (su ciclo de vida). El tablero lo marca como urgente, con los días que lleva, para que le des prioridad.
No. El tablero sirve para preparar y entregar; el cobro se realiza en el TPV como cualquier venta. Avanzar un pedido de estado y cobrarlo son acciones separadas.
Por zona: según el destino del pedido se aplica la tarifa correspondiente y se suma al total. La dirección guardada del cliente se autocompleta para no reescribirla cada vez.
***
→ [Venta rápida](/docs/rtg/tpv/procesos/venta-rapida)
→ [Cobro](/docs/rtg/tpv/procesos/cobro)
→ [Configuración del TPV](/docs/rtg/tpv/procesos/configuracion-tpv)
→ [Cierre de caja](/docs/rtg/tpv/procesos/cierre-de-caja)
# Venta rápida (/docs/rtg/tpv/procesos/venta-rapida)
La venta rápida es el corazón del TPV: el flujo para montar un ticket. Buscas productos, ajustas cantidades y descuentos, eliges el cliente y dejas la venta lista para cobrar. Esta página cubre todo el recorrido **hasta justo antes del cobro**; el cobro (efectivo, tarjeta, mixto o link de pago) vive en su propia página.
Antes de vender necesitas el TPV configurado y una caja vinculada al puesto. Si aún no lo has hecho, ve a [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv) y [Configurar y vincular una caja](/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja).
***
## Una venta de principio a fin [#una-venta-de-principio-a-fin]
### Abre una venta nueva [#abre-una-venta-nueva]
Desde el TPV, pulsa **Nueva venta**. Se abre un documento vacío listo para añadir líneas. Es el mismo punto de partida para una venta de mostrador o un pedido.
### Elige el cliente [#elige-el-cliente]
Decide a nombre de quién va la venta:
* **Cliente genérico**: para un ticket sin datos. Es lo habitual en venta de mostrador.
* **Cliente registrado**: búscalo por nombre o NIF y selecciónalo. Trae sus datos fiscales, su tarifa y sus descuentos.
* **Cliente nuevo rápido**: si no existe, créalo en el momento con lo mínimo (nombre y teléfono) sin salir de la venta.
Puedes empezar con genérico y asignar un cliente registrado después, antes de cobrar.
### Añade los productos [#añade-los-productos]
Suma líneas a la venta con el método que más te convenga (los tienes todos detallados en [Buscar y añadir productos](#buscar-y-anadir-productos)): buscador, búsqueda avanzada o lector de código de barras.
### Ajusta cada línea [#ajusta-cada-línea]
Sobre cada línea añadida puedes cambiar la **cantidad**, el **precio** y el **descuento**, o eliminarla. Revisa que las unidades y los importes son correctos antes de seguir.
### Aplica los descuentos [#aplica-los-descuentos]
Además del descuento por línea, puedes meter un **descuento global** a toda la venta. Si el cliente registrado es VIP, su descuento se aplica solo. Tienes el detalle en [Descuentos](#descuentos).
### Revisa y cobra [#revisa-y-cobra]
Comprueba el total. Con la venta montada, pasa al cobro para elegir el método de pago y cerrar el ticket.
→ [Cobro](/docs/rtg/tpv/procesos/cobro)
***
## Buscar y añadir productos [#buscar-y-añadir-productos]
Tienes varias formas de meter productos en la venta. Usa la que sea más rápida según el dispositivo y cómo tengas tu catálogo.
| Método | Cuándo usarlo |
| -------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Buscador por nombre o código** | El día a día. Escribe parte del nombre o el código del producto y selecciónalo del resultado. |
| **Búsqueda avanzada** | Cuando no recuerdas el nombre exacto. Filtra por categoría, stock o tarifa para encontrar el producto. |
| **Lector de código de barras** | Si el dispositivo tiene escáner. Apunta al código y la línea se añade sola. Lo más rápido en tienda. |
Si trabajas en **modo táctil**, organiza tu catálogo por categorías de venta con imagen para vender a golpe de dedo, sin teclear. Se configura en [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv).
***
## Modificar una línea [#modificar-una-línea]
Cada producto añadido es una línea editable. Sobre ella puedes:
* **Cantidad**: cámbiala con el teclado táctil. Multiplica el importe de la línea.
* **Precio**: ajústalo cuando necesites un precio distinto al de catálogo.
* **Descuento de línea**: aplica un porcentaje (%) solo a ese producto.
* **Eliminar**: quita la línea de la venta.
Editar el **precio** y el **descuento** puede estar bloqueado para el equipo de mostrador. Si no puedes tocarlos, es porque la empresa ha activado el bloqueo en las políticas del TPV. Revisa **Bloqueo de precios** en [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv).
***
## Descuentos [#descuentos]
Dinaup aplica los descuentos en tres niveles, y se pueden combinar:
| Tipo | Cómo funciona |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| **Por línea (%)** | Un porcentaje sobre un producto concreto. Útil para rebajar solo un artículo de la venta. |
| **Global** | Un descuento sobre el total de la venta, una vez tienes todas las líneas. |
| **Automático por cliente VIP** | Si el cliente registrado tiene descuento de cliente, se aplica solo al asignarlo a la venta, sin que tengas que introducirlo. |
El descuento de cliente VIP solo entra en juego con un **cliente registrado**. En una venta a cliente genérico no hay descuento automático: lo aplicas tú a mano, por línea o global.
***
## Añadir líneas desde una factura de proveedor (OCR) [#añadir-líneas-desde-una-factura-de-proveedor-ocr]
Cuando llega un pedido del distribuidor con su albarán o factura, no hace falta teclear las líneas una a una. La IA del TPV lee el documento y rellena la operación por ti. Es ideal para registrar entradas de mercancía sin picar 40 referencias a mano.
### Abre una compra y sube el documento [#abre-una-compra-y-sube-el-documento]
Crea una **compra** (factura recibida) y sube la factura del proveedor: una **foto** hecha con la cámara o un **PDF**.
### Elige cuánto debe leer la IA [#elige-cuánto-debe-leer-la-ia]
Indica el nivel de detección:
* **Solo bases**: rellena la cabecera (proveedor, fecha, importes) y dejas las líneas a mano. Más rápido.
* **Documento completo**: intenta también las líneas (producto, cantidad, precio, impuesto). Más lento, pero más exacto.
### Revisa lo extraído [#revisa-lo-extraído]
Dinaup te muestra el documento original junto a los datos que ha extraído, para que compares y corrijas lo que haga falta. La IA propone el **proveedor**, el **número y la fecha** de factura, las **líneas** y las **bases e importe total**. Si el proveedor no existe, te propone darlo de alta.
### Graba [#graba]
Al confirmar, la factura de compra queda registrada, el stock se incrementa y se genera el asiento contable correspondiente.
La IA lee bien PDFs y fotos legibles de facturas estándar de distribuidor. Una factura manuscrita o una foto arrugada bajan la precisión: revisa siempre los datos antes de grabar.
***
## Preguntas frecuentes [#preguntas-frecuentes]
Sí. Arranca con cliente genérico y, antes de cobrar, asígnale un cliente registrado si lo necesitas (por ejemplo, para emitir factura con sus datos fiscales).
La empresa ha activado el bloqueo de precios o de descuentos en las políticas del TPV. Es una restricción de configuración, no un error. Revisa el apartado de bloqueo en Configuración TPV.
Automáticamente, al asignar el cliente registrado a la venta. No tienes que introducirlo a mano. Solo funciona con clientes registrados, no con el cliente genérico.
No. Sube una foto o un PDF de la factura y la IA extrae proveedor, fecha, líneas e importes. Tú revisas y grabas; el stock y la contabilidad se actualizan solos.
***
→ [Cobro](/docs/rtg/tpv/procesos/cobro)
→ [Configuración TPV](/docs/rtg/tpv/procesos/configuracion-tpv)
→ [Configurar y vincular una caja](/docs/rtg/tpv/procesos/configurar-y-vincular-una-caja)
# Importador de datos (/docs/rtg/pymes/configuracion/importador)
El **importador** vuelca datos desde un archivo a una sección de Pymes. Está pensado para listados simples (productos, contactos, conceptos, tarifas) que ya tienes en una hoja de cálculo y quieres meter de una vez en lugar de teclearlos.
Llegas desde **Pymes → Configuración → Importador**, con el botón **Importar datos**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La tarjeta de configuración muestra el botón **Importar datos**, que abre el asistente. El asistente trabaja en tres pasos.
***
## Cómo se importa [#cómo-se-importa]
### Elige la sección [#elige-la-sección]
Seleccionas a qué tipo de datos vas a importar (la sección de destino). El asistente te indica cuántos campos admite y cuáles son obligatorios.
### Sube el archivo y mapea las columnas [#sube-el-archivo-y-mapea-las-columnas]
Subes un archivo **CSV, XLSX o XLS** y emparejas cada columna del archivo con un campo de destino. Tienes una vista previa de las primeras filas y un aviso si queda algún campo obligatorio sin asignar.
### Revisa e importa [#revisa-e-importa]
Ves un resumen con cuántas filas son válidas, cuántas tienen error y cuántas están vacías, y una tabla con el estado de cada fila. Pulsas **Importar** y el asistente vuelca los registros válidos, con un recuento final.
El importador es para secciones sencillas de listado. No sustituye a los procesos específicos, como la [importación de extractos bancarios](/docs/rtg/pymes/tesoreria/como-importar-extractos-bancarios) o del [cuadro de cuentas](/docs/rtg/pymes/contabilidad).
***
→ [Configuración](/docs/rtg/pymes/configuracion)
# Configuración (/docs/rtg/pymes/configuracion)
## Estructura Ventas / Compras [#estructura-ventas--compras]
En Dinaup, cada factura se organiza dentro de un **libro registro**, como el Nacional, Simplificada o Intracomunitaria. Estos libros se pueden [**exportar en Excel**](/docs/rtg/pymes/procesos/exportacion) desde la app de Pymes para contabilidad o Hacienda.
Las facturas siempre pertenecen a un **tipo**, que define su **numeración**, **serie**, prefijos, impuestos y otras reglas. Por ejemplo, puedes tener un tipo “TPV” y otro “Simplificada”, ambos asociados al libro de factura simplificada.
# Planos (/docs/rtg/pymes/configuracion/planos)
Los **planos** son la distribución física de tus espacios: el mapa de cada almacén y la sala de cada punto de venta. Sirven para ubicar el stock por hueco en el almacén y para colocar las mesas en el TPV.
Llegas desde **Pymes → Configuración → Planos**, con dos opciones: **Almacén** y **TPV**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
Cada tipo de plano muestra una rejilla de tarjetas, una por espacio:
* En **Planos de almacén**, una tarjeta por almacén. Diseñas el plano físico de cada uno.
* En **Planos de TPV (sala)**, una tarjeta por sala. Diseñas la distribución de mesas.
Cada tarjeta indica si el espacio **ya tiene un plano diseñado** o si está por diseñar. Al pulsarla se abre el diseñador de ese espacio.
Los planos de almacén necesitan que exista al menos un almacén. Si no tienes ninguno, créalo primero en **Configuración → Almacenes**.
***
→ [Almacenes](/docs/rtg/pymes/inventario-y-precios/almacenes)
→ [Configuración](/docs/rtg/pymes/configuracion)
# Retenciones (/docs/rtg/pymes/configuracion/retenciones)
Una **retención** es un porcentaje que se descuenta del importe de una factura. En lugar de cobrarse o pagarse, queda reservado para ingresarlo a Hacienda en nombre de quien lo soporta. Es el mecanismo habitual del **IRPF** en facturas de profesionales (abogados, consultores, diseñadores…) y en algunos **alquileres**.
En Dinaup configuras tus retenciones una vez y luego las aplicas en las facturas que lo necesiten. El importe retenido se calcula solo y se resta del total.
***
## Retención frente a impuesto [#retención-frente-a-impuesto]
Una retención y un [impuesto](/docs/rtg/pymes/configuracion/impuestos) (como el IVA) viajan juntos en la misma factura, pero hacen lo contrario: el impuesto **suma** al total, la retención **resta**.
| | Impuesto (IVA) | Retención (IRPF) |
| --------------------------- | ------------------------ | ------------------------------------- |
| Efecto sobre el total | Lo **aumenta** | Lo **reduce** |
| Sobre qué se calcula | La base imponible | La base imponible |
| Quién lo ingresa a Hacienda | Quien emite la factura | Quien **paga** la factura |
| Caso típico | Casi toda venta o compra | Facturas de profesionales, alquileres |
En una misma factura puedes tener IVA y retención a la vez. Por ejemplo, una factura de un profesional lleva el IVA que se suma y la retención de IRPF que se resta, ambos sobre la misma base.
***
## Cómo se calcula [#cómo-se-calcula]
El cálculo parte siempre de la **base imponible** (la suma de las líneas, antes de impuestos):
1. Sobre la base se aplica el **IVA**, que se suma.
2. Sobre esa misma base se aplica el **porcentaje de retención**, que se resta.
3. El **total a pagar** es: base + IVA − retención.
Así, el cliente o el proveedor solo abona la diferencia, y quien paga la factura es responsable de ingresar la retención a Hacienda.
El porcentaje de retención que corresponde a cada actividad lo fija la normativa fiscal vigente, y puede cambiar. Dinaup aplica el porcentaje que tú configuras: confírmalo con tu asesoría antes de emitir o registrar facturas.
***
## Configurar una retención [#configurar-una-retención]
### Abre la configuración de Pymes [#abre-la-configuración-de-pymes]
Ve a **Pymes → Configuración**. Ahí gestionas las reglas fiscales de tus facturas, junto a los [impuestos](/docs/rtg/pymes/configuracion/impuestos).
### Crea la retención [#crea-la-retención]
Da de alta una retención con una **etiqueta** clara (la que verás en la factura, por ejemplo "Retención IRPF") y su **porcentaje**. Ese porcentaje es el que Dinaup descontará de la base imponible.
### Guárdala y reutilízala [#guárdala-y-reutilízala]
Una vez creada, la retención queda disponible para aplicarla en cualquier factura de venta o de compra. No tienes que volver a configurarla: la eliges en la factura cuando la necesites.
***
## Aplicar la retención en una factura [#aplicar-la-retención-en-una-factura]
La retención no se aplica a todas las facturas por defecto: la añades solo en las que corresponde.
### En facturas de venta [#en-facturas-de-venta]
Cuando emites una [factura de venta](/docs/rtg/pymes/facturacion/ventas) a un cliente que debe practicarte retención (porque eres profesional, por ejemplo), aplicas la retención en la propia factura. Dinaup resta el importe retenido del total, de modo que tu cliente te paga la base más el IVA menos la retención. Esa retención es la que tu cliente ingresará a Hacienda en tu nombre.
### En facturas de compra [#en-facturas-de-compra]
Cuando registras una [factura de compra o gasto](/docs/rtg/pymes/facturacion/compras) de un proveedor al que tienes que retener (un profesional que te factura, el alquiler de un local…), aplicas la retención al registrarla. Dinaup calcula cuánto le pagas realmente al proveedor (menos la retención) y deja reflejado el importe que tú deberás ingresar a Hacienda.
La diferencia es de **dirección**: en una venta, la retención la soportas tú y te la practica el cliente; en una compra, eres tú quien retiene a tu proveedor. El mecanismo de cálculo es el mismo en ambos casos.
***
## Preguntas frecuentes [#preguntas-frecuentes]
El impuesto (IVA) suma al total de la factura; la retención (IRPF) resta. Ambos se calculan sobre la base imponible, pero la retención reserva un importe que ingresa a Hacienda quien paga la factura, no quien la emite.
Dinaup aplica el porcentaje que configures, no impone ninguno. El porcentaje correcto depende de la actividad y de la normativa fiscal vigente, que puede cambiar. Consúltalo con tu asesoría.
Sí. Es el caso habitual de las facturas de profesionales: el IVA se suma y la retención se resta, ambos sobre la misma base imponible.
No. La añades solo en las facturas que lo requieren (profesionales, alquileres y otros casos sujetos a retención). El resto de facturas no llevan retención.
***
→ [Impuestos](/docs/rtg/pymes/configuracion/impuestos)
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
→ [Facturación de compras](/docs/rtg/pymes/facturacion/compras)
# Correspondencias (/docs/rtg/recursos-humanos/correspondencias)
Una **correspondencia** es un comunicado interno que la empresa dirige a un empleado concreto. Funciona como un canal formal de comunicación con trazabilidad completa: quién la envía, quién la recibe, cuándo se entrega y cuándo se lee.
A diferencia de un correo suelto o un mensaje de chat, cada correspondencia queda **archivada en la ficha del empleado** y deja constancia verificable de que la comunicación llegó y se leyó. Es la herramienta para todo aquello que conviene dejar por escrito: una instrucción, un documento que el empleado debe conocer, un aviso administrativo o un reconocimiento.
***
## Para qué sirve [#para-qué-sirve]
Usa una correspondencia siempre que quieras comunicar algo a un empleado **y dejar rastro** de que lo recibió. Casos típicos:
* **Logística**: cambios de horario, turnos, instrucciones operativas, avisos de organización del día a día.
* **Administrativa**: comunicación de permisos, nóminas, documentos que el empleado debe conocer, recordatorios de plazos.
* **Confidencial**: información sensible que solo debe ver el destinatario, sin reenvíos ni copias visibles para otros.
* **Reconocimiento**: felicitaciones, agradecimientos por un buen trabajo, comunicaciones positivas que quedan en su historial.
Una correspondencia va **siempre a un empleado concreto**. No es un tablón de anuncios ni un comunicado masivo: es comunicación uno a uno con constancia individual.
***
## El ciclo de vida: enviada, abierta, leída [#el-ciclo-de-vida-enviada-abierta-leída]
Cada correspondencia avanza por una serie de **estados** que te dicen exactamente en qué punto está la comunicación. Así sabes, sin preguntar, si el empleado ya se enteró o todavía no.
| Estado | Qué significa |
| ----------- | ----------------------------------------------------------------------------- |
| **Enviada** | La has emitido y está en la bandeja del empleado, a la espera de que la abra. |
| **Abierta** | El empleado ha entrado a verla. La comunicación ya llegó a sus manos. |
| **Leída** | El empleado confirma la lectura. Queda constancia de que conoce el contenido. |
El estado cambia solo, a medida que el empleado interactúa con el mensaje. No tienes que actualizarlo a mano: tú envías, y el sistema registra cada paso.
El estado **Leída** indica que el empleado dejó constancia explícita de haber leído el contenido, no solo de haberlo recibido.
***
## La marca de lectura [#la-marca-de-lectura]
Cuando el empleado da por leída una correspondencia, queda registrada una **marca de lectura**: la fecha y la hora exactas en que confirmó que conocía el contenido.
Esa marca convierte la correspondencia en un **registro laboral verificable**, con sello temporal de que la instrucción o el aviso llegó al empleado.
***
## Enviar una correspondencia [#enviar-una-correspondencia]
### Elige el empleado destinatario [#elige-el-empleado-destinatario]
Abre **Recursos Humanos → Correspondencias** y selecciona al empleado al que va dirigida. Cada correspondencia tiene un único destinatario.
### Redacta el comunicado [#redacta-el-comunicado]
Escribe el mensaje con el contenido que quieres transmitir: la instrucción, el documento, el aviso o el reconocimiento. Dale un asunto claro para que el empleado sepa de qué trata.
### Envíala [#envíala]
Al enviarla, la correspondencia pasa al estado **Enviada** y aparece en la bandeja del empleado. A partir de ahí, el sistema va registrando cuándo la abre y cuándo la marca como leída.
***
## Dónde quedan archivadas [#dónde-quedan-archivadas]
Toda correspondencia, con su estado y su marca de lectura, queda guardada en la **ficha del empleado**. Ahí tienes el historial completo de lo que le has comunicado y de cómo respondió a cada mensaje.
Esto la hace útil mucho más allá del momento del envío: en una auditoría, en un proceso interno o ante cualquier requisito de cumplimiento, dispones de la constancia ordenada de cada comunicación, sin tener que reconstruirla.
→ [Registros de eventos legales](/docs/rtg/recursos-humanos/registros-de-eventos-legales)
***
## Preguntas frecuentes [#preguntas-frecuentes]
Abierta indica que el empleado entró a ver la correspondencia. Leída indica que confirmó explícitamente la lectura, lo que genera la marca de lectura con fecha y hora. Leída es el estado que deja constancia formal.
Una correspondencia va dirigida a un empleado concreto, para que su trazabilidad sea individual. Cada destinatario tiene su propio registro de envío, apertura y lectura.
Se queda en estado Enviada. Así puedes ver qué comunicaciones siguen pendientes de que el empleado las consulte.
Sí. Deja constancia con fecha y hora de que el empleado leyó el contenido, lo que convierte la correspondencia en un registro laboral verificable, útil en auditorías y procesos internos.
***
→ [Volver a Recursos Humanos](/docs/rtg/recursos-humanos)
→ [Registros de eventos legales](/docs/rtg/recursos-humanos/registros-de-eventos-legales)
# Horarios (/docs/rtg/recursos-humanos/horarios)
Desde aquí se configuran los distintos horarios laborales de la empresa, como el horario estándar o variaciones estacionales (por ejemplo, el horario de verano).
# Jornadas (/docs/rtg/recursos-humanos/horarios/jornadas)
Una **jornada** es la definición de las horas de un **día de trabajo**: a qué hora se entra, cuándo se descansa, a qué hora se sale y cuánto margen de flexibilidad hay. Es la pieza base de RRHH: con jornadas montas los [horarios](/docs/rtg/recursos-humanos/horarios) de tu empresa y asignas los [turnos](/docs/rtg/recursos-humanos/turnos) de cada empleado.
Piensa en la jornada como un **molde de un día**. No es el calendario de la semana ni la planificación de una persona concreta: es la plantilla de horas que luego se reutiliza una y otra vez.
***
## Anatomía de una jornada [#anatomía-de-una-jornada]
Cada jornada se define con cuatro piezas. Juntas describen exactamente cómo es un día de trabajo:
| Pieza | Qué define | Ejemplo |
| ---------------- | ----------------------------------------------------------------- | ------------- |
| **Entrada** | Hora a la que empieza el día | 09:00 |
| **Descanso** | Pausa intermedia (comida, café) que no cuenta como trabajo | 14:00 – 15:00 |
| **Salida** | Hora a la que termina el día | 18:00 |
| **Flexibilidad** | Margen de minutos para entrar o salir sin que cuente como retraso | ±30 min |
Con esas cuatro piezas, Dinaup sabe cuántas **horas efectivas** tiene ese día: el tiempo entre la entrada y la salida, menos el descanso.
El **descanso no se trabaja**: se resta del cómputo. Una jornada de 09:00 a 18:00 con una hora de comida son **8 horas efectivas**, no 9.
***
## Para qué sirve la flexibilidad [#para-qué-sirve-la-flexibilidad]
La flexibilidad es el margen que das al empleado para entrar o salir un poco antes o después sin que el sistema lo marque como impuntualidad.
Si la jornada entra a las 09:00 con una flexibilidad de ±30 minutos, fichar a las 09:20 se considera **dentro de la jornada**. Fichar a las 09:45, en cambio, ya queda fuera del margen y cuenta como retraso.
Esto evita que pequeñas variaciones del día a día (un atasco, un fichaje un minuto tarde) ensucien las métricas de [puntualidad](/docs/rtg/recursos-humanos/analisis) del equipo.
***
## Crear una jornada [#crear-una-jornada]
### Abre la configuración de horarios [#abre-la-configuración-de-horarios]
Ve a **RRHH → Horarios**. Ahí defines las jornadas que usará tu empresa.
### Crea una jornada nueva y dale nombre [#crea-una-jornada-nueva-y-dale-nombre]
Dale un nombre claro que describa qué día representa, por ejemplo **"Oficina 9-18"** o **"Media jornada mañanas"**. Ese nombre es el que verás luego al asignar horarios y turnos.
### Define las horas del día [#define-las-horas-del-día]
Indica la **entrada**, el **descanso**, la **salida** y el **margen de flexibilidad**. Con eso queda fijada la cantidad de horas efectivas de la jornada.
### Reutilízala en horarios y turnos [#reutilízala-en-horarios-y-turnos]
Con la jornada creada, ya puedes usarla para construir el [horario](/docs/rtg/recursos-humanos/horarios) semanal de un empleado o asignarla como [turno](/docs/rtg/recursos-humanos/turnos) en un día concreto. Una misma jornada sirve para tantos empleados y días como necesites.
***
## Jornadas, horarios y turnos [#jornadas-horarios-y-turnos]
Las tres piezas trabajan juntas, pero cada una resuelve un nivel distinto:
| Concepto | Qué es | Alcance |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------- |
| **Jornada** | El molde de **un día** (entrada, descanso, salida, flexibilidad) | Una plantilla reutilizable |
| **[Horario](/docs/rtg/recursos-humanos/horarios)** | El conjunto de jornadas a lo largo de la **semana** (qué jornada toca cada día laborable) | El patrón habitual de un empleado |
| **[Turno](/docs/rtg/recursos-humanos/turnos)** | La jornada asignada a una **persona en una fecha concreta** | Un día real en la planificación |
Defines la jornada **una vez** y la reutilizas. Así, si cambia el horario de verano, ajustas la jornada en un sitio y se refleja allá donde se use.
***
## Para qué se usan al calcular horas teóricas [#para-qué-se-usan-al-calcular-horas-teóricas]
Las **horas teóricas** son las que un empleado *debería* trabajar según su planificación, y se calculan a partir de las jornadas que tiene asignadas.
Cada día con jornada aporta sus horas efectivas. La suma de todos los días de un periodo da las horas teóricas de ese empleado. Esa cifra es la referencia contra la que Dinaup compara las **horas reales** (las que salen de sus [fichajes](/docs/rtg/recursos-humanos/fichaje)):
* **Horas teóricas** → lo que marca la jornada planificada.
* **Horas reales** → lo que el empleado fichó de verdad.
* **Diferencia** → las horas de más o de menos, que alimentan el [análisis de productividad](/docs/rtg/recursos-humanos/analisis) del equipo.
Sin una jornada definida, el sistema no tiene contra qué comparar los fichajes.
Si un empleado no tiene jornada asignada un día laborable, ese día no suma horas teóricas y la planificación queda incompleta. Asigna siempre una jornada a cada día de trabajo previsto.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La jornada es el molde de un solo día (entrada, descanso, salida y flexibilidad). El horario es el conjunto de jornadas a lo largo de la semana: qué jornada toca cada día laborable. Defines la jornada una vez y la reutilizas en el horario.
No. El descanso se resta del cómputo. Una jornada de 09:00 a 18:00 con una hora de comida equivale a 8 horas efectivas, no a 9.
Para permitir pequeñas variaciones de entrada y salida sin que cuenten como retraso. Dentro del margen, el fichaje se considera puntual; fuera de él, cuenta como impuntualidad en las métricas.
Las horas que un empleado debería trabajar según las jornadas que tiene planificadas. Dinaup las compara con las horas reales de sus fichajes para calcular diferencias y medir productividad.
Sí. Una jornada es una plantilla: la usas en tantos horarios, turnos y empleados como necesites. Si la modificas, el cambio se refleja allá donde esté aplicada.
***
→ [Horarios](/docs/rtg/recursos-humanos/horarios)
→ [Turnos](/docs/rtg/recursos-humanos/turnos)
→ [Fichaje](/docs/rtg/recursos-humanos/fichaje)
→ [Análisis de productividad](/docs/rtg/recursos-humanos/analisis)
# Editar fichaje (/docs/rtg/recursos-humanos/perfil-de-trabajador/editar-fichaje)
### Horas esperadas [#horas-esperadas]
Las horas esperadas se crean cada día según el horario asignado al usuario. Si deseas planificar un día futuro, puedes abrir el editor de fichaje y pulsar sobre `Copiar del horario`.
#### Configuración Horas Ordinarias o Extras [#configuración-horas-ordinarias-o-extras]
#### Configuración de Ausencias [#configuración-de-ausencias]
# Perfil de Trabajador (/docs/rtg/recursos-humanos/perfil-de-trabajador)
Ficha del empleado con su historial de fichajes, horarios y ausencias.
* [Editar fichaje](/docs/rtg/recursos-humanos/perfil-de-trabajador/editar-fichaje)
# Agregar Calendario de Festivos (/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos)
Un calendario de festivos le dice a Dinaup qué días no se trabaja. Con él asignado, el control horario, las ausencias y las horas teóricas de cada empleado se calculan sobre los días que realmente tocaba trabajar.
## Crear el calendario [#crear-el-calendario]
### Abre los festivos [#abre-los-festivos]
Ve a **Recursos Humanos → Calendario → Festivos** y crea un calendario nuevo con **+ Nuevo**.
### Completa los datos generales [#completa-los-datos-generales]
En la pestaña **General**, rellena:
* **Descripción**: nombre del calendario con año y centro, por ejemplo *Festivos Alicante 2026*.
* **Inicio y Fin**: el periodo de validez, normalmente del 1 de enero al 31 de diciembre.
* **Cantidad de Días**: no lo toques, se calcula solo al añadir festivos.
### Añade los festivos [#añade-los-festivos]
Pulsa **Agregar** por cada día no laborable e indica:
* **Título**: el nombre del festivo, por ejemplo *Día de la Constitución*.
* **Fecha**: el día exacto.
Incluye tanto los festivos oficiales como los propios de tu empresa.
### Guarda y asigna el calendario [#guarda-y-asigna-el-calendario]
Pulsa **Guardar**. Después, en la ficha de cada empleado (pestaña **Recursos Humanos**), selecciona el calendario en el campo **Calendario de Festivos**.
Todos los empleados del mismo centro de trabajo comparten calendario: se crea una vez y se selecciona en cada ficha.
Un empleado sin calendario asignado no tiene festivos: Dinaup contaría esos días como laborables. Asignar el calendario forma parte del alta del empleado.
## Preparar el cambio de año [#preparar-el-cambio-de-año]
El empleado apunta a un calendario, no a un año. Para estrenar año no se toca ninguna ficha: se encadena el calendario nuevo al actual.
### Crea el calendario del año nuevo [#crea-el-calendario-del-año-nuevo]
Repite el proceso de arriba con los festivos del año que entra, por ejemplo *Festivos Alicante 2027*.
### Enlázalo desde el calendario actual [#enlázalo-desde-el-calendario-actual]
Abre el calendario del año en curso y selecciona el nuevo en el campo **Próximo calendario**.
Dinaup recorre la cadena de calendarios enlazados al calcular los festivos de cada empleado, así que todos los que apuntan al calendario actual heredan los festivos del nuevo. Cada diciembre se repite el enlace y las fichas quedan intactas.
Deja el calendario nuevo enlazado antes de planificar los turnos de ese año: el control horario consulta los festivos en el momento de generar cada turno.
## Siguiente paso [#siguiente-paso]
* [Festivos: tipos, calendarios y para qué sirven](/docs/rtg/recursos-humanos/festivos)
* [Control horario](/docs/rtg/recursos-humanos/control-horario)
# Alta de Empleado (/docs/rtg/recursos-humanos/procesos/alta-de-empleado)
Dar de alta a un empleado es el primer paso para gestionarlo dentro del área de **Recursos Humanos**. Estos pasos lo dejan configurado y listo para su operativa diaria.
### Agrega al empleado como usuario [#agrega-al-empleado-como-usuario]
Aprende a dar de alta un empleado en [Gestión de Usuarios](/docs/cuenta/gestion-de-usuarios)
### Activa al empleado [#activa-al-empleado]
Abre la ficha del empleado y marca la opción `Activo`. Esto es necesario para que aparezca en los menús desplegables del sistema.
### ¿Horario fijo o Fichaje flexible? [#horario-fijo-o-fichaje-flexible]
\
Si el empleado tiene una jornada estructurada, lo habitual es configurarlo con **horarios fijos**. En ese caso, deberás activar el control horario y asignarle un horario concreto[Control Horario](/docs/rtg/recursos-humanos/control-horario).\
\
Si, por el contrario, no tiene un horario asignado, el sistema aplica el **fichaje flexible**: el empleado registra su jornada al entrar y salir, sin restricciones horarias.\
[Fichaje flexible](/docs/rtg/recursos-humanos/fichaje)
### **Asignar un calendario de festivos** [#asignar-un-calendario-de-festivos]
Si no existen, puedes crearlo en[Agregar Calendario de Festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos).
Desde la ficha del empleado, entra en la pestaña `Recursos Humanos` y selecciona el `Calendario de Festivos` correspondiente.
# Alta de Horarios (/docs/rtg/recursos-humanos/procesos/alta-de-horarios)
Para que el sistema sepa cuándo trabaja cada persona, primero define **las jornadas**: los turnos típicos que se repiten en tu empresa. Después montas los horarios con esas jornadas y los asignas a cada empleado.
### Crea las jornadas [#crea-las-jornadas]
Ve a `Recursos Humanos` **>** `Horarios` **>** `Jornadas`.
Aquí es donde das de alta los distintos tipos de jornada que usáis habitualmente.\
Por ejemplo:
* Jornada completa
* Jornada parcial
* Turno de mañana
* Turno de tarde
### Crear los horarios [#crear-los-horarios]
Una vez tengas definidas las jornadas, \
ve a `Recursos Humanos` **>** `Horarios` y pulsa sobre `+ NUEVO` para añadir un nuevo horario.
Aquí podrás indicar qué jornada se aplica a cada día de la semana.\
Por ejemplo:
* Lunes a jueves → Jornada completa
* Viernes → Turno de mañana
### Asigna el horario al empleado [#asigna-el-horario-al-empleado]
Con los horarios ya creados, solo te queda asignarlos a cada empleado según corresponda.\
Esto se hace desde **`Recursos Humanos` >** `Horarios` **>** `Asignaciones`, pulsando `+ NUEVO`.
# Asignar Horario a Empleado (/docs/rtg/recursos-humanos/procesos/asignar-horario-a-empleado)
El campo prioridad determina qué horario se aplicará en caso de que varios interseccionen. \
Prioridad 1 se aplicará preferentemente sobre prioridad 2.
Asignar un horario a cada empleado te permite controlar la asistencia, gestionar los fichajes y aplicar las jornadas laborales.
## Requisitos [#requisitos]
Antes de asignar un horario, asegúrate de cumplir con estos dos requisitos:
* **Tener los horarios creados en el sistema**: [Alta de Horarios](/docs/rtg/recursos-humanos/procesos/alta-de-horarios)
* Haber dado de alta al empleado: [Alta de Empleado](/docs/rtg/recursos-humanos/procesos/alta-de-empleado)
## Asignar un horario [#asignar-un-horario]
### Accede a las asignaciones de horario [#accede-a-las-asignaciones-de-horario]
Navega a `Recursos Humanos` **>** `Horarios` **>** `Asignaciones`\
Pulsa el botón `+ NUEVO` para añadir una nueva asignación.
### Completa los datos de la asignación [#completa-los-datos-de-la-asignación]
En la ventana emergente, rellena estos campos:
* **Empleado**: Selecciona a la persona a la que vas a asignar el horario.
* **Horario**: Elige el horario que ya has creado anteriormente.
* **Horario activo desde**: Fecha de inicio del horario.
* **Horario activo hasta**:\
Si no tienes claro cuándo finalizará, puedes usar una fecha futura, por ejemplo, dentro de 10 años.
* **Prioridad**: Solo se usa si hay varias asignaciones que se superponen. En general, déjalo en **0**.
* **Vigente**: Asegúrate de que esté marcado para que el horario esté activo.
* **Observaciones**: Campo libre para anotar cualquier detalle que necesites guardar.
### Guarda y ya está [#guarda-y-ya-está]
Pulsa `GUARDAR`y la asignación quedará activa.
# ¿Cómo editar un fichaje en Dinaup? (/docs/rtg/recursos-humanos/procesos/como-editar-un-fichaje-en-dinaup)
En Dinaup hay dos conceptos distintos que conviene no confundir: **fichajes** y **turnos**.
* **Fichaje:** Es un registro automático, histórico e **inmutable**. Refleja la hora exacta en la que un empleado marcó su **entrada o salida**. No se puede modificar, ya que su objetivo es dejar constancia real del momento en que se fichó, cumpliendo con la normativa de control horario. Es el **dato capturado por el sistema**, aunque no siempre coincida con la jornada que finalmente se imputa.
* **Turno realizado:** Es el tiempo que **efectivamente se reconoce como trabajado**. Puede ajustarse si hay errores o si se necesita reflejar una corrección justificada. Es el dato que impacta en informes, horas acumuladas y cálculos laborales.
## ¿Cómo se representa en Dinaup? [#cómo-se-representa-en-dinaup]
Al consultar la Línea de Tiempo de un empleado, verás tres niveles:
* **Programado**: El horario que estaba previsto, según los turnos asignados. Si el empleado no tenía turno programado o está en modo fichaje flexible, esta fila puede aparecer vacía.
* **Realizado**: El total de tiempo que se le reconoce como trabajado, tras validar los fichajes y aplicar cualquier ajuste necesario.
* **Fichaje**: Los momentos exactos en que el empleado fichó. Son registros técnicos, no editables, que sirven como base para contrastar con lo realizado.
## ¿Cómo editar el turno realizado? [#cómo-editar-el-turno-realizado]
Si necesitas corregir una jornada (por ejemplo, por olvido de fichaje o error en la imputación), puedes hacerlo desde la Línea de Tiempo:
1. Inicia sesión en [play.dinaup.com](https://play.dinaup.com/)
2. Navega hacia *`Recursos Humanos` → `Línea de Tiempo` .*
3. Localiza el **día** y **empleado** que quieres corregir.
4. En la esquina inferior derecha del registro, haz clic en **`“Editar”`**.
5. Ajusta el bloque donde pone **"Trabajado"** para reflejar el tiempo real que debe computarse.
6. Guarda los cambios.
El sistema conservará el fichaje original sin alteraciones. Solo se actualizará el **turno realizado** del día.
# Cómo Planificar una Ausencia Parcial (/docs/rtg/recursos-humanos/procesos/como-planificar-una-ausencia-parcial)
### Ve al calendario del empleado [#ve-al-calendario-del-empleado]
* Ve al calendario del empleado
* Selecciona el **día que se va a ausentar**
### Edita el Horario Oficial [#edita-el-horario-oficial]
* Haz clic en ese día
* Busca el contenedor **"Horario Oficial"**
* Configura el día teniendo en cuenta la ausencia y motivo
### Pulsa guardar [#pulsa-guardar]
* Revisa que todo esté correcto
* Haz clic en **"Guardar"**
# Procesos (/docs/rtg/recursos-humanos/procesos)
Guías para las tareas habituales de Recursos Humanos:
* [Alta de Empleado](/docs/rtg/recursos-humanos/procesos/alta-de-empleado)
* [Asignar Horario a Empleado](/docs/rtg/recursos-humanos/procesos/asignar-horario-a-empleado)
* [Alta de Horarios](/docs/rtg/recursos-humanos/procesos/alta-de-horarios)
* [Agregar Calendario de Festivos](/docs/rtg/recursos-humanos/procesos/agregar-calendario-de-festivos)
* [Cómo editar un fichaje en Dinaup](/docs/rtg/recursos-humanos/procesos/como-editar-un-fichaje-en-dinaup)
* [Cómo Planificar una Ausencia Parcial](/docs/rtg/recursos-humanos/procesos/como-planificar-una-ausencia-parcial)
# Vacaciones y Ausencias (/docs/rtg/recursos-humanos/vacaciones-y-ausencias)
Esta sección gestiona vacaciones y ausencias planificadas o imprevistas. Los empleados solicitan permisos y los responsables los aprueban o rechazan, manteniendo un control ordenado del tiempo libre de cada trabajador.
# Motivos de Ausencias (/docs/rtg/recursos-humanos/vacaciones-y-ausencias/motivos-de-ausencias)
Aquí se categorizan las diferentes razones por las cuales un empleado puede ausentarse, como enfermedad, permiso personal o licencia especial. Esta clasificación ayuda a mantener un control detallado sobre la asistencia.
# Badges y estados (/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados)
Pintas un estado (`Pagado`, `Vencido`, `Pendiente`) y quieres que salga del color que toca sin sentarte a elegir hex ni mantener un diccionario. Le pasas el texto a `DnzBadgetAutoColor` y deduce el color: verde lo bueno, rojo lo malo, cyan lo pendiente. La familia completa la cierran banderas de país, deltas con flecha de tendencia, etiquetas de producto (PRO, Beta, IA) y un punto pulsante para estados en vivo.
Si mañana cambias `Pagada` por `Cobrada`, sigue saliendo verde sin tocar nada: el color sale del texto, no de un mapeo tuyo.
## Qué componente uso [#qué-componente-uso]
| Quieres... | Componente |
| ------------------------------------------------------- | ---------------------- |
| Una etiqueta de estado que se colorea sola por el texto | `DnzBadgetAutoColor` |
| Marcar una función como PRO, Beta, Nuevo, IA o Premium | `DnzSpecialBadges` |
| Mostrar una bandera de país junto a su código ISO | `DnzCountryBadge` |
| Una variación con flecha y color (sube bien / baja mal) | `DnzDeltaBadge` |
| Un punto de estado que late (online, alerta, caído) | `DnzPulseDotAnimation` |
| Resumir cuántas filas hay en cada estado de un informe | `DnzStatusSummary` |
***
## DnzBadgetAutoColor [#dnzbadgetautocolor]
Le pasas el texto del estado en `Value` y elige el color por ti.
```razor
```
### Cómo decide el color: 3 prioridades [#cómo-decide-el-color-3-prioridades]
El componente resuelve el color en este orden, y se queda con la primera que aplique:
### Color explícito por enum [#color-explícito-por-enum]
Si pasas `Color` con un valor distinto de `Indefinido`, manda eso y se acabó. Es el override total: ignora el texto.
```razor
```
### Estilo por diccionario [#estilo-por-diccionario]
Si no fuerzas `Color` pero pasas un `BadgetStyle` (un `Dictionary` que mapea texto exacto a un índice de estilo), busca el `Value` ahí. Sirve para colorear estados propios de tu dominio que el mapeo automático no conoce.
```razor
```
### Mapeo automático por palabra [#mapeo-automático-por-palabra]
Si no hay ni `Color` ni acierto en el diccionario, normaliza el texto (lo pasa a minúsculas y recorta) y lo busca en sus categorías semánticas internas. Aquí es donde `Pagado` se vuelve verde solo.
### Qué palabras disparan cada color [#qué-palabras-disparan-cada-color]
El mapeo automático reconoce decenas de palabras en español e inglés, agrupadas por categoría. Una muestra representativa de cada grupo:
| Color | Categoría | Ejemplos de texto que la disparan |
| --------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Verde (success) | Estados positivos / completados | `pagado`, `cobrada`, `activo`, `conciliado`, `aprobado`, `enviado`, `paid`, `done`, `confirmed` |
| Rojo (danger) | Estados negativos / error | `cancelado`, `vencido`, `rechazado`, `impagado`, `bloqueado`, `error`, `expired`, `failed`, `overdue` |
| Cyan (pending) | Pendientes / en espera | `pendiente`, `abierto`, `por cobrar`, `borrador`, `pending`, `open`, `draft`, `awaiting payment` |
| Azul sky (en proceso) | En curso | `en proceso`, `procesando`, `en revisión`, `facturando`, `in progress`, `processing`, `under review` |
| Amarillo (warning) | Advertencia | `atención`, `próximo a vencer`, `incidencia`, `retrasado`, `warning`, `expiring soon`, `delayed` |
Más allá de estados, también clasifica por **temporalidad** (`hoy`/`today` verde, `ayer`/`yesterday` rojo), **tipo de operación** (`venta` verde outline, `compra` naranja, `transferencia` azul), **tipo de factura**, **periodicidad** (`mensual`, `anual`, `único`), **contabilidad** y **prioridad** (`urgente` rojo, `media` naranja, `baja` verde). Y hace coincidencia parcial para frases como `pago parcial` o `sin factura`.
El mapeo automático es por coincidencia de texto: si tu estado no está entre las palabras reconocidas, sale con el color por defecto (gris). Para estados propios de tu dominio, usa `BadgetStyle` o fuerza `Color`. No es magia, es un diccionario amplio.
Si el `Value` viene vacío o solo espacios, el componente no pinta nada.
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| ------------- | ------------------------- | ------------ | --------------------------------------------------------------------------------------------------------- |
| `Value` | `string` | | Texto del estado a mostrar. Es lo que se pinta y lo que se mapea a color. Si está vacío, no renderiza. |
| `Color` | `EnumTextoEstiloE` | `Indefinido` | Color explícito (prioridad 1). Con cualquier valor distinto de `Indefinido` ignora el texto y manda este. |
| `BadgetStyle` | `Dictionary` | `null` | Diccionario texto exacto a índice de estilo (prioridad 2). Para colorear estados propios. |
| `Visible` | `bool` | `true` | Si es `false`, el componente no se pinta. |
| `Style` | `string` | `null` | CSS inline extra para el ``. |
| `Click` | `EventCallback` | | Callback al pulsar la etiqueta. Si lo asignas, el badge muestra el cursor de mano. |
***
## DnzSpecialBadges [#dnzspecialbadges]
Etiqueta de producto con degradado e icono: marca una función como PRO, Beta, Nuevo, IA o Premium. Texto e icono ya vienen fijados por tipo, tú solo eliges cuál.
```razor
```
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| --------- | ----------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| `Type` | `BadgeType` | `Pro` | Qué etiqueta pintar. Valores del enum: `Pro`, `Beta`, `New`, `IA`, `Premium`. Cada uno trae su texto, icono y degradado. |
***
## DnzCountryBadge [#dnzcountrybadge]
Bandera de país más su código ISO en una etiqueta clara. Le pasas el código `alpha-2` y resuelve la imagen de la bandera desde el CDN de Dinaup.
```razor
```
`CountryCode` es obligatorio (`EditorRequired`). Espera ISO 3166-1 alpha-2: `ES`, `US`, `MX`, `FR`... Si la bandera no carga, la imagen se oculta sola y queda solo el código.
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| ----------------- | -------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `CountryCode` | `string` | `""` | Código de país ISO 3166-1 alpha-2. Obligatorio (`EditorRequired`). Si viene vacío, no pinta nada. |
| `Size` | `int` | `22` | Tamaño de la bandera en píxeles (alto y ancho). |
| `FlagUrlTemplate` | `string` | `https://dinaupcdn.com/public/flags/{0}.svg` | Plantilla de URL de la bandera. Debe contener `{0}`, que se reemplaza por el código en minúsculas. |
***
## DnzDeltaBadge [#dnzdeltabadge]
Una variación numérica con color y flecha: verde y flecha arriba si sube, rojo y flecha abajo si baja, gris y raya si es cero. Pensado para "+12% vs mes anterior" y similares.
```razor
```
Cuando un número que sube es malo (gastos, devoluciones, churn), invierte los colores:
```razor
```
Para valores absolutos en vez de porcentaje, apaga `IsPercent`:
```razor
```
El signo y la flecha salen del signo del `Value`: positivo sube, negativo baja, cero queda neutro. No tienes que pasar el signo ni el icono, los calcula el componente. Si `Value` es `null`, no pinta nada.
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| -------------- | ---------- | ----------- | ---------------------------------------------------------------------------------------------------- |
| `Value` | `decimal?` | `null` | La variacion a mostrar. Su signo decide color, flecha y signo del texto. Si es `null`, no renderiza. |
| `IsPercent` | `bool` | `true` | Si `true`, formatea como porcentaje (`%`); si `false`, como numero entero con separador de miles. |
| `InvertColors` | `bool` | `false` | Invierte la lectura de color: subir pasa a rojo y bajar a verde. Para metricas donde crecer es malo. |
| `Size` | `SizeType` | `Normal` | Tamano de la etiqueta. Valores: `Small`, `Normal`. |
| `Tooltip` | `string` | `""` | Texto del `title` al pasar el raton. |
***
## DnzPulseDotAnimation [#dnzpulsedotanimation]
Un punto de estado que late: online, alerta o caido en dashboards en tiempo real. Color por enum y el latido se puede apagar.
```razor
```
Estatico (sin animacion) y mas grande:
```razor
```
Respeta `prefers-reduced-motion`: si el usuario pide menos animaciones en su sistema, el punto deja de latir solo. No tienes que gestionarlo tu.
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| --------------- | ------------ | ----------- | ------------------------------------------------------------------------------------------- |
| `Color` | `PulseColor` | | Color del punto. Obligatorio (`EditorRequired`). Valores: `Green`, `Yellow`, `Red`, `Gray`. |
| `Pulse` | `bool` | `true` | Si `true`, el punto emite el anillo pulsante; si `false`, queda fijo. |
| `Size` | `int` | `14` | Diametro del punto en pixeles. |
| `RingPadding` | `int` | `6` | Espacio (px) entre el punto y el borde del anillo pulsante. |
| `RingThickness` | `int` | `2` | Grosor (px) del anillo pulsante. |
| `Title` | `string` | `null` | Texto del `title` (tooltip y accesibilidad). |
***
## DnzStatusSummary [#dnzstatussummary]
Resumen de estados de un informe Flex: agrupa las filas por su columna de estado y pinta cuantas hay en cada uno, con su badge de color y una barra de proporcion. No le pasas datos a mano, lee el `ReportContext` de la cascada.
```razor
```
Solo aparece si el informe trae filas y la columna de estado permite agrupacion tipo Kanban. Si el informe esta vacio no pinta nada, asi que no tienes que esconderlo. Reutiliza `DnzBadgetAutoColor` por dentro, asi que cada estado sale del color que le toca. Mas sobre informes en [Informes (Flex)](/docs/desarrollo/flex/informes).
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| --------------- | ----------------------- | ----------- | ---------------------------------------------------------------------------------------------- |
| `Context` | `ReportContext` | | Llega por `[CascadingParameter]`. No se pasa como atributo: lo provees con ``. |
| `OnStatusClick` | `EventCallback` | | Se dispara al pulsar un estado, con su texto. Util para filtrar el informe por ese estado. |
***
Ver tambien: [Componentes DinaZen](/docs/desarrollo/dotnet/dinazen/componentes) · [KPIs y metricas](/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas) · [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes) · [Intro DinaZen](/docs/desarrollo/dotnet/dinazen) · [Informes (Flex)](/docs/desarrollo/flex/informes) · [Guias de estilo C#/Blazor](/docs/desarrollo/dotnet/c-code-style-guidelines)
# Carga y rendimiento (/docs/desarrollo/dotnet/dinazen/componentes/carga-y-rendimiento)
Cuatro situaciones que se confunden, cuatro componentes. Hay una accion en marcha y quieres avisar de que algo se esta procesando: `DnzLoader`. La interfaz todavia no esta lista y quieres mostrar el hueco que va a ocupar: `DnzSkeleton`. Tienes una subpagina o seccion cara de pintar y quieres aplazar su render hasta que toque: `DnzDeferredContent`. Y si un bloque puede petar al renderizar, lo aislas para que no se lleve la pagina entera: `DnzTryComponent`. Elige por el **momento**, no por el aspecto.
## Cual va en cada caso [#cual-va-en-cada-caso]
La confusion habitual es entre "estoy procesando una accion" y "la interfaz aun no esta lista". No son lo mismo:
| Necesitas | Usa | Por que |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------- |
| Avisar de que **estas procesando**: una seccion entera carga datos y aun no tienes nada que pintar | `DnzLoader` | Spinner neutro centrado en el hueco mientras esperas a `OnInitializedAsync` |
| Avisar de que **la UI aun no esta lista**: reservar el hueco con la forma del contenido (lista, tarjeta, KPIs) | `DnzSkeleton` | Esqueleto animado: el usuario ya ve cuanto va a ocupar, asi la espera se siente mas corta |
| Aplazar el render de un bloque pesado para que la pagina respire | `DnzDeferredContent` | Pinta primero un skeleton y monta el contenido real tras un delay; ideal para revelado progresivo |
| Que un componente que puede fallar no tumbe toda la pagina | `DnzTryComponent` | Captura la excepcion de render y muestra un fallback en su lugar |
| Feedback de una accion concreta del usuario (un boton, 1-10s) | `IsBusy=@variable` en el boton | No es de esta familia: el spinner vive en el propio boton |
La regla rapida: **`DnzLoader` = "estoy trabajando"** (hay una operacion en curso). **`DnzSkeleton` = "esto aun no esta"** (la interfaz se esta montando). Si dudas, preguntate si hay datos viajando ahora mismo (loader) o si solo estas pintando el hueco a la espera (skeleton).
***
## DnzLoader [#dnzloader]
Spinner neutro para cuando una seccion entera esta cargando datos y aun no tienes nada que pintar. Es el patron de "cargar en `OnInitializedAsync` y devolver pronto".
```razor
@if (Facturas.IsNull())
{
}
else
{
}
@code {
private List Facturas { get; set; }
protected override async Task OnInitializedAsync()
{
Facturas = await FacturasService.GetPendientesAsync();
}
}
```
En barras o cabeceras estrechas, donde un spinner centrado no encaja, pasa `Horizontal="true"` para la variante compacta de puntos:
```razor
Sincronizando
```
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| ------------ | ------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Horizontal` | `bool` | `false` | `false` pinta el loader vertical centrado en el hueco; `true` usa la variante horizontal compacta (tira de puntos), util en barras o cabeceras estrechas |
***
## DnzSkeleton [#dnzskeleton]
Reserva el hueco con rectangulos animados que imitan la forma del contenido que va a llegar. A diferencia del loader, el usuario ve cuantas lineas y que tamano va a ocupar, asi que la espera se siente mas corta.
```razor
@if (Movimientos.IsNull())
{
}
else
{
}
```
Combina varios skeletons de distinto tamano para imitar un encabezado mas filas:
```razor
```
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| ---------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `Lines` | `int` | `1` | Numero de rectangulos (lineas) que pinta. Ajustalo a las filas que esperas: una tarjeta `1`, una lista `5`, un formulario largo `20` |
| `Height` | `string` | `"1rem"` | Alto de cada linea. Sube a `"80px"` para simular una tarjeta o KPI |
| `Radius` | `string` | `"0.25rem"` | Radio de las esquinas de cada rectangulo |
| `MaxWidth` | `string` | `"100%"` | Ancho maximo del bloque. Limitalo (`"400px"`, `"55%"`) cuando el skeleton no deba ocupar todo el ancho |
***
## DnzDeferredContent [#dnzdeferredcontent]
Envuelve un bloque pesado y aplaza su montaje: durante el delay pinta un esqueleto y, pasado ese tiempo, monta el contenido real. Es la pieza clave para que paginas con muchas subvistas aparezcan rapido en lugar de bloquearse pintando todo de golpe.
```razor
```
**Por que importa para el rendimiento.** En una pagina con muchas subvistas (un dashboard, una ficha con varias pestanas, un listado con tarjetas pesadas), Blazor intenta renderizar todo en el primer paso. Envolviendo cada bloque caro en un `DnzDeferredContent` con delays crecientes, lo importante sale ya y el resto llega escalonado: la pagina da sensacion de velocidad aunque el trabajo total sea el mismo.
Patron de revelado progresivo en un dashboard: los KPIs (lo importante) salen ya, las tarjetas pesadas llegan escalonadas.
```razor
```
Si no te vale el skeleton por defecto, pasa tu propio indicador de carga en `LoadingContent`:
```razor
```
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| ---------------- | ---------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| `DelayMs` | `int` | `500` | Milisegundos antes de montar el contenido real. `0` pinta ya; usa valores crecientes (300, 600...) para escalonar secciones |
| `ChildContent` | `RenderFragment` | | El contenido pesado que se aplaza. Es lo que pones entre las etiquetas del componente |
| `LoadingContent` | `RenderFragment` | | Indicador de carga a medida mientras espera. Si no lo pasas, usa un `DnzSkeleton` |
| `Class` | `string` | `""` | Clase CSS para el contenedor del estado de carga (p. ej. `"p-3"` para darle aire) |
`DnzDeferredContent` aplaza el **render**, no la carga de datos. Si lo caro es la query, traela en `OnInitializedAsync` y combina con `DnzLoader`/`DnzSkeleton`. El diferido solo reparte el coste de pintar la interfaz, no el de ir a buscar los datos.
***
## DnzTryComponent [#dnztrycomponent]
Envuelve un bloque que puede petar al renderizar y captura la excepcion para que no se lleve la pagina entera. Es un `ErrorBoundary` con un fallback opcional a medida.
```razor
```
Con fallback propio: el `context` es la `Exception` capturada, asi que puedes mostrar el motivo.
```razor
No se pudo cargar el widget: @context.Message
```
El componente expone un metodo `Recover()` por referencia (`@ref`) para reintentar el render tras un fallo, util si das al usuario un boton de "Reintentar":
```razor
El widget fallo: @context.Message boundary.Recover()) />
@code {
private DnzTryComponent boundary;
}
```
**Parametros**
| Parametro | Tipo | Por defecto | Que hace |
| -------------- | --------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ChildContent` | `RenderFragment` | | El contenido que se renderiza dentro del limite de error. Obligatorio (`EditorRequired`) |
| `ErrorContent` | `RenderFragment` | | Fallback que se pinta si el `ChildContent` lanza una excepcion. El `context` es la `Exception` capturada. Si no lo pasas, no se muestra nada en su lugar |
`DnzTryComponent` tiene tambien un metodo publico `Recover()` (accesible por `@ref`) que reintenta renderizar el `ChildContent` despues de un fallo. Combinalo con un boton "Reintentar" en tu `ErrorContent`.
***
## Relacionado [#relacionado]
* [Dialogos](/docs/desarrollo/dotnet/dinazen/componentes/dialogos): `DnzSkeleton` es el patron tipico mientras el cuerpo de un dialogo carga sus datos
* [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes): donde mas rinde el diferido y los skeletons al pintar listados pesados
* [KPIs y metricas](/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas): el caso de uso clasico del revelado progresivo con `DnzDeferredContent`
* [Cookbook de patrones](/docs/desarrollo/dotnet/dinazen/patrones): recetas de extremo a extremo que combinan estos componentes con el SDK
* [Indice de componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [Intro DinaZen](/docs/desarrollo/dotnet/dinazen)
* [SDK .NET](/docs/desarrollo/dotnet/sdk) · [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente): trae los datos que estos componentes cubren mientras cargan
* [Informes de Dinaup Flex](/docs/desarrollo/flex/informes): la fuente de datos que suele estar detras de un loader o un skeleton
# Datos tipados (Spans) (/docs/desarrollo/dotnet/dinazen/componentes/datos-tipados)
Lees una fila de un informe y pintas cada celda con el formato correcto: el dinero con su simbolo, la fecha en local, los minutos como duracion, los bytes como MB. Todo sin formatear a mano ni acordarte de la cultura del cliente.
Comparten patron: les pasas el valor crudo y ellos deciden como mostrarlo. Casi todos aceptan un `Label`/`Key`, un `Icon` opcional y un `FontSize`. El formato y la region salen del `RegionService` interno, asi que el mismo componente se ve bien en cualquier pais. Mapean 1:1 con las columnas que devuelve un [informe del SDK](/docs/desarrollo/flex/informes): la columna trae el dato, el span lo pinta.
El tipo del dato manda: si tienes un `decimal` de euros usa `DnzSpanMoney`, si es un porcentaje `DnzSpanPercent`, si son minutos `DnzSpanMinutes`. No hay un span generico que valga para todo.
## Que formatea cada uno [#que-formatea-cada-uno]
| Componente | Tipo de valor | Para que sirve |
| --------------------------- | -------------------- | ------------------------------------------------------------ |
| `DnzSpanMoney` | `decimal?` (importe) | Dinero con simbolo de moneda y region. Auto-color rojo/verde |
| `DnzSpanDecimal` | `decimal?` | Decimal con sufijo libre (` kg`, ` uds`...). Auto-color |
| `DnzSpanPercent` | `decimal?` | Porcentaje con ` %` y decimales recortados. Auto-color |
| `DnzSpanInteger` | `decimal?` | Entero pelado (trunca decimales) |
| `DnzSpanDate` | `DateOnly?` | Fecha localizada con badge Hoy/Ayer/Pasado |
| `DnzSpanDateTime` | `DateTime?` | Fecha y hora completa, relativa o con estado |
| `DnzSpanMinutes` | `decimal?` (minutos) | Minutos como duracion corta: `90 -> 1h 30m` |
| `DnzSpanKV` | `string` | Par clave-valor inline (label + valor) |
| `DnzSpanBytes` | `long?` | Tamano en B/KB/MB/GB/TB |
| `DnzSpanGigaBytes` | `decimal?` (GB) | GB con conversion automatica de unidad |
| `DnzSpanGrams` | `decimal?` (gramos) | Peso en gr o Kg segun magnitud |
| `DnzTimeSpanDisplay` | `TimeSpan?` | Duracion en partes: `2d 3h 15m` |
| `DnzTimeSpanDisplayCompact` | `TimeSpan?` | Igual, en tamano pequeno |
| `DnzTimeSpanDisplayBadge` | `TimeSpan?` | Igual, cada parte en un badge |
Todos se autoocultan cuando el valor es nulo: si `Value`/`Amount` viene `null`, no pintan nada. No hace falta envolverlos en un `@if`.
### AutoColor: verde positivo, rojo negativo [#autocolor-verde-positivo-rojo-negativo]
`DnzSpanMoney`, `DnzSpanDecimal` y `DnzSpanPercent` traen `AutoColor`. Con el activado, el valor se pinta **verde si es positivo y rojo si es negativo**. Ideal para saldos, margenes o variaciones, donde el signo distingue lo que suma de lo que resta sin escribir una sola condicion.
```razor
```
Saldo positivo, verde. Saldo en numeros rojos, rojo. Sin un solo `if`.
```razor
```
Un total se enseña en el color por defecto: no tiene sentido pintar de rojo un importe que solo es lo que hay que pagar.
***
## DnzSpanMoney [#dnzspanmoney]
Importes de dinero con el simbolo de moneda y el formato de la region del cliente. Para listados de facturas, totales y resumenes.
```razor
```
Con etiqueta e icono para un KPI en una tarjeta:
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ---------------- | ---------- | -------- | ------------------------------------------------ |
| `Amount` | `decimal?` | `0` | El importe a mostrar. Si es `null` no pinta nada |
| `Label` | `string` | `""` | Etiqueta encima del importe (caption) |
| `Icon` | `string` | `""` | Icono Material a la izquierda (requiere `Label`) |
| `AutoColor` | `bool` | `false` | Verde si positivo, rojo si negativo |
| `AutoColorGreen` | `bool` | `false` | Solo verde cuando es positivo |
| `AutoColorRed` | `bool` | `false` | Solo rojo cuando es negativo |
| `CssClass` | `string` | `""` | Clases extra para el `` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
| `IsVisible` | `bool` | `true` | Oculta el componente sin quitarlo del arbol |
Sin `Label` pinta solo el importe. Con `Label` lo monta en columna (etiqueta arriba, importe abajo). Con `Label` + `Icon`, ademas añade el icono a la izquierda del bloque.
## DnzSpanDecimal [#dnzspandecimal]
Cualquier decimal con un sufijo libre detras: unidades de stock, kilos, lo que sea. Lo que `DnzSpanMoney` hace con la moneda, este lo deja a tu eleccion via `Symbol`.
```razor
```
Una diferencia con color segun el signo:
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ----------- | ---------- | -------- | -------------------------------------------- |
| `Value` | `decimal?` | `null` | Numero a mostrar. Si es `null` no pinta nada |
| `Symbol` | `string` | `""` | Texto detras del numero (` kg`, ` uds`...) |
| `AutoColor` | `bool` | `false` | Verde si positivo, rojo si negativo |
| `Class` | `string` | `""` | Clases extra para el `` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
## DnzSpanPercent [#dnzspanpercent]
Porcentaje listo: tu das el numero en escala humana (`12.5`), el le pone el ` %` y recorta los decimales sobrantes.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ----------- | ---------- | -------- | ------------------------------------------------------------------ |
| `Value` | `decimal?` | `null` | Porcentaje a mostrar. Si es `null` no pinta nada |
| `Decimals` | `int` | `1` | Decimales maximos; los ceros de cola se omiten (`12,50` -> `12,5`) |
| `AutoColor` | `bool` | `false` | Verde si positivo, rojo si negativo |
| `Class` | `string` | `""` | Clases extra para el `` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
`Value` va en escala humana: para enseñar "12,5 %" pasale `12.5`, no `0.125`.
## DnzSpanInteger [#dnzspaninteger]
Entero limpio: trunca la parte decimal del valor y lo pinta sin separadores ni simbolos. Para contadores y cantidades enteras donde los decimales sobran.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ---------- | ---------- | -------- | ------------------------------------ |
| `Value` | `decimal?` | `null` | Valor a truncar y mostrar como `int` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
## DnzSpanDate [#dnzspandate]
Fecha (sin hora) en formato amigable y localizado, con un badge opcional que dice si es Hoy, Ayer, Manana, Pasado o Futuro. Trabaja con `DateOnly`.
```razor
```
Con el badge de estado para una agenda de vencimientos:
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| -------------- | ----------- | ------------ | ------------------------------------------- |
| `Value` | `DateOnly?` | `null` | Fecha a mostrar. Si es `null` no pinta nada |
| `FriendlyMode` | `bool` | `true` | Formato amigable en lugar de literal |
| `ShowBadge` | `bool` | `false` | Pinta la fecha dentro de un `RadzenBadge` |
| `ShowStatus` | `bool` | `false` | Anade el badge Hoy/Ayer/Pasado al lado |
| `Class` | `string` | `""` | Clases extra para el contenedor |
| `FontSize` | `string` | `"0.875rem"` | Tamano de fuente |
El tooltip siempre lleva la fecha exacta, aunque el texto visible sea amigable. Pasas el raton por encima y ves el dia concreto.
## DnzSpanDateTime [#dnzspandatetime]
Fecha y hora completas. Puede pintarse en modo relativo (`hace 5 min`), como caption discreto, o con el badge de estado. Trabaja con `DateTime` (en UTC, como todo en Dinaup).
```razor
```
Modo relativo para un feed de actividad reciente:
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ------------ | ----------- | ------------ | -------------------------------------------------------- |
| `Value` | `DateTime?` | `null` | Fecha y hora a mostrar. Si es `null` no pinta nada |
| `Relative` | `bool` | `false` | Texto relativo (`hace 5 min`); el absoluto va al tooltip |
| `ShowBadge` | `bool` | `false` | Pinta el texto dentro de un `RadzenBadge` |
| `ShowStatus` | `bool` | `false` | Anade el badge Hoy/Ayer/Pasado al lado |
| `Caption` | `bool` | `false` | Estilo caption (texto pequeno y discreto) |
| `Class` | `string` | `""` | Clases extra para el contenedor |
| `FontSize` | `string` | `"0.875rem"` | Tamano de fuente |
## DnzSpanMinutes [#dnzspanminutes]
Convierte un numero de minutos en una duracion corta y legible: `45 -> 45m`, `90 -> 1h 30m`, `180 -> 3h`. Aguanta negativos (les antepone el signo). Para tiempos de servicio, citas o tareas medidas en minutos.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ---------- | ---------- | -------- | ----------------------------------------------------------------------- |
| `Value` | `decimal?` | `0` | Minutos totales. Soporta negativos (`-30m`). Si es `null` no pinta nada |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
## DnzSpanKV [#dnzspankv]
Par clave-valor: la etiqueta arriba o a la izquierda y el valor debajo o al lado. Es el bloque de detalle tipico de un dialogo o una ficha. A diferencia del resto, este recibe el valor ya formateado como `string` (o un `ChildContent` con markup libre).
```razor
```
```razor
```
El `ChildContent` manda: si lo pones, ignora `Value` y pinta lo que metas dentro.
**Parametros**
| Parametro | Tipo | Default | Que hace |
| -------------- | ---------------- | ------- | --------------------------------------------------------- |
| `Key` | `string` | `""` | La etiqueta / clave |
| `Value` | `string` | `null` | El valor ya formateado (si no usas `ChildContent`) |
| `ChildContent` | `RenderFragment` | `null` | Markup libre para el valor; tiene prioridad sobre `Value` |
| `Horizontal` | `bool` | `false` | Clave y valor en la misma linea, no apilados |
| `Icon` | `string` | `""` | Icono Material o URL de imagen (`/...` o `http`) |
| `IconColor` | `string` | `""` | Color del icono |
| `ValueColor` | `string` | `""` | Color del texto del valor |
| `TextRight` | `bool` | `false` | Alinea el valor a la derecha |
| `LabelWidth` | `string` | `""` | Ancho maximo de la etiqueta |
| `Class` | `string` | `""` | Clases extra para el contenedor |
| `Visible` | `bool` | `true` | Oculta el componente entero |
## DnzSpanBytes [#dnzspanbytes]
Tamano de fichero a partir de un `long` de bytes, con conversion automatica de unidad: elige entre B, KB, MB, GB o TB segun la magnitud. Para adjuntos, backups y almacenamiento.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ---------- | -------- | -------- | ------------------------------------------- |
| `Value` | `long?` | `null` | Tamano en bytes. Si es `null` no pinta nada |
| `Class` | `string` | `""` | Clases extra para el `` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
## DnzSpanGigaBytes [#dnzspangigabytes]
Igual que `DnzSpanBytes` pero partiendo de GB (`decimal`). Sube a TB o baja a MB/KB segun el valor, y puede pintar en color cuando se acerca a la cuota.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ----------- | ---------- | -------- | ---------------------------------------- |
| `Value` | `decimal?` | `null` | GB a mostrar. Si es `null` no pinta nada |
| `AutoColor` | `bool` | `false` | Naranja si > 50, rojo si > 100 |
| `Class` | `string` | `""` | Clases extra para el `` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
Ojo: el `AutoColor` de `DnzSpanGigaBytes` **no** es verde/rojo por signo, es un semaforo de consumo (naranja al pasar de 50 GB, rojo al pasar de 100 GB). Pensado para cuotas de almacenamiento.
## DnzSpanGrams [#dnzspangrams]
Peso a partir de gramos (`decimal`). Por debajo de 1000 lo muestra en `gr`; a partir de ahi salta a `Kg`. Pensado para basculas y pesaje en TPV.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ----------- | ---------- | -------- | ------------------------------------------ |
| `Value` | `decimal?` | `null` | Peso en gramos. Si es `null` no pinta nada |
| `AutoColor` | `bool` | `false` | Color segun si pasa de 1000 gr |
| `Class` | `string` | `""` | Clases extra para el `` |
| `FontSize` | `string` | `"16px"` | Tamano de fuente |
## DnzTimeSpanDisplay [#dnztimespandisplay]
Pinta un `TimeSpan` descompuesto en partes con su etiqueta: `2d 3h 15m`. Solo muestra las partes que no son cero, asi que una duracion corta sale limpia. Numero y etiqueta se estilan por separado.
```razor
```
Con texto para el caso vacio:
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ------------- | ----------- | ------------------------- | ----------------------------------------------------------------- |
| `Value` | `TimeSpan?` | `null` | Duracion a descomponer. Si es `null` muestra `EmptyText` (o nada) |
| `ShowSeconds` | `bool` | `false` | Incluye los segundos en el desglose |
| `EmptyText` | `string` | `""` | Texto a mostrar cuando `Value` es `null` |
| `NumberClass` | `string` | `"fw-semibold text-dark"` | Clases para los numeros |
| `LabelClass` | `string` | `"text-muted small ms-1"` | Clases para las etiquetas (`d`, `h`, `m`) |
| `Style` | `string` | `""` | Estilo inline del contenedor |
## DnzTimeSpanDisplayCompact [#dnztimespandisplaycompact]
El mismo desglose que `DnzTimeSpanDisplay`, pero con numero y etiqueta en tamano pequeno. Atajo comodo para tablas y celdas: ya trae las clases de estilo puestas.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ------------- | ----------- | ------- | ----------------------------------------------------------------- |
| `Value` | `TimeSpan?` | `null` | Duracion a descomponer. Si es `null` muestra `EmptyText` (o nada) |
| `ShowSeconds` | `bool` | `false` | Incluye los segundos en el desglose |
| `EmptyText` | `string` | `""` | Texto a mostrar cuando `Value` es `null` |
| `Style` | `string` | `""` | Estilo inline del contenedor |
## DnzTimeSpanDisplayBadge [#dnztimespandisplaybadge]
El mismo desglose, pero cada parte va dentro de un badge de color. Para resaltar duraciones en cabeceras o resumenes.
```razor
```
**Parametros**
| Parametro | Tipo | Default | Que hace |
| ------------- | ----------- | ------- | ----------------------------------------------------------------- |
| `Value` | `TimeSpan?` | `null` | Duracion a descomponer. Si es `null` muestra `EmptyText` (o nada) |
| `ShowSeconds` | `bool` | `false` | Incluye los segundos en el desglose |
| `EmptyText` | `string` | `""` | Texto a mostrar cuando `Value` es `null` |
| `Style` | `string` | `""` | Estilo inline del contenedor |
***
## Patron tipico: columna de informe -> span [#patron-tipico-columna-de-informe---span]
Estos componentes encajan directamente sobre las filas que devuelve un informe del SDK. Cada columna tiene su span.
### Trae las filas con el SDK [#trae-las-filas-con-el-sdk]
Ejecuta un [informe](/docs/desarrollo/flex/informes) con el [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente) y recorre las filas que te devuelve.
### Pinta cada columna con su span [#pinta-cada-columna-con-su-span]
Importe -> `DnzSpanMoney`. Fecha -> `DnzSpanDate`. Duracion -> `DnzSpanMinutes`. Sin formatear nada a mano.
```razor
@foreach (var fila in informe.Filas)
{
}
```
### Deja que el `null` haga su trabajo [#deja-que-el-null-haga-su-trabajo]
No protejas con `if`: si una columna viene vacia, el span no pinta nada. Menos ruido en tu marcado.
***
## Relacionado [#relacionado]
* [KPIs y metricas](/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas): cuando el dato tipado es la cifra protagonista de una tarjeta.
* [Badges y estados](/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados): para estados y etiquetas de color, no valores numericos.
* [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes): listados donde estos spans son las celdas.
* [Catalogo de componentes](/docs/desarrollo/dotnet/dinazen/componentes): el resto de familias de DinaZen.
* [Intro a DinaZen](/docs/desarrollo/dotnet/dinazen): como encaja la libreria con el SDK.
* [Informes de Dinaup Flex](/docs/desarrollo/flex/informes): de donde salen las columnas que pintas.
* [Cliente Dinaup (SDK .NET)](/docs/desarrollo/dotnet/sdk/cliente): el que trae los datos.
# Diálogos (/docs/desarrollo/dotnet/dinazen/componentes/dialogos)
Todos los diálogos de Dinaup comparten el mismo esqueleto. Lo montas con `DnzDialogLayout` y rellenas tres huecos: cabecera, cuerpo y pie. Para los dos casos más repetidos no montas nada: `DnzConfirmDialog` te resuelve el "¿seguro?" antes de borrar, y `DnzItemPickerDialog` deja al usuario elegir una ficha de un informe.
Los diálogos de DinaZen funcionan sobre el `DialogService` de Radzen. Necesitas el `` colocado en tu layout raíz y el servicio inyectado: `@inject DialogService DialogService`.
## El patrón de diálogo Dinaup [#el-patrón-de-diálogo-dinaup]
Antes de mirar props, quédate con la receta. Un diálogo de edición estándar se monta así:
### Envuelve en DnzDialogLayout [#envuelve-en-dnzdialoglayout]
El componente raíz de tu `.razor` es ``. Te da el grid de tres filas (cabecera / cuerpo con scroll / pie) y se encarga de cerrar.
### Título en TitleContent [#título-en-titlecontent]
Un `` con el título, normalmente condicional según si creas o editas: `@(ID.IsEmpty() ? "Nueva Retención" : "Editar Retención")`.
### Formulario en BodyContent [#formulario-en-bodycontent]
Aquí van los campos. Mientras cargan los datos, pinta un ``; cuando están, el formulario dentro de un `
`.
### Botones en FooterContent [#botones-en-footercontent]
A la derecha: Guardar (Success, `IsBusy=@isBusy`) y Cerrar (Danger, Text). Al guardar bien, cierras con `DialogService.Close(...)`.
Para confirmar algo destructivo (borrar, dar de baja, desvincular) NO montes un `DnzDialogLayout`. Eso es trabajo de `DnzConfirmDialog.OpenAsync`, que ya trae el icono de alerta, el color según gravedad y los dos botones. Te ahorra el diálogo entero.
***
## DnzDialogLayout [#dnzdialoglayout]
Estructura fija de cualquier diálogo: cabecera arriba, cuerpo con scroll en medio y pie abajo. Tú rellenas los tres `RenderFragment` y el componente pone el grid y el botón de cerrar. Solo el cuerpo hace scroll; cabecera y pie quedan anclados.
```razor
@(ID.IsEmpty() ? "Nueva Retención" : "Editar Retención")
@if (cargando)
{
}
else
{
}
```
Si omites `TitleContent` o `FooterContent`, el layout genera una cabecera automática (con `Title` + `Icon` + botón de cerrar) y un pie con un botón "Cerrar" por defecto. Pero el patrón Dinaup es darle tu propio pie con Guardar + Cancelar.
### Cabecera: automática o a medida [#cabecera-automática-o-a-medida]
Si solo pasas `Title` (y opcionalmente `Icon`), el componente pinta la cabecera por ti con el título, el icono y el botón de cerrar. Si necesitas algo más, usa `TitleContent` y mandas tú.
```razor
@* ... *@
```
```razor
Detalle del pedido #1042
@* ... *@
```
### Convención del pie [#convención-del-pie]
El pie de página de Dinaup siempre sigue el mismo orden: Cancelar a la izquierda en estilo discreto, Aceptar a la derecha y destacado.
| Botón | Estilo | Variante |
| ------------ | --------- | ---------------------------------- |
| **Cancelar** | `Danger` | `Text` (discreto) |
| **Aceptar** | `Success` | sólido + `IsBusy` mientras procesa |
Marca el botón de Aceptar con `IsBusy=@variable` durante la operación: el propio botón muestra el spinner y bloquea el doble clic.
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| --------------- | ---------------- | ----------- | ---------------------------------------------------------------------------------- |
| `Title` | `string` | `null` | Texto del título cuando NO pasas `TitleContent`. |
| `Icon` | `string` | `null` | Icono Material Design de la cabecera automática cuando NO pasas `TitleContent`. |
| `TitleContent` | `RenderFragment` | `null` | Cabecera a medida. Si la omites, se genera con `Title` + `Icon` + botón de cerrar. |
| `BodyContent` | `RenderFragment` | `null` | Cuerpo del diálogo (formulario, contenido). Es la única zona con scroll. |
| `FooterContent` | `RenderFragment` | `null` | Pie a medida con los botones. Si lo omites, sale un "Cerrar" por defecto. |
| `ContentStyle` | `string` | `null` | `style` inline para el contenedor del cuerpo (usar con cabeza). |
| `HeaderStyle` | `string` | `null` | `style` inline para la cabecera. |
| `Flat` | `bool` | `false` | `true` deja el diálogo blanco y plano, sin el fondo gris ni los degradados. |
`DnzDialogLayout` expone también `SetWidth(width)` y `SetHeight(height)` por referencia (`@ref`) para ajustar el tamaño del diálogo desde código, y `Cerrar()`, que llama a `DialogService.Close()`. En la mayoría de casos basta con definir el tamaño en las `DialogOptions` al abrir el diálogo.
***
## DnzConfirmDialog [#dnzconfirmdialog]
Diálogo de "¿seguro?" para acciones que no se pueden deshacer. No lo pintas en tu markup: lo abres con el método estático `OpenAsync`, que devuelve `true` si el usuario confirma y `false` si cancela o cierra.
```razor
@code {
async Task EliminarDominioAsync(string dominio)
{
if (await DnzConfirmDialog.OpenAsync(DialogService, $"¿Eliminar el dominio '{dominio}'?", "Eliminar dominio", DnzConfirmSeverity.Danger, "Eliminar") == false) return;
// ... borrar el dominio
NotificationService.Notify(NotificationSeverity.Success, "Dominio eliminado");
}
}
```
El patrón es siempre el mismo: `if (await ...OpenAsync(...) == false) return;` y, si pasa, ejecutas la acción.
**Firma de `OpenAsync`**
```csharp
public static async Task OpenAsync(DialogService dialogService, string message, string title = "Confirmar", DnzConfirmSeverity severity = DnzConfirmSeverity.Warning, string okText = "Confirmar", string cancelText = "Cancelar")
```
Devuelve `Task`: `true` si el usuario pulsa aceptar, `false` si cancela, cierra o pulsa fuera. Solo `dialogService` y `message` son obligatorios; el resto tiene valor por defecto.
| Argumento | Tipo | Por defecto | Qué hace |
| --------------- | -------------------- | ------------- | ------------------------------------------------------------------------------- |
| `dialogService` | `DialogService` | — | El servicio de diálogos de Radzen inyectado. |
| `message` | `string` | — | Texto que explica la consecuencia. Aquí describes qué va a pasar. |
| `title` | `string` | `"Confirmar"` | Título de la cabecera. |
| `severity` | `DnzConfirmSeverity` | `Warning` | Color, icono y estilo del botón de aceptar según gravedad. |
| `okText` | `string` | `"Confirmar"` | Texto del botón de aceptar. Mejor en imperativo: "Eliminar", "Sí, dar de baja". |
| `cancelText` | `string` | `"Cancelar"` | Texto del botón de cancelar. |
### Valores de `DnzConfirmSeverity` [#valores-de-dnzconfirmseverity]
El `severity` cambia el color de acento, el icono y el estilo del botón de aceptar. Elige el que case con la gravedad de la acción.
| Valor | Cuándo usarlo |
| --------- | -------------------------------------------------------------------------- |
| `Info` | Aviso informativo, sin riesgo. |
| `Warning` | Acción que conviene revisar (valor por defecto). |
| `Danger` | Acción destructiva o irreversible (borrar, anular). El botón sale en rojo. |
| `Success` | Confirmación positiva de algo que va a completarse. |
El mensaje es el único parámetro obligatorio de verdad; el resto tiene valores por defecto, pero un `title` y un `okText` claros marcan la diferencia entre un diálogo entendible y un "¿Confirmar? \[Confirmar]" que no dice nada. Para borrados usa siempre `DnzConfirmSeverity.Danger`.
```razor
if (await DnzConfirmDialog.OpenAsync(DialogService, $"¿Eliminar el dominio '{dominio}'?", "Eliminar dominio", DnzConfirmSeverity.Danger, "Eliminar") == false) return;
```
```razor
if (await DnzConfirmDialog.OpenAsync(DialogService, "¿Instalar esta app externa? Tendrá acceso a tus datos.", "Instalar app externa", DnzConfirmSeverity.Warning, "Instalar") == false) return;
```
***
## DnzItemPickerDialog [#dnzitempickerdialog]
Selector de ficha sobre un informe de Dinaup. Abre un diálogo con una tabla buscable y devuelve la fila que elija el usuario, o `null` si cancela. Igual que el de confirmación, se abre con `OpenAsync`.
```razor
@code {
async Task ElegirClienteAsync()
{
var fila = await DnzItemPickerDialog.OpenAsync(DialogService, Client, "clientes");
if (fila == null) return;
// fila es la DinaupDynamicRowDTO seleccionada
var nombre = fila.GetLegible("nombre");
}
}
```
**Firma de `OpenAsync`**
```csharp
public static async Task OpenAsync(DialogService dialogService, DinaupClientC client, string reportId)
```
Devuelve `Task` con la fila seleccionada, o `null` si el usuario cancela o cierra el diálogo. Por dentro monta un `DnzReportView` sobre el informe que le pases y cierra devolviendo la fila al pulsar sobre ella.
| Argumento | Tipo | Por defecto | Qué hace |
| --------------- | --------------- | ----------- | --------------------------------------------------- |
| `dialogService` | `DialogService` | — | El servicio de diálogos de Radzen inyectado. |
| `client` | `DinaupClientC` | — | El cliente Dinaup con el que se ejecuta el informe. |
| `reportId` | `string` | — | Id del informe que alimenta la tabla de selección. |
El diálogo es redimensionable y arrastrable, y muestra hasta 50 filas. El informe (`reportId`) debe existir y devolver las columnas que quieras enseñar; la fila completa vuelve como `DinaupDynamicRowDTO`. Si necesitas el selector embebido en un formulario en vez de un diálogo aparte, mira los [selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores).
***
## Relacionado [#relacionado]
* [Intro a DinaZen](/docs/desarrollo/dotnet/dinazen): la librería de componentes al completo.
* [Índice de componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [Selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores) · [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes)
* [Cookbook de patrones](/docs/desarrollo/dotnet/dinazen/patrones): recetas de diálogos y otros patrones de UI.
* [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente): el cliente que alimenta el selector de ficha.
* [Informes de Dinaup Flex](/docs/desarrollo/flex/informes): los informes que usa `DnzItemPickerDialog`.
# Componentes (/docs/desarrollo/dotnet/dinazen/componentes)
Aquí tienes **DinaZen** partido en familias. Cada una cubre un tipo de necesidad en pantalla; entra por la que te haga falta, no de arriba abajo.
DinaZen no es un catálogo cerrado de "todo lo que existe": es la **selección de piezas que de verdad usas** al construir una app sobre el [SDK .NET](/docs/desarrollo/dotnet/sdk). Los componentes internos del producto (recursos humanos, terminal, asistente) no se documentan aquí porque no están pensados para integrarse fuera de Play.
***
## Elige por necesidad [#elige-por-necesidad]
| Necesito... | Familia |
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Mostrar dinero, fechas, decimales o duraciones con el formato de Dinaup | [Datos tipados (Spans)](/docs/desarrollo/dotnet/dinazen/componentes/datos-tipados) |
| Estructurar la pantalla con cabeceras, tarjetas y bloques | [Tarjetas y layout](/docs/desarrollo/dotnet/dinazen/componentes/tarjetas-y-layout) |
| Señalizar estados con color automático, banderas o deltas | [Badges y estados](/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados) |
| Montar un dashboard con cifras y comparativas | [KPIs y métricas](/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas) |
| Pintar un informe del SDK como tabla, tarjetas o gráfica | [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes) |
| Que el usuario elija un valor, una ficha o un enum | [Selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores) |
| Indicar carga o aplazar contenido pesado | [Carga y rendimiento](/docs/desarrollo/dotnet/dinazen/componentes/carga-y-rendimiento) |
| Capturar datos: ficheros, texto rico, imágenes, pasos | [Inputs y formularios](/docs/desarrollo/dotnet/dinazen/componentes/inputs-y-formularios) |
| Abrir un diálogo o confirmar una acción destructiva | [Diálogos](/docs/desarrollo/dotnet/dinazen/componentes/dialogos) |
| Gantt, código resaltado o rangos de fechas | [Vistas avanzadas](/docs/desarrollo/dotnet/dinazen/componentes/vistas-avanzadas) |
***
## Cómo leer cada página [#cómo-leer-cada-página]
Cada componente trae **una frase de para qué sirve**, un **ejemplo mínimo copiable** y una **tabla de parámetros** sacada directamente del código fuente, no de la memoria. Si un parámetro no aparece en la tabla, es porque es estado interno del componente y no lo necesitas.
Los ejemplos siguen las convenciones Blazor de Dinaup: expresiones con `@` sin comillas, strings literales con comillas, `nameof` para nombres de propiedad y maquetación con clases Bootstrap. Respétalas y tu app se comporta como Play. Detalle en las [guías de estilo C# y Blazor](/docs/desarrollo/dotnet/c-code-style-guidelines).
→ [Volver a DinaZen](/docs/desarrollo/dotnet/dinazen) · [Cookbook de patrones](/docs/desarrollo/dotnet/dinazen/patrones) · [SDK .NET](/docs/desarrollo/dotnet/sdk) · [Informes](/docs/desarrollo/flex/informes)
# Inputs y formularios (/docs/desarrollo/dotnet/dinazen/componentes/inputs-y-formularios)
Lo que el usuario teclea, pega o sube. Esta familia agrupa los inputs autónomos de DinaZen (una caja de búsqueda, un botón de subida, un editor de etiquetas, un recortador de imagen…). A ellos se suma el sistema de formularios dinámicos de **Flex**, que pinta una ficha completa a partir de un GUID de sección. Recurre a ella cuando montas una pantalla de alta o edición y no quieres pelearte con cada `` a mano.
Casi todos son componentes de **dos vías**: les pasas el dato con `Value` y te avisan del cambio con `ValueChanged`. En Razor eso se escribe con `@bind-Value=@Modelo.Campo`.
Los que suben ficheros (`DnzFileUploaderButton`, `DnzImageEditor`) hablan con un **endpoint de presign** que firma la subida directa a S3. El fichero no viaja por SignalR. Por defecto apuntan a `/file/upload/sign`.
***
## DnzSearchInput [#dnzsearchinput]
Caja de búsqueda con icono de lupa y **debounce de 500 ms**: no dispara en cada tecla, espera a que el usuario pare de escribir. Ideal para filtrar una tabla o una lista sin machacar el servidor.
```razor
@code {
private string _filtro = "";
private async Task OnBuscar(string texto)
{
_filtro = texto;
await RecargarListaAsync();
}
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------------- | ----------------------- | ------------- | ------------------------------------------------------------------- |
| `Value` | `string` | | Texto actual del campo. |
| `Placeholder` | `string` | `"Buscar..."` | Texto guía cuando está vacío. |
| `BounceValueChanged` | `EventCallback` | | Se dispara 500 ms después de la última tecla, con el texto escrito. |
| `Class` | `string` | `""` | Clases CSS del contenedor. |
| `Style` | `string` | `""` | Estilo inline del contenedor. |
Usa `BounceValueChanged`, no `ValueChanged`: la gracia de este componente es que ya trae el debounce hecho. Si enganchas tu recarga ahí, solo se ejecuta cuando el usuario deja de teclear.
Los atributos extra que pongas (por ejemplo `autofocus` o `maxlength`) se pasan tal cual al elemento `` raíz.
***
## DnzFileUploaderButton [#dnzfileuploaderbutton]
Botón que abre el selector nativo, sube los ficheros a S3 (vía presign + Uppy) y te devuelve los `DinaupFileDTO` ya registrados en Dinaup. Si subes una sola imagen, abre antes el editor de imagen.
```razor
@code {
private async Task OnFicherosSubidos(List ficheros)
{
foreach (var f in ficheros)
Factura.Adjuntos.Add(f);
await InvokeAsync(StateHasChanged);
}
private void OnErrorSubida(string mensaje)
{
NotificationService.Notify(NotificationSeverity.Error, "Subida", mensaje);
}
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------------- | ------------------------------------ | --------------------- | ------------------------------------------------------------------------------------------------- |
| `Client` | `DinaupClientC` | | Cliente que registra el fichero subido (`File_UploadURLAsync`). Necesario en modo por lotes. |
| `PresignEndpoint` | `string` | `"/file/upload/sign"` | Endpoint que firma la subida a S3. |
| `OnFilesUploaded` | `EventCallback>` | | Se dispara cuando termina el lote, con los ficheros ya registrados. |
| `OnEachFileUploaded` | `EventCallback` | | Se dispara por cada fichero subido. Si lo enganchas, tú gestionas el registro y se salta el lote. |
| `AcceptExtensions` | `string[]` | `[]` | Extensiones permitidas (`.pdf`, `.png`...). Vacío = todas. |
| `MaxSizeBytes` | `long` | `157286400` (150 MB) | Tamaño máximo por fichero. |
| `MaxFiles` | `int` | `1000` | Número máximo de ficheros por subida. |
| `Disabled` | `bool` | `false` | Inhabilita el botón. |
| `ButtonText` | `string` | | Texto del botón. |
| `ButtonIcon` | `string` | `"attach_file"` | Icono del botón. |
| `ButtonStyle` | `ButtonStyle` | `Secondary` | Estilo Radzen del botón. |
| `ButtonSize` | `ButtonSize` | `Small` | Tamaño Radzen del botón. |
| `ButtonVariant` | `Variant` | `Outlined` | Variante visual del botón. |
| `UseDashboard` | `bool` | `false` | Abre el dashboard de Uppy (drag\&drop) en vez de un botón simple. |
| `Note` | `string` | | Nota opcional para el dashboard. |
| `EditBeforeUpload` | `bool` | `true` | Si subes 1 imagen, la pasa por el editor antes de subir. |
| `OnError` | `EventCallback` | | Se dispara con el mensaje cuando falla una subida o el registro. |
`Client` es opcional, pero si no lo pasas en modo por lotes, los ficheros suben a S3 sin registrarse en Dinaup. Para registrar manualmente engancha `OnEachFileUploaded` y haz tú la llamada.
***
## DnzFileName [#dnzfilename]
Pinta un fichero **ya subido**: icono según su extensión, nombre, tamaño y un botón de descarga o una acción propia. Es lo que enseñas en una lista de adjuntos; no sube nada.
```razor
@foreach (var adjunto in Factura.Adjuntos)
{
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------------- | --------------- | --------------- | --------------------------------------------------------- |
| `DnzFileNameDisplay` | `string` | `""` | Nombre del fichero. La extensión decide el icono. |
| `FileSize` | `long?` | | Tamaño en bytes. Se formatea solo (KB, MB...). |
| `DownloadURL` | `string` | `""` | URL de descarga. Si la pasas, pinta el botón de descarga. |
| `OnClick` | `EventCallback` | | Acción propia. Solo se usa si no hay `DownloadURL`. |
| `OnClick_Icon` | `string` | `"arrow_right"` | Icono del botón de la acción propia. |
| `Horizontal` | `bool` | `false` | Disposición en línea, más compacta. |
| `IsCompact` | `bool` | `false` | Variante mínima (icono + nombre + tamaño en una fila). |
***
## DnzHtmlEditor [#dnzhtmleditor]
Editor de texto rico (Radzen HtmlEditor) con la barra de herramientas de Dinaup. Para descripciones largas, plantillas de email o notas de un cliente.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------- | ----------------------- | --------------------- | ------------------------------------------------------------------ |
| `Value` | `string` | | HTML editado. Úsalo con `@bind-Value`. |
| `ValueChanged` | `EventCallback` | | Se dispara al cambiar el contenido. |
| `Context` | `string` | `""` | Contexto que recibe la barra (placeholders/variables disponibles). |
| `EditorStyle` | `string` | `"min-height:300px;"` | Estilo del área de edición (altura mínima, etc.). |
| `UploadUrl` | `string` | `"upload/image"` | Endpoint donde sube las imágenes pegadas/insertadas. |
| `Class` | `string` | `""` | Clases CSS del contenedor. |
| `Style` | `string` | `""` | Estilo inline del contenedor. |
***
## DnzImageEditor [#dnzimageeditor]
Editor de imagen completo embebido: recorte, rotación, volteo, ajustes, mejora automática y herramientas externas (`IDnzImageTool`). Trabaja sobre una URL o sobre `byte[]`. Lo normal es usarlo dentro del diálogo (ver abajo), pero puedes incrustarlo suelto.
```razor
@code {
private DnzImageEditor _editor;
private async Task Guardar()
{
var bytes = await _editor.GetResultBytesAsync();
// ...persistir bytes
}
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | ---------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------- |
| `ImageUrl` | `string` | | URL de la imagen a cargar. |
| `ImageBytes` | `byte[]` | | Imagen en bytes, alternativa a `ImageUrl`. |
| `PresignEndpoint` | `string` | | Endpoint de presign para las herramientas que hacen round-trip por S3 (evita pasar la imagen por SignalR). |
| `ExternalTools` | `IEnumerable` | | Herramientas extra que se añaden a la barra (p. ej. quitar fondo). |
| `OnSave` | `EventCallback` | | Se dispara al guardar, con los bytes del resultado. |
| `OnCancel` | `EventCallback` | | Se dispara al cancelar. |
| `Style` | `string` | | Estilo inline (sobre todo la altura). |
Para sacar el resultado tienes dos métodos en el `@ref`: `GetResultBytesAsync()` devuelve el `byte[]` del canvas, y `UploadResultToS3Async(endpoint)` lo sube directo a S3 y te da la URL. Úsalos desde el padre o el diálogo.
***
## DnzImageEditorDialog [#dnzimageeditordialog]
El editor de imagen ya envuelto en un diálogo modal con Aceptar/Cerrar. No lo pones en el markup: lo abres con un método estático y te devuelve el resultado. Es la forma recomendada de editar imágenes.
```razor
@code {
private async Task EditarFoto()
{
var bytes = await DnzImageEditorDialog.OpenAsync(DialogService, imageUrl: Producto.FotoUrl);
if (bytes.IsNull()) return; // cancelado
// ...persistir bytes
}
}
```
```razor
@code {
private async Task EditarYSubir()
{
var result = await DnzImageEditorDialog.OpenAndUploadToS3Async(DialogService, "/file/upload/sign", imageUrl: Producto.FotoUrl);
if (result.IsNull()) return; // cancelado
Producto.FotoUrl = result.Url;
}
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | -------- | ----------- | ------------------------------------------------------------------------------------- |
| `ImageUrl` | `string` | | URL de la imagen a editar. |
| `ImageBytes` | `byte[]` | | Imagen en bytes, alternativa a `ImageUrl`. |
| `PresignEndpoint` | `string` | | Endpoint de presign. Si lo pasas, Aceptar sube a S3 y devuelve `PresignUploadResult`. |
**Métodos estáticos**
| Método estático | Devuelve | Para qué |
| ------------------------------------------------------------------ | -------------------------------- | ----------------------------------------------------------------- |
| `OpenAsync(dialogService, imageUrl, imageBytes)` | `byte[]` (o `null` si cancela) | Edita y devuelve los bytes del resultado. |
| `OpenAndUploadToS3Async(dialogService, presignEndpoint, imageUrl)` | `PresignUploadResult` (o `null`) | Edita, sube a S3 y devuelve la URL final. Sin imagen por SignalR. |
***
## DnzTagListEditor [#dnztaglisteditor]
Editor de una lista de etiquetas (`List`). Se escribe y se pulsa Enter para añadir, click en la X para quitar. Admite pegar varias separadas por coma o punto y coma, validación por valor y transformación.
```razor
v.Trim().ToLower()) />
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | ----------------------------- | --------------- | -------------------------------------------------------------------------------------------- |
| `Value` | `List` | `new()` | La lista de etiquetas. Úsalo con `@bind-Value`. |
| `ValueChanged` | `EventCallback>` | | Se dispara al añadir o quitar una etiqueta. |
| `Title` | `string` | `""` | Título de la cabecera. Vacío = sin cabecera ni botón Clear. |
| `Icon` | `string` | `""` | Icono junto al título. |
| `Placeholder` | `string` | `"Add item..."` | Texto guía del input. |
| `EmptyText` | `string` | `"No items"` | Texto cuando no hay etiquetas. |
| `ReadOnly` | `bool` | `false` | Solo lectura (oculta el input y las X). |
| `Validator` | `Func` | | Devuelve un mensaje de error si el valor no vale, o vacío si vale. |
| `Transform` | `Func` | | Transforma cada valor antes de añadirlo (Trim, ToLower...). |
| `AllowMultiPaste` | `bool` | `true` | Permite pegar varias etiquetas de golpe separadas por coma, `;`, salto de línea o tabulador. |
| `Class` | `string` | `""` | Clases CSS del contenedor. |
| `Style` | `string` | `""` | Estilo inline del contenedor. |
***
## DnzJsonKVEditor [#dnzjsonkveditor]
Editor de pares clave/valor que entra y sale como JSON (`string`). Para metadatos sueltos, configuración de una integración, cabeceras HTTP... Trae copiar, pegar JSON e importar. Usa notación con punto (`app.apikey`) para agrupar visualmente.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------- | ----------------------- | ----------- | ------------------------------------------------------------------------- |
| `Value` | `string` | `"{}"` | El JSON con los pares. Úsalo con `@bind-Value`. |
| `ValueChanged` | `EventCallback` | | Se dispara al editar, añadir o quitar un par. Devuelve el JSON indentado. |
| `ReadOnly` | `bool` | `false` | Solo lectura. |
| `Class` | `string` | `""` | Clases CSS del contenedor. |
| `Style` | `string` | `""` | Estilo inline del contenedor. |
***
## DnzStepper [#dnzstepper]
Lista vertical de pasos numerados con la línea que los une. Es **presentacional**: muestra un proceso ("cómo empezar", "qué pasa después"), no controla un wizard ni navega. Los pasos van dentro como `DnzStepperStep`.
```razor
Crea la factura
Elige cliente y añade las líneas.
Revisa los importes
Comprueba bases, IVA y total.
Emite y envía
Genera el PDF y mándalo al cliente.
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------- | ---------------- | ----------- | ------------------------------------------- |
| `ChildContent` | `RenderFragment` | | Los `DnzStepperStep` que componen la lista. |
***
## DnzStepperStep [#dnzstepperstep]
Un paso suelto dentro del `DnzStepper`: el círculo numerado y el contenido al lado.
```razor
Configura el almacén
Define ubicaciones y stock inicial.
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------- | ---------------- | ----------- | -------------------------------------------- |
| `Index` | `int` | `0` | Número que se pinta en el círculo. |
| `ChildContent` | `RenderFragment` | | Contenido del paso (título, descripción...). |
***
## DnzFormView [#dnzformview]
El **formulario dinámico de Flex**. No declaras campos: le pasas el GUID de una sección y el cliente, y pinta la ficha completa (cabecera, pestañas, controles, botones, guardar/cancelar) tal cual está definida en Dinaup. Es lo que usas para dar de alta o editar un registro de cualquier sección sin escribir un solo ``.
```razor
@code {
private void OnFichaCerrada(DinaupFormResult result)
{
if (result.Reason == DinaupFormCloseReason.Saved)
RecargarLista();
}
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ------------------- | ---------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------- |
| `Client` | `DinaupClientC` | | **Obligatorio.** Cliente DinaupSL ya inicializado. |
| `SectionId` | `string` | `""` | **Obligatorio.** GUID de la sección a cargar. |
| `DatoId` | `string` | `""` | GUID del registro a editar. Vacío = formulario de alta nuevo. |
| `UserId` | `string` | `""` | ID del usuario (opcional). |
| `OnFormatearCodigo` | `Func>` | | Callback para formatear códigos contables (subcuenta). |
| `OnClosed` | `EventCallback` | | Se dispara al cerrar el formulario, con el resultado (guardado, cancelado...). |
| `OnAnnotationOpen` | `EventCallback` | | Se dispara al abrir comentarios/archivos/galería. La app host puede personalizar el diálogo. |
| `WindowId` | `string` | | ID de la ventana flotante que lo contiene. Si tiene valor, el form vive dentro de una ventana. |
| `PreFillValues` | `Dictionary` | | Valores a precargar en un alta nueva (clave de campo → valor). Solo si `DatoId` está vacío. |
| `PreFillList` | `List>` | | Filas a precargar en los campos de lista de un alta nueva. Solo si `DatoId` está vacío. |
| `AttachFileId` | `Guid` | | ID de un fichero a adjuntar automáticamente al guardar. |
Los formularios de Flex requieren un **ancho mínimo de 1.000 px**. No hay versión responsive más pequeña: por debajo aparece scroll horizontal. Para pantallas pequeñas, escala el contenedor padre con `zoom` o `transform: scale(...)`.
En vez de incrustarlo en el markup, lo habitual es abrirlo como modal o como ventana flotante con sus helpers estáticos:
```razor
@code {
private async Task EditarCliente(string clienteId)
{
var result = await DnzFormView.OpenAsync(DialogService, Cliente, SeccionClientesId, clienteId);
if (result.Reason == DinaupFormCloseReason.Saved)
RecargarLista();
}
}
```
Firma: `OpenAsync(DialogService dialogService, DinaupClientC client, string sectionId, string datoId = "", string title = "", string width = "1000px", string height = "85%")` → devuelve `Task`.
```razor
@code {
private void AbrirFichaFlotante(string clienteId)
{
DnzFormView.OpenAsWindow(WindowManager, Cliente, SeccionClientesId, clienteId, title: "Cliente");
}
}
```
Firma: `OpenAsWindow(DnzWindowManagerService windowManager, DinaupClientC client, string sectionId, string datoId = "", string title = "", string icon = "")` → devuelve el `windowId` (`string`).
***
## DnzFormTab [#dnzformtab]
Es la **pieza interna** que `DnzFormView` usa para renderizar cada pestaña del formulario: el título, los contenedores, los controles y los botones de esa pestaña. No lo montas tú directamente; lo gestiona `DnzFormView`. Lo listamos para que, si depuras un formulario de Flex, sepas qué estás viendo en el árbol de componentes.
```razor
@* DnzFormView monta esto por cada pestaña; no se usa suelto *@
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------------------------- | ------------------------------------------ | ----------- | ----------------------------------------------------------------------------- |
| `Tab` | `VirtualFormDTO.Tab` | | **Obligatorio.** La pestaña a renderizar (controles, contenedores y botones). |
| `Client` | `DinaupClientC` | | **Obligatorio.** Cliente DinaupSL ya inicializado. |
| `OnTabChanged` | `EventCallback` | | Se dispara cuando cambia un control de la pestaña. |
| `OnButtonClick` | `EventCallback` | | Se dispara al pulsar un botón de la pestaña. |
| `OnDeleteItemPrimaryList` | `EventCallback` | | Se dispara al borrar un ítem de la lista principal. |
| `OnMostrarDialogRequiereGuardar` | `EventCallback` | | Se dispara cuando una acción exige guardar primero. |
| `OnOpenListItem` | `EventCallback` | | Se dispara al abrir un ítem de una lista. |
| `OnAddItem` | `EventCallback` | | Se dispara al añadir un ítem a una lista. |
| `OnFormatearCodigo` | `Func>` | | Callback para formatear códigos contables. |
***
## Relacionado [#relacionado]
* [Selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores): elegir opciones (enum, memoria o catálogo remoto), con `DnzSearchInput` por dentro.
* [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes): pintar un informe del SDK como tabla, tarjetas o gráfica.
* [Cookbook de patrones](/docs/desarrollo/dotnet/dinazen/patrones): recetas que combinan estos inputs con el SDK.
* [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente): conexión, `WriteOperations` y `File_UploadURLAsync` para persistir lo que capturan estos inputs.
* [Informes de Dinaup Flex](/docs/desarrollo/flex/informes): el origen de datos que rellenan las tablas y los formularios.
→ [Volver a Componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [DinaZen](/docs/desarrollo/dotnet/dinazen) · [SDK .NET](/docs/desarrollo/dotnet/sdk)
# KPIs y métricas (/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas)
Para un cuadro de mando lo que manda es la cifra: número grande, etiqueta corta y, si puedes, una tendencia que diga si va bien o mal. Esta familia te da las piezas para montar ese panel sin pelearte con HTML. La tarjeta destacada la pones con `DnzKpiCard`. Cuando quieres una tira compacta de varios números (cabeceras, pies de ficha) tiras de `DnzKpiInline`. Para agrupar varias tarjetas en rejilla responsive usas `DnzKpiRow`. Para grupos de estadísticas dentro de una card, `DnzStatsDisplay` o `DnzStatItem`. Y para comparar tiempo planificado contra real, `DnzTimeComparisonDisplay`.
## Qué componente uso [#qué-componente-uso]
| Quieres... | Componente |
| ------------------------------------------------------------ | ----------------------------------- |
| Una cifra destacada, con icono, color y tendencia | `DnzKpiCard` |
| Varias tarjetas KPI en rejilla que se adapta sola | `DnzKpiRow` (envuelve `DnzKpiCard`) |
| Una tira horizontal compacta de números (estilo GitHub) | `DnzKpiInline` |
| Un grupo de estadísticas valor + etiqueta dentro de una card | `DnzStatsDisplay` |
| Un stat suelto con icono y contenido libre como valor | `DnzStatItem` |
| Comparar tiempo previsto contra tiempo real (semáforo) | `DnzTimeComparisonDisplay` |
| Resumir totales de un informe Flex automáticamente | `DnzSummaryBar` |
Casi todos reciben la cifra **ya formateada como texto** (`"1.250 €"`, `"42"`). El separador de miles, el símbolo de moneda y los decimales los pones tú antes. La excepción son los deltas (`DeltaPercent`), que entran como `decimal` para que el componente elija color y flecha solo.
Regla rápida: si vas a poner más de una tarjeta, mete los `DnzKpiCard` dentro de un `DnzKpiRow` y olvídate del grid. La rejilla se ajusta al ancho disponible con `MinCardWidth`.
***
## DnzKpiCard [#dnzkpicard]
La tarjeta de un KPI: título, cifra grande, icono opcional, color, badge de comparativa porcentual y mini-gráfico de tendencia. Tiene tres modos según cómo la configures.
Cifra, título, delta y descripción en una card sobria.
```razor
```
Con `IsCompact=true`, una versión mini de una sola línea, para meter muchas en poco espacio.
```razor
```
Con `HighlightColor`, la card se pinta entera con un degradado y texto en blanco.
```razor
```
El delta se colorea solo: positivo en verde, negativo en rojo, cero en gris, con su flecha. Si tu métrica es "cuanto menos mejor" (gastos, tiempos), pon `DeltaInvertColors=true` para que bajar salga en verde.
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| ------------------- | -------------------- | ----------- | ---------------------------------------------------------------- |
| `Title` | `string` | `""` | Etiqueta de la cifra. |
| `Value` | `string` | `""` | La cifra en sí, ya formateada. |
| `Icon` | `string` | `""` | Icono Material. Vacío = sin icono. |
| `Color` | `string` | `"black"` | Color del texto y del icono (modo estándar/compacto). |
| `Description` | `string` | `""` | Texto pequeño bajo la cifra (modo estándar). |
| `IsCompact` | `bool` | `false` | Variante compacta de una línea. |
| `HighlightColor` | `HighlightColorType` | `Undefined` | Degradado de fondo. `Auto` deduce verde/rojo según el valor. |
| `DeltaPercent` | `decimal?` | | Porcentaje de cambio. Pinta badge con flecha y signo. |
| `DeltaLabel` | `string` | `""` | Texto junto al delta, ej. "vs mes anterior". |
| `DeltaInvertColors` | `bool` | `false` | Invierte verde/rojo (útil cuando subir es malo, ej. gastos). |
| `TrendContent` | `RenderFragment` | | Contenido libre para un mini-gráfico de tendencia (sparkline). |
| `ButtonText` | `string` | `""` | Si lo rellenas, pinta un botón de acción al pie (modo estándar). |
| `ButtonIcon` | `string` | `""` | Icono de ese botón. |
| `OnClick` | `EventCallback` | | Se dispara al pulsar el botón. |
| `Tooltip` | `string` | `""` | Tooltip al pasar el ratón por la card. |
| `Variant` | `Radzen.Variant` | `Filled` | Variante de la card base (modo estándar/compacto). |
| `Class` | `string` | `""` | Clases CSS extra de la card. |
| `Style` | `string` | `""` | Estilo inline extra de la card. |
`HighlightColorType` admite: `Undefined`, `Auto`, `Red`, `Blue`, `Green`, `Yellow`, `Orange`, `Purple`, `Black`, `White`, `Gray`.
`HighlightColorType.Auto` mira los dígitos del `Value`: si hay un número distinto de cero lo pinta verde, y rojo si además hay un signo menos. Si tu cifra lleva formato raro (separadores, símbolos), mejor fija el color a mano.
***
## DnzKpiRow [#dnzkpirow]
Contenedor en rejilla responsive para tus `DnzKpiCard`. Mete dentro cuantas tarjetas quieras y el grid se reparte solo según el ancho mínimo que le digas. No tienes que tocar el grid: las columnas se ajustan al ancho disponible y bajan de línea cuando no caben.
```razor
```
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| -------------- | ---------------- | ------- | ------------------------------------------------------------------- |
| `ChildContent` | `RenderFragment` | | Las tarjetas KPI que van dentro de la rejilla. |
| `MinCardWidth` | `int` | `220` | Ancho mínimo (px) de cada tarjeta. Define cuántas caben por fila. |
| `Class` | `string` | `""` | Clases CSS extra del contenedor. |
| `Style` | `string` | `""` | Estilo inline extra (se concatena con la variable de ancho mínimo). |
***
## DnzKpiInline [#dnzkpiinline]
Tira horizontal compacta de varios números, separados por punto, barra o pipe (estilo GitHub). Ideal para cabeceras de ficha, pies de card o líneas de meta-información. Los items se pasan como lista, no como markup hijo.
```razor
@code {
List KpiItems = new()
{
new("Horas oficiales", "40h 00m", Icon: "calendar_month"),
new("Realizado", "38h 30m", Icon: "work", ValueColor: "#d97706"),
new("Horas extra", "2h 15m", Icon: "more_time"),
};
}
```
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| ----------- | ----------------- | ----------- | ------------------------------------------------------------------------- |
| `Items` | `List` | `new()` | Los números a pintar. Ver `ItemModel` abajo. |
| `Separator` | `SeparatorType` | `MiddleDot` | Separador entre items: `None`, `MiddleDot` (·), `Pipe` (\|), `Slash` (/). |
| `Class` | `string` | `""` | Clases CSS extra del contenedor. |
| `Style` | `string` | `""` | Estilo inline extra del contenedor. |
`ItemModel` es un record con estos campos (todos menos los dos primeros son opcionales): `Label`, `Value`, `Icon`, `ValueColor`, `IconColor`, `Tooltip`. Si `IconColor` va vacío, el icono hereda el color del valor.
***
## DnzStatItem [#dnzstatitem]
Un stat suelto: icono a la izquierda, valor grande y etiqueta debajo. A diferencia de `DnzKpiCard`, el valor es contenido libre (`ChildContent`), así que puedes meter un `DnzSpanMoney`, un badge o lo que necesites.
```razor
1.23489
```
El `Icon` acepta tanto un nombre de icono Material como una ruta de imagen: si empieza por `/` o `http`, lo pinta como ``.
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| -------------- | ---------------- | --------------------- | ---------------------------------------------------------------- |
| `ChildContent` | `RenderFragment` | | El valor, como contenido libre. Obligatorio. |
| `Label` | `string` | `""` | Etiqueta bajo el valor. |
| `Icon` | `string` | `""` | Icono Material, o una URL (`/...` o `http...`) para imagen. |
| `IconColor` | `string` | `"var(--rz-primary)"` | Color del icono Material. |
| `IconSize` | `string` | `"40px"` | Tamaño del icono (CSS). |
| `ValueColor` | `string` | `""` | Color del valor. Vacío = color del tema. |
| `ValueSize` | `string` | `"fs-3"` | Clase Bootstrap de tamaño del valor (`fs-1`, `fs-3`, `fs-5`...). |
| `Visible` | `bool` | `true` | Si es `false`, no se renderiza nada. |
| `Class` | `string` | `""` | Clases CSS extra del contenedor. |
***
## DnzStatsDisplay [#dnzstatsdisplay]
Grupo de estadísticas valor + etiqueta + unidad dentro de una card, repartidas en horizontal. Le pasas una lista de `StatisticModel` como datos (no como hijos) y él se encarga del layout, pintando una celda por cada métrica.
```razor
@code {
private List stats = new()
{
new() { Value = "12", Label = "Usuarios" },
new() { Value = "45,3", Label = "Base de datos", Unit = "GB" },
new() { Value = "8,1", Label = "Archivos", Unit = "GB" },
};
}
```
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| ------------ | ---------------------- | ------- | ----------------------------------------------------------- |
| `Statistics` | `List` | `new()` | Las estadísticas a pintar. Requerido (`EditorRequired`). |
| `Variant` | `Variant` | | Variante de la card base (`Text`, `Filled`, `Outlined`...). |
`StatisticModel` tiene tres campos: `Value` (string), `Label` (string) y `Unit` (string).
### DnzStatsDisplay.Item (subcomponente) [#dnzstatsdisplayitem-subcomponente]
Es la celda que pinta cada cifra individual: valor grande, unidad más pequeña al lado y etiqueta debajo. **No lo usas directamente**: `DnzStatsDisplay` lo instancia por ti, uno por cada elemento de `Statistics`. Lo documentamos para que veas qué recibe cada celda.
Patrón padre/hijo: el padre (`DnzStatsDisplay`) recorre la lista `Statistics` y, por cada métrica, renderiza un hijo (`DnzStatsDisplay.Item`) con `@key=@stat` para que Blazor reutilice bien las celdas. Tú solo tocas el padre y le das la lista; el hijo es detalle interno.
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| --------- | -------- | ------- | -------------------------------------------------- |
| `Value` | `string` | `""` | El número grande de la celda. |
| `Label` | `string` | `""` | Etiqueta debajo del valor. |
| `Unit` | `string` | `""` | Unidad pequeña junto al valor. Vacía = sin unidad. |
***
## DnzTimeComparisonDisplay [#dnztimecomparisondisplay]
Compara tiempo planificado contra tiempo real y lo pinta con color de semáforo: verde si vas holgado, amarillo si te acercas al límite, rojo si te pasas. Pensado para tareas, partes de trabajo y presupuestos de horas. Los tiempos entran en **minutos** y se formatean solos a `h`/`m`.
```razor
```
Eso pinta "8h 30m / 8h" con badge "+30m" en rojo (te has pasado) y barra de progreso. Variantes:
Con barra de progreso, badge de diferencia e icono de estado. El modo por defecto.
```razor
```
Con `Compact=true`, todo en una línea para meterlo en una fila de tabla o un pie de card.
```razor
```
Si no pasas `PlannedTime` (queda en 0), pinta solo el tiempo real sin comparativa ni barra.
```razor
```
El color y el icono de estado salen solos del porcentaje: verde hasta el 80%, amarillo entre 80% y 100%, rojo al pasarse o si el tiempo real es negativo.
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| ----------------- | --------- | ------- | ----------------------------------------------------------------- |
| `PlannedTime` | `decimal` | `0` | Tiempo planificado, en minutos. En `0` desactiva la comparativa. |
| `ActualTime` | `decimal` | `0` | Tiempo real consumido, en minutos. |
| `ShowProgressBar` | `bool` | `true` | Pinta la barra de progreso (solo si hay tiempo planificado). |
| `ShowDiff` | `bool` | `true` | Muestra el badge con la diferencia (`+30m`, `-1h 10m`, `=`). |
| `Compact` | `bool` | `false` | Modo de una sola línea. |
| `Label` | `string` | `""` | Etiqueta encima de la comparativa. También aparece en el tooltip. |
Si tanto `PlannedTime` como `ActualTime` son 0, el componente **no pinta nada**. Es deliberado: una tarea sin tiempo ni estimación no aporta a un panel.
***
## DnzSummaryBar [#dnzsummarybar]
Barra de totales para informes Flex. No le pasas datos a mano: lee el `ReportContext` de la cascada y suma las columnas de dinero, numéricas, minutos, booleanas (cuenta los `true`, ej. `5 / 20`) y el rango de la fecha principal. La pones dentro de un informe y se rellena sola.
```razor
```
**Parámetros**
| Parámetro | Tipo | Default | Qué hace |
| --------- | --------------- | ------- | ------------------------------------------------------------------------------------------------------- |
| `Context` | `ReportContext` | | Llega por `[CascadingParameter]`. No se pasa como atributo: lo aporta el informe que envuelve la barra. |
`DnzSummaryBar` solo aparece si el contexto trae filas. Si el informe está vacío no pinta nada, así que no tienes que esconderlo tú. Más sobre informes en [Informes (Flex)](/docs/desarrollo/flex/informes).
***
## Relacionado [#relacionado]
Ver tambien: [Índice de componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [Intro DinaZen](/docs/desarrollo/dotnet/dinazen) · [Cookbook de patrones](/docs/desarrollo/dotnet/dinazen/patrones) · [Badges y estados](/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados) · [Tarjetas y layout](/docs/desarrollo/dotnet/dinazen/componentes/tarjetas-y-layout) · [Tablas e informes](/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes) · [Informes (Flex)](/docs/desarrollo/flex/informes) · [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente)
# Selectores (/docs/desarrollo/dotnet/dinazen/componentes/selectores)
Casi todo lo que el usuario "elige" en Dinaup pasa por uno de estos componentes. La pregunta de fondo siempre es la misma: ¿de dónde salen las opciones? De ahí cuelga todo lo demás. No fuerces un componente equivocado: cada uno está pensado para un origen de datos distinto y mezclarlos te trae problemas de rendimiento o de UX.
Antes de mirar props, decide cuál te toca con la regla de los 3 segundos.
## Regla de los 3 segundos [#regla-de-los-3-segundos]
| Lo que tienes | Componente | Por qué |
| --------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------ |
| Un `enum` de C# | [`DnzEnumDropDown`](#dnzenumdropdown) | Las opciones SON el enum. Cero datos, cero query. |
| Una lista corta ya cargada en memoria (impuestos, almacenes, estados) | [`DnzDataGridDropDown`](#dnzdatagriddropdown) | Le pasas la colección y filtra en cliente. Sin ir al servidor. |
| Buscar/elegir una ficha de un catálogo grande (clientes, productos) | [`DnzRowSelector`](#dnzrowselector) | No le pasas datos: consulta un informe remoto con búsqueda y paginación. |
Si la lista cabe en memoria sin sudar (decenas, pocos cientos), `DnzDataGridDropDown`. Si es un catálogo que crece sin límite y vive en el servidor, `DnzRowSelector`. El primero te ahorra una consulta; el segundo te evita cargar 10.000 filas en el navegador para elegir una.
Los tres últimos de esta página (`DnzDropDown`, `DnzSearchInput`, `DnzItemPickerDialog`) son piezas de apoyo: el dropdown de datos en su versión cruda, la caja de búsqueda con debounce que monta el selector remoto por dentro, y un picker en diálogo para cuando no quieres un desplegable embebido sino una ventana de selección.
***
## DnzEnumDropDown [#dnzenumdropdown]
Desplegable directo sobre un `enum` de C#. No le pasas opciones: las saca del propio tipo, y usa el `[Display(Name=...)]` de cada valor como texto visible si lo tiene.
```razor
```
```razor
@code {
EstadoPedidoE estadoPedido = EstadoPedidoE.Pendiente;
}
```
| Parámetro | Tipo | Default | Para qué |
| -------------- | ---------------------- | --------------- | ------------------------------------------------------------- |
| `Value` | `TEnum` | | Valor seleccionado. Úsalo con `@bind-Value`. |
| `ValueChanged` | `EventCallback` | | Se dispara al cambiar la selección (lo cablea `@bind-Value`). |
| `Placeholder` | `string` | `""` | Texto cuando no hay nada elegido. |
| `Disabled` | `bool` | `false` | Bloquea el control. |
| `Style` | `string` | `"width:200px"` | Estilo inline del desplegable, normalmente el ancho. |
| `Name` | `string` | `""` | Nombre del campo (para formularios/validación Radzen). |
El texto de cada opción sale de `[Display(Name = "Pendiente de pago")]` sobre el valor del enum. Sin el atributo, se muestra el nombre técnico del miembro. Decóralo en la definición del enum y aquí no tocas nada.
***
## DnzDataGridDropDown [#dnzdatagriddropdown]
Selector para una lista que ya tienes en memoria. Le pasas la colección por `Data`, le dices qué propiedad pintar con `TextProperty`, y él monta un desplegable con buscador, columna y acciones (limpiar, abrir ficha, añadir). El tipo `T` tiene que implementar `IDinaupRow`.
```razor
await Recalcular()) Style="width:100%" />
```
Con color por estado (badge automático) y columnas a medida:
```razor
```
| Parámetro | Tipo | Default | Para qué |
| --------------- | ------------------------- | --------------- | ----------------------------------------------------------------------- |
| `Data` | `IEnumerable` | `new List()` | La colección en memoria a elegir. |
| `Value` | `T` | | Fila seleccionada. Úsalo con `@bind-Value`. |
| `ValueChanged` | `EventCallback` | | Se dispara al cambiar la selección. |
| `TextProperty` | `string` | | Nombre de la propiedad a mostrar. **Obligatorio**; usa `@nameof(...)`. |
| `Label` | `string` | | Etiqueta del campo. |
| `ColorProperty` | `string` | | Propiedad con el estilo de color; pinta la opción como badge. |
| `IconoProperty` | `string` | | Propiedad que aporta el icono de cada opción. |
| `IsRequired` | `bool` | `false` | Marca visual de obligatorio si no hay valor. |
| `Disabled` | `bool` | `false` | Bloquea el control. |
| `Width` | `string` | `"280px"` | Ancho del campo. |
| `Style` | `string` | | Estilo inline adicional del campo. |
| `Icon` | `string` | | Icono al inicio del campo. |
| `OpenInWindow` | `bool` | `true` | Permite abrir la ficha del seleccionado en ventana (necesita `Client`). |
| `Client` | `DinaupClientC` | | Cliente para abrir la ficha en ventana. |
| `OnAdd` | `EventCallback` | | Se dispara al pulsar el "+" cuando no hay nada seleccionado. |
| `OnRemove` | `EventCallback` | | Se dispara al limpiar. Si no lo cableas, limpia el valor solo. |
| `OnOpen` | `EventCallback` | | Se dispara al pulsar "abrir ficha". |
| `Columns` | `RenderFragment` | | Columnas custom para el popup (override de la columna por defecto). |
| `ValueTemplate` | `RenderFragment` | | Plantilla del valor seleccionado mostrado en el campo. |
| `IconTemplate` | `RenderFragment` | | Plantilla del icono por fila. |
| `ColumnWidth` | `string` | `""` | Ancho de columna por defecto del desplegable. |
| `Visible` | `bool` | `true` | Oculta el componente entero. |
`TextProperty` es obligatorio. Sin él, el componente pinta un aviso en rojo en vez del desplegable. Pásalo siempre con `@nameof(Tipo.Propiedad)`, nunca como string suelto.
***
## DnzRowSelector [#dnzrowselector]
No le pasas `Data`: le das un `ReportId` (el informe de la sección) y un `Client`, y él busca contra el servidor con paginación. Para catálogos grandes (clientes, productos, proveedores) donde cargar todo en memoria no tiene sentido.
```razor
```
Hay dos formas de decirle "ya hay algo seleccionado" al cargar, y eligen entre una consulta o ninguna:
Si ya tienes la fila (`IDinaupRow`), pásala por `@bind-SelectedRow` y el componente la pinta directa, sin ir al servidor.
```razor
```
Si solo tienes el `Guid`, usa `DefaultID`: el componente lanza una consulta al informe para resolver la fila y mostrar su etiqueta. Una query de más, úsalo solo cuando no tengas la fila a mano.
```razor
```
| Parámetro | Tipo | Default | Para qué |
| -------------------- | --------------------------- | ------------ | ------------------------------------------------------------------------------ |
| `Client` | `DinaupClientC` | | Cliente contra el que consulta el informe. **Obligatorio** (`EditorRequired`). |
| `ReportId` | `string` | | GUID del informe (`SeccionD._SectionID`) que alimenta la búsqueda. |
| `SelectedRow` | `IDinaupRow` | | Fila seleccionada. Úsalo con `@bind-SelectedRow`. |
| `SelectedRowChanged` | `EventCallback` | | Se dispara al cambiar la selección. |
| `DefaultID` | `Guid` | `Guid.Empty` | ID inicial a resolver (lanza una consulta al informe). |
| `Label` | `string` | | Etiqueta del campo. |
| `Placeholder` | `string` | | Texto cuando no hay nada elegido. |
| `IsRequired` | `bool` | `false` | Marca visual de obligatorio si está vacío. |
| `Disabled` | `bool` | `false` | Bloquea el control. |
| `AdvancedFilter` | `List` | | Filtro aplicado al informe (acota el universo buscable). |
| `AdminMode` | `bool` | `false` | Consulta el informe en modo admin. |
| `Width` | `string` | `"280px"` | Ancho del campo. |
| `Style` | `string` | `"flex:1"` | Estilo inline del campo. |
| `Class` | `string` | `""` | Clases CSS extra del contenedor. |
| `Icon` | `string` | | Icono al inicio del campo. |
| `KeyboardShortcut` | `string` | | Atajo de teclado asociado al selector. |
| `OpenInWindow` | `bool` | `true` | Permite abrir la ficha seleccionada en ventana. |
| `OnAdd` | `EventCallback` | | Se dispara al pulsar el "+" para crear una ficha nueva. |
| `OnOpenRecord` | `EventCallback` | | Se dispara al pulsar "abrir"; si no lo cableas, abre la ficha en ventana. |
`AdvancedFilter` es tu palanca para acotar: pásale un `List` y el usuario solo busca dentro de ese subconjunto (ej. clientes activos, productos de un almacén). Combínalo con `OnAdd` para que pueda crear sobre la marcha si no encuentra lo que busca.
Además del binding, `DnzRowSelector` expone métodos públicos para preseleccionar desde código: `SelectByIdAsync(Guid id)` resuelve la fila por id contra el informe, y `SelectAsync(...)` acepta una fila (`IDinaupRow`), una `DinaupBasicInformation` o incluso otro `DnzRowSelector` como origen.
***
## DnzDropDown [#dnzdropdown]
La versión cruda del desplegable de datos sobre `IDinaupRow`, sin la capa de overlay de acciones ni resolución de color/icono de `DnzDataGridDropDown`. En la práctica usa `DnzDataGridDropDown`; este queda para casos donde quieras el grid pelado. Igual que aquel, `TextProperty` es obligatorio.
```razor
```
| Parámetro | Tipo | Default | Para qué |
| ----------------- | ------------------ | --------------- | --------------------------------------------------------- |
| `Data` | `IEnumerable` | `new List()` | La colección a elegir. |
| `Selected` | `T` | | Fila seleccionada. Úsalo con `@bind-Selected`. |
| `SelectedChanged` | `EventCallback` | | Se dispara al cambiar la selección. |
| `TextProperty` | `string` | | Propiedad a mostrar. **Obligatorio**; usa `@nameof(...)`. |
| `ColorProperty` | `string` | | Propiedad de estilo de color de cada opción. |
| `IconoProperty` | `string` | | Propiedad que aporta el icono de cada opción. |
| `Label` | `string` | | Etiqueta del campo. |
| `Icon` | `string` | | Icono al inicio del campo. |
| `Style` | `string` | | Estilo inline del control. |
| `Class` | `string` | | Clases CSS extra. |
| `Disabled` | `bool` | `false` | Bloquea el control. |
| `Visible` | `bool` | `true` | Oculta el componente entero. |
| `OnAdd` | `EventCallback` | | Se dispara al pulsar el "+". |
| `OnRemove` | `EventCallback` | | Se dispara al limpiar; si no lo cableas, limpia solo. |
| `OnOpen` | `EventCallback` | | Se dispara al pulsar "abrir ficha". |
***
## DnzSearchInput [#dnzsearchinput]
Caja de búsqueda con icono de lupa y debounce de 500 ms. No es un selector: es la pieza que dispara el filtro sin lanzar una consulta por cada tecla. La usa por dentro `DnzRowSelector` para buscar contra el informe, y te sirve para tu propio buscador sobre una lista o un informe.
```razor
```
```razor
@code {
async Task OnBuscar(string texto) {
await CargarResultados(texto);
}
}
```
| Parámetro | Tipo | Default | Para qué |
| -------------------- | ----------------------- | ------------- | --------------------------------------------------------------------------------- |
| `BounceValueChanged` | `EventCallback` | | Se dispara 500 ms después de que el usuario deja de teclear, con el texto actual. |
| `Value` | `string` | | Texto del campo. |
| `Placeholder` | `string` | `"Buscar..."` | Texto cuando está vacío. |
| `Class` | `string` | `""` | Clases CSS extra para el contenedor. |
| `Style` | `string` | `""` | Estilo inline del contenedor. |
El debounce es de 500 ms y va por dentro con el `Debouncer` de Dinaup. No montes tu propio temporizador encima: engancha tu carga a `BounceValueChanged` y listo.
***
## DnzItemPickerDialog [#dnzitempickerdialog]
Cuando no quieres un desplegable embebido sino abrir una ventana de selección a pantalla completa sobre un informe. Lo lanzas con `OpenAsync` y te devuelve la fila elegida (o `null` si el usuario cierra).
```razor
@inject DialogService DialogService
@code {
async Task ElegirCliente() {
var fila = await DnzItemPickerDialog.OpenAsync(DialogService, SessionPlay, EntidadesD._SectionID);
if (fila.IsNotNull()) clienteSeleccionado = fila;
}
}
```
| Parámetro | Tipo | Default | Para qué |
| ---------- | --------------- | ------- | ---------------------------------------------- |
| `Client` | `DinaupClientC` | | Cliente contra el que consulta el informe. |
| `ReportId` | `string` | | GUID del informe que se muestra en el diálogo. |
El método estático `OpenAsync(DialogService, DinaupClientC, string reportId)` abre el diálogo (800×600, redimensionable y arrastrable) y devuelve un `DinaupDynamicRowDTO` con la fila seleccionada, o `null` si se cancela.
Para elegir una ficha dentro de un formulario, casi siempre prefieres `DnzRowSelector` embebido. Reserva este diálogo para cuando la selección es una acción aparte (un botón "Elegir cliente…" que abre la ventana) y no un campo más del layout.
***
Relacionado: [Introducción a DinaZen](/docs/desarrollo/dotnet/dinazen) · [Índice de componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [Informes (Flex)](/docs/desarrollo/flex/informes) · [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente) · [Guías de estilo C#/Blazor](/docs/desarrollo/dotnet/c-code-style-guidelines)
# Tablas e informes (/docs/desarrollo/dotnet/dinazen/componentes/tablas-e-informes)
Un informe de [Dinaup Flex](/docs/desarrollo/flex/informes) vive en el servidor: tú lo pides por su `ReportId` con el [SDK .NET](/docs/desarrollo/dotnet/sdk) y te devuelve filas tipadas con sus columnas, formatos y totales. Esta familia coge ese resultado y lo pinta (tabla, tarjetas, gráfica o ranking) **con el mismo aspecto que Play** y sin que escribas una sola `RadzenDataGridColumn` a mano.
La decisión es una sola: ¿quieres **una rejilla completa** o **varias vistas del mismo informe a la vez**? Para lo primero, `DnzReportView` directo. Para lo segundo, `DnzReportProvider` como contenedor que carga el informe una vez y lo reparte por cascada a sus hijos.
El `ReportId` es el GUID del informe definido en [Flex / Informes](/docs/desarrollo/flex/informes). Lo mismo que alimenta los listados de Play alimenta estos componentes.
***
## ¿Tabla suelta o dashboard? [#tabla-suelta-o-dashboard]
`DnzReportView` resuelve el caso completo: cabecera, buscador, exportar CSV, paginación server-side y filtros por columna.
```razor
```
`DnzReportProvider` carga el informe una vez y lo expone como cascada (`ReportContext`). Dentro metes las vistas que quieras, todas leyendo de la misma carga: una llamada al servidor, varias representaciones.
```razor
```
`DnzReportView` con `OnItemSelect` te da la fila pulsada como `DinaupDynamicRowDTO`. Es la base de los selectores relacionales y de los pickers de Play; mira [Selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores) si tu caso es "elige una ficha".
`DnzReportView` pinta una tabla por sí solo. `DnzReportProvider` **no dibuja nada**: es el grifo de datos para `DnzCardList`, `DnzChartView` y `DnzTopN`. No los mezcles esperando que el Provider muestre una rejilla.
***
## DnzReportView [#dnzreportview]
La tabla completa de Play a partir de un `ReportId`: columnas tipadas, orden multi-columna, filtros avanzados, paginación server-side, exportar CSV y doble clic para abrir la ficha.
```razor
@code {
private async Task AbrirFactura(DinaupDynamicRowDTO fila) {
await DnzFormView.OpenAsync(DialogService, Client, fila.SectionId, fila.ID);
}
}
```
Para embeberlo dentro de otra ficha sin barra de título ni botón de añadir:
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------ |
| `Client` | `DinaupClientC` | — | **Requerido.** Cliente del SDK que ejecuta el informe contra el servidor. |
| `ReportId` | `string` | `""` | **Requerido.** GUID del informe a cargar. |
| `VariablesValues` | `Dictionary` | — | Valores de las variables del informe; si faltan, se pregunta al usuario antes de pintar. |
| `QuerySearch` | `string` | `""` | Texto de búsqueda inicial. Cambiarlo en caliente recarga el informe. |
| `AdvancedFilter` | `List` | — | Filtro server-side aplicado de entrada, además de los que ponga el usuario. |
| `Limit` | `int` | `50` | Tamaño de página inicial. El usuario puede subirlo (25–3000). |
| `Orden` | `Dictionary` | — | Orden inicial por columna (`true` = ascendente). |
| `ShowTitle` | `bool` | `true` | Muestra la cabecera con icono, título y selector de columnas visibles. |
| `Title` | `string` | `""` | Sobrescribe el título; si está vacío, usa el del informe. |
| `ShowSearch` | `bool` | `true` | Muestra el buscador de la cabecera. |
| `Filtrable` | `bool` | `true` | Habilita los filtros por columna en las cabeceras. |
| `ShowAdd` | `bool` | `true` | Muestra el botón "+" para crear un registro de la sección del informe. |
| `AdminMode` | `bool` | `false` | Carga el informe en modo administrador (sin algunos filtros de visibilidad). |
| `ToolBarTemplate` | `RenderFragment` | — | Contenido extra inyectado en la barra de herramientas de la rejilla. |
| `OnItemSelect` | `EventCallback` | — | Se dispara al seleccionar una fila. Si lo defines, sustituye la apertura automática de la ficha. |
| `OnDataChanged` | `EventCallback` | — | Se dispara cada vez que el informe (re)carga sus datos. |
Las columnas visibles se recuerdan por URL + `ReportId` en `localStorage`, igual que en Play: el usuario ajusta una vez y se mantiene. Las columnas de moneda salen con `DnzSpanMoney` (rojo en negativos) y suma en el pie automáticamente.
### Las columnas se pintan solas [#las-columnas-se-pintan-solas]
No declaras columnas. `DnzReportView` lee el formato de cada campo del informe (`DEC`, `INT`, `DATE`, `BOOL`, texto…) y elige la plantilla adecuada: importes con `DnzSpanMoney` y suma en el pie, fechas en formato local, booleanos como badge Sí/No, estados con color. Tú solo le das el `ReportId`; el informe manda.
Lo único que personalizas por plantilla es la **barra de herramientas**, vía `ToolBarTemplate`:
```razor
```
### Abrirlo sin colocarlo en el markup [#abrirlo-sin-colocarlo-en-el-markup]
`DnzReportView` expone dos métodos estáticos para abrirlo bajo demanda como diálogo o ventana flotante:
```razor
await DnzReportView.OpenAsync(DialogService, Client, "3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f", title: "Facturas");
```
Firma real:
```csharp
public static Task OpenAsync(DialogService ds, DinaupClientC client, string reportId, Dictionary vars = null, string title = "Informe", string width = "90%", string height = "80%")
```
```razor
DnzReportView.OpenAsWindow(WindowManager, Client, "3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f", title: "Facturas", icon: "receipt_long");
```
Firma real:
```csharp
public static string OpenAsWindow(DnzWindowManagerService wm, DinaupClientC client, string reportId, Dictionary vars = null, string title = "Informe", string icon = "analytics")
```
***
## DnzReportProvider [#dnzreportprovider]
Contenedor "headless": carga el informe una vez y lo reparte por cascada a sus hijos vía `ReportContext`. No dibuja tabla; es el grifo de datos para dashboards con varias vistas del mismo informe.
```razor
```
Las vistas hijas van dentro de `ChildContent` (el contenido entre las etiquetas del Provider), así que es un `RenderFragment`: metes el markup que quieras y las vistas leen el contexto por cascada.
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ----------------- | ---------------------------- | ----------- | --------------------------------------------------------------------------------------- |
| `Client` | `DinaupClientC` | — | **Requerido.** Cliente del SDK que ejecuta el informe. |
| `ReportId` | `string` | `""` | **Requerido.** GUID del informe a cargar. |
| `VariablesValues` | `Dictionary` | — | Valores de las variables del informe; si faltan, se pregunta antes de pintar los hijos. |
| `QuerySearch` | `string` | `""` | Búsqueda aplicada a la carga. |
| `AdvancedFilter` | `List` | — | Filtro server-side aplicado a la carga. |
| `Limite` | `int` | `500` | Número de filas que trae para alimentar los hijos. |
| `Orden` | `Dictionary` | — | Orden de las filas que se cargan. |
| `AdminMode` | `bool` | `false` | Carga el informe en modo administrador. |
| `ChildContent` | `RenderFragment` | — | Las vistas que consumen el contexto (tarjetas, gráficas, ranking). |
| `OnDataLoaded` | `EventCallback` | — | Se dispara cuando termina la carga del informe. |
El Provider analiza las columnas del informe y deja preparado el mapeo del `ReportContext` (qué columna es la numérica principal, cuál es la de categoría/estado, cuál es de moneda…). Por eso `DnzChartView`, `DnzTopN` y `DnzCardList` funcionan sin que les digas qué columna pintar: lo adivinan del informe. Si no aciertan, se lo fuerzas con `ValueColumn` / `CategoryColumn`.
***
## DnzCardList [#dnzcardlist]
Pinta las filas del informe como tarjetas en vez de rejilla: título, una imagen de preview si la fila la trae, unos pocos campos y el importe destacado. Va dentro de un `DnzReportProvider`.
```razor
@code {
private async Task AbrirFicha(DinaupDynamicRowDTO fila) {
await DnzFormView.OpenAsync(DialogService, Client, fila.SectionId, fila.ID);
}
}
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| -------------- | ------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------- |
| `MaxFields` | `int` | `4` | Cuántos campos secundarios muestra cada tarjeta (sin contar el título ni el importe). |
| `OnItemSelect` | `EventCallback` | — | Se dispara al pulsar una tarjeta. Si lo defines, sustituye la apertura automática de la ficha. |
Además acepta **atributos extra** (`class`, `style`, `data-*`…) que se aplican al `div` raíz de la lista.
La columna de moneda y el campo principal los elige el componente leyendo el mapeo del informe: el importe sale destacado a la derecha con `DnzSpanMoney`, las fechas en formato local y los estados con badge de color. Si la fila trae imagen de preview, la pinta redonda o cuadrada según el propio dato.
***
## DnzChartView [#dnzchartview]
Gráfica del informe (columnas, barras, líneas, área o tarta) agrupando por una categoría y sumando una métrica. Vive dentro de `DnzReportProvider`.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ---------------- | ------------ | ----------- | ------------------------------------------------------------------------------------------------ |
| `ChartType` | `ChartTypeE` | `Column` | Tipo de gráfica: `Column`, `Bar`, `Line`, `Area` o `Pie`. |
| `ValueColumn` | `string` | — | Keyword de la métrica a representar. Si lo omites, usa la numérica principal del informe. |
| `CategoryColumn` | `string` | — | Keyword de la categoría del eje X. Si lo omites, usa la columna de estado o la primera de texto. |
| `MaxItems` | `int` | `20` | Máximo de categorías (las de mayor valor); el resto se descarta. |
Además acepta **atributos extra** que se aplican al `div` raíz de la gráfica.
`ChartTypeE` es un enum anidado del propio componente, por eso en el markup va como `DnzChartView.ChartTypeE.Column`. Las filas se agrupan por `CategoryColumn` y se **suma** `ValueColumn` por grupo, así que un informe de líneas de factura se convierte en "total por cliente" sin más.
***
## DnzTopN [#dnztopn]
Ranking visual de barras horizontales con las N filas de mayor (o menor) valor del informe. Va dentro de un `DnzReportProvider`.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ------------- | -------- | ----------- | ------------------------------------------------------------------------------------- |
| `N` | `int` | `10` | Cuántas filas mostrar en el ranking. |
| `ShowTitle` | `bool` | `true` | Muestra la cabecera "Top N — Columna". |
| `ValueColumn` | `string` | — | Keyword de la columna a rankear. Si lo omites, usa la numérica principal del informe. |
| `Ascending` | `bool` | `false` | `true` para mostrar los valores más bajos primero. |
Si la columna es de tipo moneda o minutos, el valor se formatea solo con `DnzSpanMoney` / `DnzSpanMinutes`. No tienes que indicar el formato: lo hereda del informe. Si el informe no tiene ninguna columna numérica representable, `DnzTopN` no pinta nada.
***
## DnzFilter [#dnzfilter]
El sistema de filtros por columna de `DnzReportView`. No lo colocas tú: la propia tabla lo inserta en la cabecera de cada columna y elige el filtro adecuado según el tipo del campo.
```razor
```
**Parámetros**
| Parámetro | Tipo | Por defecto | Qué hace |
| ------------ | ------------------------------------------- | ----------- | --------------------------------------------------------------------------- |
| `Column` | `DinaupFieldDTO` | — | Definición de la columna del informe (tipo, formato, valores predefinidos). |
| `DataColumn` | `RadzenDataGridColumn` | — | La columna de la rejilla a la que se ata el filtro. |
`DnzFilter` es un **router**: según el formato de la columna delega en el filtro especializado correspondiente. La familia completa:
| Filtro | Cuándo entra |
| ------------------------------------------------------- | ------------------------------------------- |
| `DnzTextFilter` | Texto libre (por defecto). |
| `DnzIntegerFilter` | Columnas `INT`. |
| `DnzDecimalFilter` | Columnas `DEC`. |
| `DnzDateFilter` / `DnzDateTimeFilter` / `DnzTimeFilter` | Fechas, fecha-hora y hora. |
| `DnzBoolFilter` | Booleanos. |
| `DnzBadgeFilter` | Columnas con estilo de badge. |
| `DnzPredefinedFilter` | Columnas con lista de valores predefinidos. |
No documentamos cada filtro por separado porque no los instancias a mano: pones `DnzReportView` y el filtro correcto aparece según el informe. El concepto de filtrado server-side y cómo definir filtros de entrada vive en [Flex / Informes](/docs/desarrollo/flex/informes).
***
## Leer una fila [#leer-una-fila]
Las filas que reparten estos componentes son `DinaupDynamicRowDTO`. Para sacar el texto de una columna usa `.GetLegible("columna")`; `ID` y `SectionId` vienen rellenos para abrir la ficha.
```razor
@code {
private async Task AbrirFila(DinaupDynamicRowDTO fila) {
var nombre = fila.GetLegible("cliente");
await DnzFormView.OpenAsync(DialogService, Client, fila.SectionId, fila.ID);
}
}
```
***
## Relacionado [#relacionado]
* [Selectores](/docs/desarrollo/dotnet/dinazen/componentes/selectores): cuando el caso es "elige una ficha" a partir de un informe.
* [KPIs y métricas](/docs/desarrollo/dotnet/dinazen/componentes/kpis-y-metricas): cifras y comparativas para completar el dashboard.
* [Datos tipados (Spans)](/docs/desarrollo/dotnet/dinazen/componentes/datos-tipados): `DnzSpanMoney`, `DnzSpanMinutes` y demás, lo que estas vistas usan por dentro.
* [Cookbook de patrones](/docs/desarrollo/dotnet/dinazen/patrones): recetas de extremo a extremo que combinan estos componentes con el SDK.
* [Informes de Dinaup Flex](/docs/desarrollo/flex/informes): qué es un informe, su `ReportId`, variables y filtros. · [Filtrar un informe por rango de fechas](/docs/desarrollo/flex/informes/filtrar-informe-por-rango-de-fechas)
* [SDK / Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente): cómo ejecutar el informe con `Report_GetAsync`.
→ [Volver a Componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [DinaZen](/docs/desarrollo/dotnet/dinazen) · [SDK .NET](/docs/desarrollo/dotnet/sdk)
# Tarjetas y layout (/docs/desarrollo/dotnet/dinazen/componentes/tarjetas-y-layout)
Casi toda pantalla de Dinaup es lo mismo: una `RadzenCard`, una cabecera arriba y un cuerpo debajo. La cabecera la pones con `DnzCardTitle` y el cuerpo con el contenido que toque. Con estas piezas montas vistas con la estructura visual de Play.
`RadzenCard` envuelve, `DnzCardTitle` titula, y dentro va tu grid, tu formulario o tu lista. El resto de la familia son atajos para casos concretos (KPIs, fichas clicables, avatares, bloques con zoom).
## El patrón base [#el-patrón-base]
Toda subpage parte del mismo esqueleto. Cabecera con icono y título, acciones a la derecha, cuerpo debajo.
### Envuelve en RadzenCard [#envuelve-en-radzencard]
La tarjeta da el fondo, la sombra y el padding. Nunca pintes contenido suelto sin contenedor.
### Pon la cabecera con DnzCardTitle [#pon-la-cabecera-con-dnzcardtitle]
`Icon` + `Title` y listo. Si necesitas botones (agregar, refrescar), van en el slot ``.
### Mete el cuerpo [#mete-el-cuerpo]
Tu `RadzenDataGrid`, tu formulario o una lista. Si quieres que el bloque se pegue a los bordes de la tarjeta, usa `DnzCardBody`.
```razor
@if (productos.IsEmpty())
{
}
else
{
...
}
```
***
## DnzCardTitle [#dnzcardtitle]
Cabecera de tarjeta con icono, título, subtítulo opcional, botones de acción y panel de ayuda desplegable.
```razor
```
| Parámetro | Tipo | Default | Para qué |
| ------------- | ----------------------------- | ------- | --------------------------------------------------------------------------------------- |
| `Title` | `string` | `""` | Texto principal de la cabecera. |
| `Subtitle` | `string` | `""` | Segunda línea bajo el título. Si va vacío, no se pinta. |
| `Icon` | `string` | `""` | Icono Material a la izquierda. Si es una ruta (`/...`, `http...`) lo pinta como imagen. |
| `BadgeType` | `DnzSpecialBadges.BadgeType?` | | Badge especial junto al título (Beta, New\...). |
| `Compact` | `bool` | `false` | Versión reducida con borde inferior, para cabeceras secundarias. |
| `HelpLink` | `string` | `""` | URL de documentación. Activa el botón de ayuda con enlace externo. |
| `HelpContent` | `RenderFragment` | | Contenido de ayuda inline (texto rico) en el panel desplegable. |
| `Actions` | `RenderFragment` | | Slot de botones a la derecha de la cabecera. |
Los botones del slot `Actions` que disparan operaciones async deben llevar `IsBusy=@variable` para que el usuario vea el spinner. Es UX, no opcional.
El botón de ayuda (icono de interrogación a la derecha) solo aparece si pones `HelpContent` o `HelpLink`. Con `HelpContent` escribes el panel a mano; con `HelpLink` el componente pinta un enlace "Ver documentación" que abre en pestaña nueva. Si pones los dos, manda `HelpContent`.
```razor
Configura los tipos impositivos que se ofrecen al crear lineas de factura. El marcado como predeterminado se aplica a productos nuevos.
```
```razor
```
Además de los parámetros de arriba, `DnzCardTitle` acepta **atributos extra que pasan al elemento raíz** (`[Parameter(CaptureUnmatchedValues = true)]`): útil para colar un `id`, un `data-*` o una clase suelta sin tocar el componente.
## DnzCardBody [#dnzcardbody]
Bloque que escapa del padding de la `RadzenCard` padre con margen negativo, para que un grid o una tabla llegue a ras de borde dentro de la tarjeta.
```razor
...
```
| Parámetro | Tipo | Default | Para qué |
| -------------- | ---------------- | ------- | --------------------------------------------------- |
| `ChildContent` | `RenderFragment` | | Contenido del bloque a ancho completo. |
| `Class` | `string` | `""` | Clases CSS extra sobre el contenedor. |
| `Style` | `string` | `""` | Estilos inline extra (se suman al margen negativo). |
## DnzCardKV [#dnzcardkv]
Tarjeta clave-valor para KPIs: icono coloreado a la izquierda, etiqueta arriba y valor grande debajo. Pensada para filas de metricas (uptime, total facturado, stock).
```razor
```
| Parámetro | Tipo | Default | Para qué |
| ----------- | --------- | ---------------- | ----------------------------------------------------------------------- |
| `Title` | `string` | `""` | Etiqueta superior (preferido sobre `Tile`). |
| `Value` | `string` | `""` | Valor principal grande. |
| `Icon` | `string` | `""` | Icono Material a la izquierda. |
| `IconColor` | `string` | `Colors.Primary` | Color del icono (`Colors.Success`, `Colors.Warning`...). |
| `Variant` | `Variant` | `Variant.Flat` | Variante visual de la tarjeta (`Flat`, `Outlined`...). |
| `Tile` | `string` | `""` | Etiqueta legacy. Solo si `Title` va vacío; usa `Title` en código nuevo. |
| `Style` | `string` | `""` | Estilo inline sobre la tarjeta (ej. `flex:1` para repartir ancho). |
`Tile` existe por compatibilidad con consumidores antiguos. En código nuevo usa siempre `Title`.
## DnzCardList [#dnzcardlist]
Renderiza el resultado de un informe Flex como lista de fichas clicables, con imagen, título y hasta 4 campos. Se alimenta del `ReportContext` cascada, no le pasas los datos a mano. Al pulsar una ficha abre el registro o dispara tu callback.
```razor
```
| Parámetro | Tipo | Default | Para qué |
| -------------- | ------------------------------------ | ------- | --------------------------------------------------------------------------------- |
| `MaxFields` | `int` | `4` | Número máximo de campos a mostrar por ficha. |
| `OnItemSelect` | `EventCallback` | | Se dispara al pulsar una ficha. Si no lo enganchas, abre el registro por defecto. |
`DnzCardList` vive dentro del sistema de informes Flex y consume el `ReportContext` por cascada. Para entender de donde sale ese contexto, mira [Informes Flex](/docs/desarrollo/flex/informes).
## DnzContainer [#dnzcontainer]
Contenedor de formularios virtuales (Flex). Posiciona una `RadzenCard` con coordenadas absolutas y dentro pinta una lista de informe, una lista primaria o botones, según la definición del `Container`. Es infraestructura del motor de formularios: rara vez lo instancias a mano, lo coloca el renderizador de formularios.
```razor
```
| Parámetro | Tipo | Default | Para qué |
| ------------------------- | --------------------------------- | ------- | ---------------------------------------------------------------- |
| `Client` | `DinaupClientC` | | (Requerido) Cliente Dinaup con la sesión. |
| `Container` | `Dinaup.VirtualFormDTO.Container` | | (Requerido) Definición del contenedor: posición, lista, botones. |
| `OnButtonClick` | `EventCallback` | | Se dispara al pulsar un botón del contenedor. |
| `OnTabChanged` | `EventCallback` | | Se dispara al cambiar de pestaña en una lista primaria. |
| `OnAddItem` | `EventCallback` | | Se dispara al añadir un item a la lista primaria. |
| `OnOpenListItem` | `EventCallback` | | Se dispara al abrir un item de la lista. |
| `OnDeleteItemPrimaryList` | `EventCallback` | | Se dispara al eliminar un item de la lista primaria. |
## DnzControl [#dnzcontrol]
El campo individual de un formulario virtual (Flex): elige el input correcto (texto, número, fecha, checkbox, selector, editor HTML) según el `FieldFormatE` del `DataControl`. Como `DnzContainer`, es motor de formularios; lo pinta el renderizador, no tu código de pantalla.
```razor
```
| Parámetro | Tipo | Default | Para qué |
| ---------------------- | ------------------------------- | ------- | ---------------------------------------------------------------- |
| `Client` | `DinaupClientC` | | (Requerido) Cliente Dinaup con la sesión. |
| `DataControl` | `Dinaup.VirtualFormDTO.Control` | | (Requerido) Definición del campo: formato, valor, label, estado. |
| `OnDataControlChanged` | `EventCallback` | | Se dispara cuando el usuario cambia el valor del campo. |
| `ModoCelda` | `bool` | `false` | Modo compacto sin label, para edición en celda de tabla. |
| `OnFormatearCodigo` | `Func>` | | Hook para reformatear un código de subcuenta al pulsar Enter. |
## DnzScalableBlock [#dnzscalableblock]
Envuelve cualquier contenido con dos botones de zoom (más/menos) y recuerda la escala en `localStorage`. Útil para tablas anchas o vistas densas que el usuario quiere agrandar. Cada bloque necesita un `Key` único para no pisar la escala de otro.
```razor
...
```
| Parámetro | Tipo | Default | Para qué |
| -------------- | ---------------- | ------- | ------------------------------------------------------------------------------ |
| `Key` | `string` | | (Requerido) Identificador unico. Con el se guarda la escala en `localStorage`. |
| `ChildContent` | `RenderFragment` | | Contenido que se escala con el zoom. |
El `Key` debe ser unico por bloque escalable. Si dos bloques comparten `Key`, comparten la escala guardada y se pisan.
## DnzAvatarInitial [#dnzavatarinitial]
Avatar circular con la inicial del nombre y un color de fondo derivado de esa letra (siempre el mismo color para la misma inicial). Para listas de usuarios, clientes o empleados sin foto.
```razor
@cliente.Nombre
```
| Parámetro | Tipo | Default | Para qué |
| --------- | --------------- | ---------- | ------------------------------------------------------------------------------ |
| `Data` | `string` | `""` | Texto fuente. Se toma su primera letra para la inicial y el color. |
| `Size` | `string` | `"2.5rem"` | Diámetro del avatar (ej. `"32px"`, `"28px"`). |
| `OnClick` | `EventCallback` | | Se dispara al pulsar el avatar. Si lo enganchas, el avatar se vuelve clicable. |
| `Style` | `string` | `""` | Estilos inline extra sobre el contenedor. |
## DnzBanner [#dnzbanner]
Banner destacado de ancho completo con icono, título, contenido libre y botón opcional. Como pieza de layout va arriba de una pantalla, para avisos de versión, ofertas, mantenimiento o errores a página completa.
```razor
La factura se ha emitido y enviado al cliente correctamente.
```
| Parámetro | Tipo | Default | Para qué |
| ----------------- | ---------------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| `Style` | `DnzBannerStyle` | `Primary` | Tema visual: `Primary`, `Gold`, `Love`, `Danger`, `Success`, `Warning`, `Pro`, `Beta`, `New`, `Premium`, `IA`. |
| `Title` | `string` | `""` | Titulo principal. Si va vacío, no se pinta. |
| `Icon` | `string` | `""` | Icono Material Symbols (`"check_circle"`, `"update"`, `"bolt"`). Si va vacío, no hay icono. |
| `ChildContent` | `RenderFragment` | | Cuerpo del banner: párrafos, ``, lo que necesites. |
| `ButtonText` | `string` | `""` | Texto del botón. Solo aparece junto con `DnzButtonrl`. |
| `DnzButtonrl` | `string` | `""` | URL de destino del botón. |
| `OpenInNewTab` | `bool` | `true` | Abre el enlace del botón en pestaña nueva. |
| `AdditionalClass` | `string` | `""` | Clases CSS extra sobre el contenedor. |
`DnzBanner` también aparece en [Badges y estados](/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados) por su faceta de señalizador: es el mismo componente, úsalo donde te encaje en la pantalla.
***
Relacionado: [Intro a DinaZen](/docs/desarrollo/dotnet/dinazen) · [Índice de componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [Badges y estados](/docs/desarrollo/dotnet/dinazen/componentes/badges-y-estados) · [Datos tipados (Spans)](/docs/desarrollo/dotnet/dinazen/componentes/datos-tipados) · [Informes Flex](/docs/desarrollo/flex/informes) · [Guías de estilo C#/Blazor](/docs/desarrollo/dotnet/c-code-style-guidelines)
# Vistas avanzadas (/docs/desarrollo/dotnet/dinazen/componentes/vistas-avanzadas)
Piezas más especializadas, fuera del CRUD de cada día. Aquí tienes la planificación en línea de tiempo con `DnzGenericGantt`, el código resaltado para documentar dentro de la app (`DnzHighlightCode` y `DnzCodeWindow`) y los selectores de rango de fechas con presets para alimentar informes y dashboards (`DnzDateRangeSelector` y `DnzDateTimeRangeSelector`).
## Qué componente uso [#qué-componente-uso]
Tres familias dentro de la página:
| Necesito... | Componente |
| ----------------------------------------------------------------------- | -------------------------- |
| Pintar tareas/recursos en una línea de tiempo con zoom y navegación | `DnzGenericGantt` |
| Mostrar un snippet con resaltado de sintaxis, copiar y números de línea | `DnzHighlightCode` |
| Lo mismo pero con aspecto de ventana (dots de macOS, temas, footer) | `DnzCodeWindow` |
| Elegir un rango de fechas (solo día) con presets tipo "Últimos 7 días" | `DnzDateRangeSelector` |
| Elegir un rango con fecha y hora (incluye el HH:mm) | `DnzDateTimeRangeSelector` |
`DnzGanttToolBar` no se usa suelto: lo monta `DnzGenericGantt` por dentro para la barra de navegación y zoom. Lo documentamos abajo por transparencia, pero tú solo tocas el Gantt.
***
## DnzGenericGantt [#dnzgenericgantt]
Línea de tiempo tipo Gantt: filas por grupo (empleado, recurso, tarea) y barras por intervalo de tiempo, con barra superior para navegar, cambiar de vista (Horas / Semana / Mes / Año) y hacer zoom.
Le pasas dos listas: los `Groups` (las filas) y los `SourceItems` (las barras). Cada item se asocia a su fila por `GroupId`. El componente recalcula el layout solo cuando cambias de vista o de fecha.
```razor
@code {
private List _grupos = new();
private List _citas = new();
protected override void OnInitialized()
{
_grupos.Add(new GanttGroup { Id = "tecnico-1", Text = "Laura (Taller A)" });
_grupos.Add(new GanttGroup { Id = "tecnico-2", Text = "Marcos (Taller B)" });
_citas.Add(new GanttItem("c-1001", "tecnico-1", "Revision 8430-KLM", DateTime.Today.AddHours(9), DateTime.Today.AddHours(11), null));
_citas.Add(new GanttItem("c-1002", "tecnico-2", "ITV 1190-ZRT", DateTime.Today.AddHours(10), DateTime.Today.AddHours(12), null, "background:#0d6efd;color:#fff"));
}
private void AbrirCita(GanttItem item) { /* item.Data trae tu objeto de negocio */ }
}
```
| Parámetro | Tipo | Default | Para qué |
| ------------- | -------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `Groups` | `List` | | Filas del Gantt. Cada `GanttGroup` tiene `Id`, `Text` y `Template` opcional para pintar la celda de la fila. |
| `SourceItems` | `List` | | Barras a colocar. Cada `GanttItem` se ata a su fila por `GroupId` y lleva `From`/`To`, `Text`, `Tooltip` y `RowStyle` (CSS inline de la barra). |
| `OnItemClick` | `EventCallback` | | Se dispara al hacer clic en una barra. Recupera tu entidad desde `item.Data`. |
Por encima de 20.000 items el componente deja de pintar y muestra un aviso de "demasiados resultados". Es a propósito: filtra antes de pasarle los datos, no le eches el listado entero.
`GanttItem` se construye con el constructor `new GanttItem(id, groupId, text, from, to, data, styleX)`. El ultimo parametro es CSS inline opcional para colorear la barra.
## DnzGanttToolBar [#dnzgantttoolbar]
Barra de control del Gantt: flechas anterior/siguiente, botón "Hoy", selector de vista (Horas / Semana / Mes / Año) y zoom. La monta `DnzGenericGantt` internamente; normalmente no la instancias tú.
```razor
@code {
private GanttViewport _viewport = new() { ViewMode = GanttViewMode.Hour, FocusDate = DateTime.Today };
private void OnViewportChanged(GanttViewport vp) => _viewport = vp;
}
```
| Parámetro | Tipo | Default | Para qué |
| ----------------- | ------------------------------ | ----------- | -------------------------------------------------------------------------------------------------- |
| `Viewport` | `GanttViewport` | (requerido) | Estado actual: `FocusDate`, `ViewMode` y `Zoom`. La barra lo lee para pintar titulo y modo activo. |
| `ViewportChanged` | `EventCallback` | | Se dispara al navegar, cambiar de vista o tocar el zoom. Devuelve una copia nueva del viewport. |
## DnzHighlightCode [#dnzhighlightcode]
Bloque de código con resaltado de sintaxis (highlight.js), cabecera con el lenguaje y el nombre de fichero, botón de copiar y números de línea opcionales. Para documentar dentro de la app: snippets de setup, ejemplos de uso, comandos.
```razor
@code {
private string _snippet = "builder.Services.AddDinaZen();";
}
```
| Parámetro | Tipo | Default | Para qué |
| ----------------- | ---------------------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
| `Code` | `string` | `""` | El código a mostrar. |
| `Language` | `string` | `""` | Lenguaje para el resaltado: `csharp`, `razor`, `bash`, `json`, `sql`, `vb`... Acepta alias (`cs`, `js`, `cshtml`). |
| `DnzFileName` | `string` | `""` | Nombre de fichero a mostrar en la cabecera (ej. `Program.cs`). |
| `ShowCopy` | `bool` | `true` | Muestra el boton de copiar al portapapeles. |
| `ShowLineNumbers` | `bool` | `false` | Pinta la columna de números de línea. |
| `Size` | `DnzHighlightCodeSize` | `Default` | Tamaño del bloque: `Small`, `Default` o `Large`. |
Razor (`razor` / `cshtml`) se resalta como XML por dentro. Es el truco de highlight.js, tú solo pasas `Language="razor"`.
## DnzCodeWindow [#dnzcodewindow]
Lo mismo que `DnzHighlightCode` pero con estética de ventana: los tres puntos rojo/amarillo/verde de macOS, título, temas de color y un footer opcional. Para landings, demos o documentación donde quieras que el código "se vea bonito".
```razor
Registra DinaZen en el arranque.
@code {
private string _setup = "builder.Services.AddDinaZen();";
}
```
| Parámetro | Tipo | Default | Para qué |
| ----------------- | -------------------- | --------- | ---------------------------------------------------------------------------------------------------- |
| `Code` | `string` | `""` | El código a mostrar. |
| `Language` | `string` | `""` | Lenguaje del resaltado (mismos alias que `DnzHighlightCode`, más `py`, `go`, `rs`, `dockerfile`...). |
| `Title` | `string` | `""` | Titulo de la ventana (nombre de fichero o descripcion). |
| `ShowCopy` | `bool` | `true` | Muestra el boton de copiar. |
| `ShowLineNumbers` | `bool` | `false` | Pinta los números de línea. |
| `Tilted` | `bool` | `false` | Aplica un efecto 3D inclinado, útil en landings. |
| `Size` | `DnzCodeWindowSize` | `Default` | `Small`, `Default` o `Large`. |
| `Theme` | `DnzCodeWindowTheme` | `Dark` | Tema visual: `Dark`, `Light`, `Monokai` o `Dracula`. |
| `ChildContent` | `RenderFragment` | | Contenido del footer de la ventana (nota, enlace, etc.). |
Si solo quieres mostrar un snippet copiable con resaltado en una ficha o subpage, tira de `DnzHighlightCode`. Es más plano y ocupa menos.
Si es una landing o una demo donde el código es parte del diseño, `DnzCodeWindow` con `Theme` y `Tilted` queda mucho mejor.
## DnzDateRangeSelector [#dnzdaterangeselector]
Selector de rango de fechas (solo día, sin hora) con un desplegable de presets: Hoy, Ayer, Últimos 7 días, Este mes, Este trimestre, Este año, etc. Al elegir "Personalizado" aparecen dos date pickers Desde/Hasta. El componente devuelve el rango ya calculado como `DateOnly`; tú solo recargas datos.
```razor
@code {
private DnzDateRangeSelector.DateRangePreset _preset = DnzDateRangeSelector.DateRangePreset.Last30Days;
private async Task CargarFacturas((DateOnly From, DateOnly To) rango)
{
// recargar el listado de facturas entre rango.From y rango.To
}
}
```
| Parámetro | Tipo | Default | Para qué |
| ----------------------- | --------------------------------------------- | ----------- | ---------------------------------------------------------------------------------- |
| `SelectedPreset` | `DateRangePreset` | `Last7Days` | Preset activo. Bindeable con `@bind-SelectedPreset`. |
| `SelectedPresetChanged` | `EventCallback` | | Se dispara al cambiar de preset (lo usa el binding). |
| `OnRangeChanged` | `EventCallback<(DateOnly From, DateOnly To)>` | | Se dispara con el rango ya calculado cada vez que cambia. Aquí recargas tus datos. |
`OnRangeChanged` salta tambien en el primer render con el preset por defecto, asi que el listado carga solo sin tener que disparar nada a mano.
## DnzDateTimeRangeSelector [#dnzdatetimerangeselector]
Gemelo del anterior pero con hora: los date pickers personalizados incluyen `HH:mm` y el rango se devuelve como `DateTime` (no `DateOnly`). Úsalo cuando el intervalo importa al minuto: logs, fichajes, eventos, auditoría.
```razor
@code {
private DnzDateTimeRangeSelector.DateTimeRangePreset _preset = DnzDateTimeRangeSelector.DateTimeRangePreset.Today;
private async Task CargarEventos((DateTime From, DateTime To) rango)
{
// consultar eventos entre rango.From y rango.To
}
}
```
| Parámetro | Tipo | Default | Para qué |
| ----------------------- | --------------------------------------------- | ----------- | -------------------------------------------------------------------- |
| `SelectedPreset` | `DateTimeRangePreset` | `Last7Days` | Preset activo. Bindeable con `@bind-SelectedPreset`. |
| `SelectedPresetChanged` | `EventCallback` | | Se dispara al cambiar de preset (lo usa el binding). |
| `OnRangeChanged` | `EventCallback<(DateTime From, DateTime To)>` | | Se dispara con el rango ya calculado (con hora) cada vez que cambia. |
Regla rápida: si el dato es "por día" (ventas, stock, facturación) usa `DnzDateRangeSelector`. Si necesitas el minuto exacto (logs, fichajes, trazabilidad) usa `DnzDateTimeRangeSelector`. No mezcles tipos: uno te da `DateOnly` y el otro `DateTime`.
***
Relacionado: [Intro a DinaZen](/docs/desarrollo/dotnet/dinazen) · [Índice de componentes](/docs/desarrollo/dotnet/dinazen/componentes) · [SDK .NET](/docs/desarrollo/dotnet/sdk) · [Informes Flex](/docs/desarrollo/flex/informes) · [Guías de estilo C#/Blazor](/docs/desarrollo/dotnet/c-code-style-guidelines)
# Ejemplo: agregar un cliente desde Dinaup (.NET) (/docs/desarrollo/dotnet/sdk/cliente/ejemplo-agregar-cliente)
Este ejemplo usa [WriteOperation](/docs/desarrollo/dotnet/sdk/cliente/ejemplo-writeoperations-por-lotes) del [SDK Dinaup (.NET)](/docs/desarrollo/dotnet/sdk/cliente) para agregar un cliente en la sección **Entidades**, con la opción de Cliente (bool) activada.
```csharp
public async Task AddCustomer()
{
var datosCliente = new Dictionary
{
{ SectionsD.EntidadesD.EntidadesES.TextoPrincipal, $"Cliente {Guid.NewGuid()}" },
{ SectionsD.EntidadesD.EntidadesES.NombrePersonalRazonSocial, "Juan García S.A." },
{ SectionsD.EntidadesD.EntidadesES.Apellidos, "García López" },
{ SectionsD.EntidadesD.EntidadesES.Cliente, "1" }
};
var writeOperation = new WriteOperation(string.Empty, datosCliente);
var seccionID = SectionsD.EntidadesD._SectionIDGUID;
try
{
await Client.RunWriteOperationAsync(seccionID, writeOperation, false);
writeOperation.EnsureSuccess();
return writeOperation.WriteOperationResult.RowID;
}
catch (Exception ex)
{
Dinaup.Logs.Error(ex, "AddCustomer");
throw;
}
}
```
# Ejemplo: agregar un recambio en Dinaup (.NET) (/docs/desarrollo/dotnet/sdk/cliente/ejemplo-agregar-recambio)
Agregar un nuevo recambio utilizando el [SDK Dinaup para .NET](/docs/desarrollo/dotnet/sdk/cliente) se hace mediante la clase [WriteOperation](/docs/desarrollo/dotnet/sdk/cliente/ejemplo-writeoperations-por-lotes), enviando los campos requeridos a la sección de recambios.
### Requisitos previos [#requisitos-previos]
Antes de agregar un recambio asegúrate de contar con:
* `vehiculoID`: El ID de un vehículo válido para desguace.
* `numeracionID`: Una numeración activa (serie de recambio).
* `tipoID`: El tipo de recambio.
* `estadoID`: El estado del recambio.
Si no tienes los valores puedes obtenerlos usando los métodos para consultar informes. [Reports](/docs/desarrollo/flex/informes)
### Preparar los datos [#preparar-los-datos]
Crea un diccionario con los datos del recambio:
```csharp
var datosRecambio = new Dictionary
{
{ RecambiosES.TextoPrincipal, "Motor diésel completo" },
{ RecambiosES.ReferenciaRecursoDeOrigen, vehiculoID },
{ RecambiosES.ReferenciaNumeracion, numeracionID },
{ RecambiosES.ReferenciaEstado, estadoID },
{ RecambiosES.ReferenciaTipo, tipoID }
};
```
`RecambiosES` se encuentra en el espacio de nombres `MyDinaup.SectionsD.RecambiosD`. \
Debes tener instalada en el proyecto la librería de mapeo personalizada [MyDinaup](/docs/desarrollo/dotnet/mydinaup).
### Crear y ejecutar la operación [#crear-y-ejecutar-la-operación]
Crea la operación de escritura:
```csharp
var writeOperation = new WriteOperation(string.Empty, datosRecambio);
```
Ejecuta la operación
```csharp
var seccionID = MyDinaup.SectionsD.RecambiosD._SectionIDGUID;
var resultado = await client.RunWriteOperationAsync(
seccionID,
writeOperation,
false // false = escritura directa, true = virtualizada (ejecuta scripts)
);
resultado.EnsureSuccess(); // Provoca excepción si algo falla.
```
# Ejemplo: ejecución de WriteOperations por lotes (.NET) (/docs/desarrollo/dotnet/sdk/cliente/ejemplo-writeoperations-por-lotes)
### Aprende a crear WriteOperations [#aprende-a-crear-writeoperations]
Puedes aprender a crear **WriteOperations** consultando la guía del [Cliente Dinaup](/docs/desarrollo/dotnet/sdk/cliente).
### Crea una lista de WriteOperations [#crea-una-lista-de-writeoperations]
```csharp
var bulkOperations = new List();
/// Agregar WriteOperation
```
Todos los WriteOperations deben tener las mismas columnas.
### Ejecuta la colección [#ejecuta-la-colección]
```csharp
var bulkOperations = new List();
/// Agregar WriteOperation
var sectionId = MyDinaup.SectionsD.TareasDeProyectosD.TareasDeProyectosES._SectionIDGUID;
var result = await dinaupClient.RunWriteOperationAsync(sectionId, bulkOperations, true);
result.EnsureSuccess(); // Provoca excepción si algo falla.
```
## Ejemplo [#ejemplo]
```csharp
var bulkOperations = new List();
for (int i = 1; i <= 5; i++)
{
var itemData = new Dictionary
{
{ MyDinaup.SectionsD.TareasDeProyectosD.TareasDeProyectosES.Resumen, $"Tarea #{i}" },
{ MyDinaup.SectionsD.TareasDeProyectosD.TareasDeProyectosES.TextoPrincipal, $"Contenido para la tarea {i}" },
{ MyDinaup.SectionsD.TareasDeProyectosD.TareasDeProyectosES.Prioridad, (i % 3).ToString() }
};
bulkOperations.Add(new WriteOperation(string.Empty, itemData));
}
var sectionId = MyDinaup.SectionsD.TareasDeProyectosD.TareasDeProyectosES._SectionIDGUID;
var result = await dinaupClient.RunWriteOperationAsync(sectionId, bulkOperations, true);
result.EnsureSuccess(); // Provoca excepción si algo falla.
```
# Escribir en secciones (/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts)
Un WriteOperation envía un diccionario campo → valor. Pero la sección no es un almacén pasivo: al escribir, el servidor **autorrellena** campos dependientes, **calcula** totales y puede ejecutar la **misma lógica interna** que usa la interfaz. Entender estos tres comportamientos evita la mayoría de sorpresas al integrar.
## 1. El orden de los campos importa [#1-el-orden-de-los-campos-importa]
Los campos se procesan en el orden en que los envías, y escribir uno dispara los autorrellenados que dependen de él.
Ejemplo real de **Ventas**: al rellenar `Cliente`, se copia automáticamente su descuento a la venta. Si envías primero el descuento manual y después el cliente, el autorrellenado del cliente **pisa** tu descuento. Regla práctica: **primero las referencias** (cliente, proceso, producto...), **después los valores manuales**.
Otro ejemplo, de **Oportunidades CRM**: al escribir el `Proceso` comercial, la `Fase` se autorrellena con la fase inicial de ese proceso. El proceso va antes que cualquier campo que dependa de la fase.
## 2. Autorrellenado «Siempre» copia incondicionalmente [#2-autorrellenado-siempre-copia-incondicionalmente]
Cuando un campo está definido como autorrellenado «Siempre» desde otro, la copia se ejecuta **cada vez** que cambia el origen:
* Si seleccionas un cliente **sin** descuento, el descuento de la venta se copia **vacío** (no se conserva el anterior).
* Si **deseleccionas** el cliente, el destino también se vacía.
No es un valor por defecto: es una copia viva. Si necesitas un valor manual distinto, escríbelo **después** del campo que lo autorrellena.
## 3. Los scripts hacen el trabajo por ti [#3-los-scripts-hacen-el-trabajo-por-ti]
Cada sección puede llevar scripts internos: cálculos, validaciones y filtros que en la interfaz se ejecutan solos. Al escribir por API con **scripts activados**, se ejecutan igual:
```csharp
// Tercer parámetro a true: el servidor ejecuta los scripts de la sección
// (calcula totales, valida y aplica su lógica, igual que en la interfaz).
var result = await dinaupClient.RunWriteOperationAsync(sectionId, bulkOperations, true);
```
En una **venta**, rellenas `Cantidad` y `PrecioPorUnidad` de una línea y el total del concepto —y los totales del documento— se calculan solos. En **turnos**, los scripts calculan duraciones. Sin scripts, esos campos quedarían a tu cargo: actívalos y reduce tu responsabilidad a los datos de negocio.
Los campos marcados como auto-gestionados (fechas UTC, autor del alta, empresa, calculados como los totales) **los pone el servidor**: enviarlos es en el mejor caso inútil y en el peor un error. En el SDK, el comentario de cada campo (`///`) indica su política de escritura: `Required`, `Auto-filled (Siempre)`, `Read-only via REST` o `can be set when creating, but read-only on update`.
## 4. En las listas, el servidor solo toca las líneas que envías [#4-en-las-listas-el-servidor-solo-toca-las-líneas-que-envías]
Una sección con lista (una venta y sus conceptos, un asiento y sus apuntes) se escribe siempre por su sección principal: la cabecera en `DataMainRow` y las líneas en `DataListRows`, dentro del mismo WriteOperation. La sección de lista no admite escrituras directas — sus scripts y cálculos viven en la principal.
Enviar líneas **no reemplaza la lista**. El servidor procesa una a una las que recibe, decide por su `"id"`, y deja intactas las que no están en el envío:
| La línea enviada lleva | El servidor |
| --------------------------------- | ------------------------------ |
| `"id"` vacío, o sin `"id"` | crea la línea |
| el `"id"` de una línea existente | edita solo los campos enviados |
| su `"id"` y `"eliminado"` a `"1"` | borra la línea |
Puedes corregir el precio de un concepto enviando una única línea con su `"id"`, sin releer ni reenviar el resto del documento.
## Resumen operativo [#resumen-operativo]
| Situación | Qué hacer |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Alta con referencias (cliente, producto, proceso...) | Referencias primero, valores manuales después |
| Un valor manual "desaparece" | Un autorrellenado «Siempre» posterior lo pisó: reordena |
| Totales o campos derivados | No los calcules: `withScripts: true` y los pone el servidor |
| Editar o borrar una línea concreta | Envíala en `DataListRows` con su `id` (`eliminado` a `1` para borrarla); el resto de líneas no se toca |
| Campo rechazado o ignorado | Mira su política REST en el comentario del SDK |
| ¿Qué sección uso para este dato? | [Catálogo de secciones del núcleo](/docs/desarrollo/recursos/secciones-nucleo) |
Ejemplos completos de escritura: [WriteOperations por lotes](/docs/desarrollo/dotnet/sdk/cliente/ejemplo-writeoperations-por-lotes), [agregar un cliente](/docs/desarrollo/dotnet/sdk/cliente/ejemplo-agregar-cliente) y [agregar un recambio](/docs/desarrollo/dotnet/sdk/cliente/ejemplo-agregar-recambio).
# Cliente Dinaup (/docs/desarrollo/dotnet/sdk/cliente)
El cliente `Dinaup` en .NET te conecta al servicio para consultar informes, gestionar archivos, añadir anotaciones, generar documentos dinámicos, leer/escribir datos de secciones y trabajar con paginación y filtros.
## Conectar y operar [#conectar-y-operar]
### Instala [#instala]
```bash
dotnet add package Dinaup
dotnet add package Demoup.MyDinaup
```
### Conecta [#conecta]
```csharp
var client = await DinaupClientC.ConnectAsync(
endPoint: "https://api.dinaup.com/v2/tu-codigo",
publicKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
secretKey: "tu-secret-key-aqui"
);
if (client == null || client.IsConnected == false)
{
throw new Exception("No se pudo conectar a Dinaup");
}
```
```csharp
using Dinaup;
// Las unicas credenciales en variables de entorno
var vault = new VaultData(
Environment.GetEnvironmentVariable("VAULT_URL"),
Environment.GetEnvironmentVariable("VAULT_PASSWORD")
);
vault.Initialize();
// Todo lo demas viene del Vault
var client = await DinaupClientC.ConnectAsync(
endPoint: vault.Read("dinaup.endpoint"),
publicKey: vault.Read("dinaup.publickey"),
secretKey: vault.Read("dinaup.secretkey")
);
if (client == null || client.IsConnected == false)
{
throw new Exception("No se pudo conectar a Dinaup");
}
```
```csharp
using Dinaup;
var builder = WebApplication.CreateBuilder(args);
// Cargar Vault
var vault = new VaultData(
Environment.GetEnvironmentVariable("VAULT_URL"),
Environment.GetEnvironmentVariable("VAULT_PASSWORD")
);
vault.Initialize();
// Conectar a Dinaup
var client = await DinaupClientC.ConnectAsync(
endPoint: vault.Read("dinaup.endpoint"),
publicKey: vault.Read("dinaup.publickey"),
secretKey: vault.Read("dinaup.secretkey")
);
if (client == null || client.IsConnected == false)
throw new Exception("No se pudo conectar a Dinaup");
// Registrar como Singleton
builder.Services.AddSingleton(client);
var app = builder.Build();
```
### Opera [#opera]
```csharp
// Use pre-built reports from DemoUp.MyDinaup
using DemoUp.MyDinaup.Reports.FuncionalidadD;
// Create and execute the report
var ventasReport = new APIVentasC();
await ventasReport.ExecuteQueryAsync(
dinaupClient: client,
page: 1,
resultsPerPage: 50
);
// Access results
Console.WriteLine($"Total: {ventasReport.TotalResults} records");
foreach (var row in ventasReport.Rows)
{
Console.WriteLine($"- {row.NumerodefacturaCompleto}: {row.Total}");
}
```
```csharp
Guid sectionId = /* sección destino */;
var data = new Dictionary
{
{
SeccionDePruebasAPIES.TextoPrincipal,
$"Prueba {Guid.NewGuid()}"
}
};
var wOp = new WriteOperation("", data); // "" => alta
// El sectionId es un Guid: usa _SectionIDGUID (no _SectionID, que es string)
await dinaupClient.RunWriteOperationAsync(SeccionDePruebasAPIES._SectionIDGUID, wOp, false);
// Lanza excepción si la operación falló o no se ejecutó
wOp.EnsureSuccess();
// Tras EnsureSuccess, WriteOperationResult está garantizado (no nulo)
Guid newId = wOp.WriteOperationResult.RowID;
```
```csharp
Guid rowId = /* Id del registro a editar */;
var data = new Dictionary
{
{
SeccionDePruebasAPIES.TextoPrincipal,
$"Prueba {Guid.NewGuid()}"
}
};
var wOp= new WriteOperation(rowId, data);
await dinaupClient.RunWriteOperationAsync(sectionId, wOp, false);
// Lanza excepción si la operación falló o no se ejecutó
wOp.EnsureSuccess();
Guid updatedId = wOp.WriteOperationResult.RowID;
```
## Referencias [#referencias]
### Dinaup .NET [#dinaup-net]
Antes de empezar, instala el paquete Dinaup, que incluye el Cliente base: conexión, autenticación, sesiones, archivos, anotaciones, WriteOperations, etc.
[https://www.nuget.org/packages/Dinaup](https://www.nuget.org/packages/Dinaup)
### MyDinaup [#mydinaup]
Cada empresa tiene su propio modelo de datos. Para trabajarlo tipado, añade tu biblioteca **MyDinaup**: las secciones, informes y documentos de tu tenant convertidos en clases con sus nombres reales. Qué contiene, qué paquete elegir y cómo se regenera, en [MyDinaup](/docs/desarrollo/dotnet/mydinaup).
### Informes [#informes]
Los informes son consultas predefinidas y tipadas para acceder a datos de manera eficiente. Están en el espacio de nombres:
* `{Empresa}.MyDinaup.Reports.{CategoriaD}`
* Convención de nombres de clases: API + NombreDeSeccion + C
* Los nombres de secciones/clases están en español porque se generan a partir de tu licencia (por ejemplo, “Ventas”, “Impuestos”, etc.).
Ejemplos de clases:
* DemoUp.MyDinaup.Reports.FuncionalidadD.APISeccionDePruebasAPIC
* DemoUp.MyDinaup.Reports.FuncionalidadD.APIEntidadesC
* DemoUp.MyDinaup.Reports.VentasD.APIVentasC
* DemoUp.MyDinaup.Reports.ImpuestosD.APIImpuestosC
Usa ExecuteQueryAsync para obtener resultados paginados. Accede a filas fuertemente tipadas desde report.Rows.
```csharp
using DemoUp.MyDinaup.Reports.FuncionalidadD;
var report = new APISeccionDePruebasAPIC(); //
await report.ExecuteQueryAsync(dinaupClient, page: 1, resultsPerPage: 10);
Console.WriteLine($"Total resultados: {report.TotalResults}");
if (report.Rows.IsNotEmpty())
{
foreach (var fila in report.Rows)
{
// Accede a propiedades tipadas de cada fila
// Ej.: fila.TextoPrincipal, fila.ValorEntero, etc.
}
}
```
Ajusta resultsPerPage a tus necesidades. Si esperas muchos resultados, usa paginación.
* **Filtrar resultados** \
Filtro simple por campo de la misma sección
```csharp
var report = new APISeccionDePruebasAPIC();
// Igualdad estricta
report.AddFilter(
SeccionDePruebasAPIES.ValorEntero,
"=",
3);
await report.ExecuteQueryAsync(dinaupClient, page: 1, resultsPerPage: 10);
if (report.Rows.IsNotEmpty())
{
foreach (var fila in report.Rows)
{
// Usar fila...
}
}
```
* **Filtrar utilizando datos relacionados** (composición de rutas):
Construye una clave de relación combinando el ID de sección y el campo de interés en la entidad relacionada.
```csharp
// Clave de relación (ruta compuesta)
var relationKey =
SeccionDePruebasAPIES._SectionID.STR() + "." +
SeccionDePruebasAPIES.ReferenciaAutorDelAlta + "." +
EntidadesBaseES._SectionID.STR() + "." +
EntidadesBaseES.VIP;
var report = new APISeccionDePruebasAPIC();
report.AddFilter(relationKey, "=", 3);
await report.ExecuteQueryAsync(dinaupClient, page: 1, resultsPerPage: 10);
if (report.Rows.IsNotEmpty())
{
foreach (var fila in report.Rows)
{
// Usar fila...
}
}
```
* **Filtrado Between**
```csharp
// Between (ej.: 1 a 2999)
var reportBetween = new APISeccionDePruebasAPIC();
reportBetween.AddFilterBetween(
SeccionDePruebasAPIES.ValorEntero,
1,
2999
);
await reportBetween.ExecuteQueryAsync(dinaupClient, page: 1, resultsPerPage: 10);
```
* **Solapamiento de rangos de fechas (overlap)**
```csharp
var eventosReport = new APIEventosDeCRMC();
var campoInicio = EventosDeCRMES.InicioEvento_UTC;
var campoFin = EventosDeCRMES.FinEvento_UTC;
var rangoInicio = DateOnly.FromDateTime(new DateTime(2000, 1, 1));
var rangoFin = DateOnly.FromDateTime(DateTime.Today.AddYears(50));
eventosReport.AddFilterDateRangeOverlapFilter(campoInicio, campoFin, rangoInicio, rangoFin);
await eventosReport.ExecuteQueryAsync(dinaupClient, page: 1, resultsPerPage: 25);
```
* **Búsqueda de texto libre**
El parámetro `querySearch` de `ExecuteQueryAsync` busca en los campos de texto del informe, como el buscador de la interfaz web.
```csharp
var report = new APISeccionDePruebasAPIC();
await report.ExecuteQueryAsync(dinaupClient, 1, 25, "iPhone Pro Max");
```
* **Filtro IN (varios valores a la vez)**
```csharp
// Con textos
report.AddFilter(SeccionDePruebasAPIES.TextoPrincipal, new[] { "Valor A", "Valor B" });
// Con Guids (relaciones)
report.AddFilterIn(SeccionDePruebasAPIES.ReferenciaAutorDelAlta, new[] { id1, id2 });
```
* **OR implícito**
Dos filtros sobre el mismo campo se combinan con OR, no con AND.
```csharp
report.AddFilter(PaisesD.PaisesES.CodigoDePaisAlfabeticoDe2Caracteres, "=", "ES");
report.AddFilter(PaisesD.PaisesES.CodigoDePaisAlfabeticoDe2Caracteres, "=", "IT");
// Devuelve España e Italia
```
* **Variables de informe**
Si el informe define variables (por ejemplo, un rango de fechas parametrizado), pásalas con `AddVariable`. Admite `string`, `Guid`, `int`, `decimal`, `bool`, `Date` y `DateOnly`.
```csharp
report.AddVariable("ClienteId", clienteId);
report.AddVariable("FechaDesde", new DateOnly(2026, 1, 1));
```
Cuando el informe tiene muchos resultados, recorre página a página con ExecuteQuery\_NextPage\_Async.
```csharp
var report = new APISeccionDePruebasAPIC();
await report.ExecuteQueryAsync(_dinaupClient, 1, 300);
if (report.Rows.IsNotEmpty())
{
do
{
foreach (var row in report.Rows)
{
}
} while (await report.ExecuteQuery_NextPageAsync());
}
```
Para exportar o procesar **todas** las filas de un informe, usa `LoadAllRowsAsync`. Pagina por keyset (cursor sobre el id), sin `OFFSET`, con coste constante por página y sin filas repetidas ni saltadas. Escala a millones.
```csharp
// Devuelve TODAS las filas del informe, ordenadas por id.
var report = new APISeccionDePruebasAPIC();
var todas = await report.LoadAllRowsAsync(dinaupClient, pageSize: 10000, adminMode: true);
Console.WriteLine($"{todas.Count} filas volcadas");
```
Es para exportar y procesar por lotes, no para mostrar en pantalla. El orden es por id (un GUID), así que **no** tiene orden de presentación. Si necesitas otro orden, ordénalo en memoria después. No llames a `AddOrder` antes: el keyset impone su propio orden por id y lanza excepción si ya hay uno.
Ver la guía [Listados de alto rendimiento](/docs/desarrollo/dotnet/sdk/listados-de-alto-rendimiento) para el detalle, los límites y las excepciones.
Cada informe expone tiempos del servidor para diagnóstico: `DatabaseTimeMS` (lo que tardó Postgres), `PrepareTimeMS`, `PostProcessTimeMS` y `ServerTimeMS` (la suma). `TraceId` correlaciona la consulta con los logs del servidor y `SQL` devuelve la sentencia ejecutada. Todos valen `0`/vacío hasta la primera consulta.
#### Columnas ausentes en la respuesta [#columnas-ausentes-en-la-respuesta]
Si el modelo tipado declara una columna que el servidor ya no devuelve, el informe lanza una excepción por defecto: así detectas de inmediato un desajuste entre tu MyDinaup y la estructura real. Para tolerarlo (registrar un aviso y dejar esas propiedades en su valor por defecto), activa `TolerateMissingColumns`:
```csharp
// Por informe:
var report = new APISeccionDePruebasAPIC();
report.TolerateMissingColumns = true;
// O como valor por defecto de todo el proceso, una vez al arrancar:
DinaupReportSettings.TolerateMissingColumns = true;
```
Cada informe hereda el valor de `DinaupReportSettings.TolerateMissingColumns` (por defecto `false`) al crearse, y puede sobrescribirlo por instancia.
### Archivos [#archivos]
Dinaup permite subir archivos desde memoria o URL y obtener URLs firmadas para su consumo.
* **Subir desde un array de bytes**
```csharp
var bytes = System.Text.Encoding.UTF8.GetBytes("hola " + Guid.NewGuid());
var upload = await dinaupClient.File_UploadBytesAsync(bytes, "prueba.txt");
Guid fileId = upload.FileId;
```
* **Subir desde una URL**
```csharp
var upload = await dinaupClient.File_UploadURLAsync(
"https://cdn.dinaup.com/dinaup/web/portal/img/dinabot_marca.png",
"dinabot.png"
);
Guid fileId = upload.FileId;
```
* **Obtener una URL firmada (lectura)**
```csharp
var signed = await dinaupClient.File_SignURLGetAsync(fileId);
var url = signed.url_original; // URL lista para usar
```
Calcula el SHA1 en cliente y consulta antes de subir. Ahorra almacenamiento y ancho de banda.
```csharp
private async Task GetExistingFileAsync(string sha1)
{
var report = new MyDinaup.Reports.FuncionalidadD.APIIndiceDeArchivosEnSistemaC();
report.AddFilter("crcbase", "=", sha1);
await report.ExecuteQueryAsync(_dinaupClient, 1, 1, "", true, true);
return report.Files.Values.FirstOrDefault();
}
private async Task GetExistingFileAsync(byte[] data)
{
string sha1 = Dinaup.extensions.ToSHA1(data);
return await GetExistingFileAsync(sha1);
}
```
### Anotaciones [#anotaciones]
Todas las filas (registros) de Dinaup admiten 3 tipos de anotaciones:
* `AnnotationTypeE.`**`Comments`**: Mensajería tipo chat para el equipo, dentro del contexto del registro.
* `AnnotationTypeE.`**`PublicGallery`**: Archivos públicos en el CDN (p. ej., fotos de productos).
* `AnnotationTypeE.`**`Files`**: Documentos privados asociados (contratos, presupuestos, soportes, etc.).
Los archivos en **PublicGallery** son públicos: cualquiera con el enlace puede verlos.
A continuación, ejemplos usando AnnotationTypeE.Comments.
* **Agregar un comentario (solo texto)**
```csharp
Guid sectionId = /* tu sección */;
Guid rowId = /* registro al que agregas el comentario */;
var anotacion = new AnotationParameters(sectionId, rowId, AnnotationTypeE.Comments)
.WithText("¡Hola mundo! Este es mi primer comentario.");
await dinaupClient.Annotation_PutAsync(anotacion);
```
* **Agregar un comentario con archivo adjunto**
```csharp
var bytes = System.Text.Encoding.UTF8.GetBytes("contenido adjunto");
var upload = await dinaupClient.File_UploadBytesAsync(bytes, "nota.txt");
var anotacion = new AnotationParameters(sectionId, rowId, AnnotationTypeE.Comments)
.WithText("Comentario con adjunto")
.WithFile(upload.FileId); // adjuntamos el archivo
await dinaupClient.Annotation_PutAsync(anotacion);
```
* **Leer anotaciones**
```csharp
var resultado = await dinaupClient.Annotations_GetAsync(
sectionId,
rowId,
AnnotationTypeE.Comments
);
foreach (var anotacion in resultado.Annotations)
{
var texto = anotacion.Text;
var adjuntos = anotacion.AttachedFiles; // si hay archivos adjuntos
}
```
### Documentos dinámicos [#documentos-dinámicos]
Los Documentos Dinámicos permiten:
* Agrupar varias consultas en una sola operación para reducir latencia.
* Generar documentos de impresión (facturas, albaranes) delegando la composición en Dinaup.
Recomendación:
* Para consultar datos en general, usa Reports siempre que sea posible. Documentos Dinámicos son útiles para orquestar múltiples consultas y componer resultados.
- **Ejecutar un documento dinámico**
```csharp
var documentoSesionExecutor = new DynamicDocuments.APID.SesionC();
await documentoSesionExecutor.ExecuteAsync(dinaupClient);
```
### Secciones [#secciones]
Las secciones son el equivalente a tablas/entidades por empresa (Clientes, Facturas, Empleados, etc.). En MyDinaup existen utilidades tipadas para trabajar con ellas:
* Espacio de nombres: MyDinaup.SectionsD
* Incluye métodos para leer registros por Id o por criterios.
Advertencia de rendimiento:
* Las operaciones de lectura en SectionsD consultan todos los datos de la sección y los textos principales de los datos relacionados (p. ej., en una venta también recupera empleados, clientes, productos, impuestos, etc.). Esto tiene mayor coste computacional.
* Para rendimiento óptimo, usa Reports. Para escenarios “super optimizados”, usa PGSync.
* Usa SectionsD cuando el código se ejecute con poca frecuencia o para prototipos rápidos.
- **Recibir un dato por Id**
```csharp
Guid paisId = /* Id del país */;
var pais = await MyDinaup.SectionsD.PaisesD.GetRowByIdAsync(dinaupClient, paisId);
// Usa pais.Propiedad...
```
- **Recibir una lista**
```csharp
var filtros = new List
{
new FilterCondition(
MyDinaup.SectionsD.PaisesD.PaisesES.CodigoDePaisAlfabeticoDe2Caracteres,
"=",
"ES"
)
};
var parametros = new RowsRequestParameters(filtros.ToArray());
var paises = await MyDinaup.SectionsD.PaisesD.GetRowsAsync(dinaupClient, parametros);
// GetRowsAsync devuelve directamente una List
foreach (var p in paises)
{
// p.Propiedad...
}
```
- **Recibir cabecera y líneas en una llamada**
En secciones con lista (una factura y sus líneas), `GetRowsWithListAsync` devuelve cada registro como `MainRow` más su colección `ListRows`.
```csharp
var filas = await MyDinaup.SectionsD.FacturasD
.GetRowsWithListAsync(dinaupClient, new RowsRequestParameters(facturaId.STR()));
var factura = filas.FirstOrDefault();
// factura.MainRow.Propiedad...
foreach (var linea in factura.ListRows) { }
```
### Escritura [#escritura]
Las operaciones de escritura usan WriteOperation para altas y ediciones.
* El ID vacío ("") indica alta
* Un ID válido indica edición.
* Un ID que no existe provocará una excepción.
- **Alta simple (crear un registro)**
```csharp
Guid sectionId = /* sección destino */;
var data = new Dictionary
{
{
SeccionDePruebasAPIES.TextoPrincipal,
$"Prueba {Guid.NewGuid()}"
}
};
var wOp = new WriteOperation("", data); // "" => alta
// El sectionId es un Guid: usa _SectionIDGUID (no _SectionID, que es string)
await dinaupClient.RunWriteOperationAsync(SeccionDePruebasAPIES._SectionIDGUID, wOp, false);
// Lanza excepción si la operación falló o no se ejecutó
wOp.EnsureSuccess();
// Tras EnsureSuccess, WriteOperationResult está garantizado (no nulo)
Guid newId = wOp.WriteOperationResult.RowID;
```
- Edición (actualizar un registro existente)
```csharp
Guid rowId = /* Id del registro a editar */;
var data = new Dictionary
{
{
SeccionDePruebasAPIES.TextoPrincipal,
$"Prueba {Guid.NewGuid()}"
}
};
var wOp= new WriteOperation(rowId, data);
await dinaupClient.RunWriteOperationAsync(sectionId, wOp, false);
// Lanza excepción si la operación falló o no se ejecutó
wOp.EnsureSuccess();
Guid updatedId = wOp.WriteOperationResult.RowID;
```
- **Alta con líneas (cabecera + lista)**
En secciones con lista, añade cada línea como diccionario en `DataListRows`. Se guardan en la misma operación que la cabecera.
```csharp
var wOp = new WriteOperation("", data);
wOp.DataListRows.Add(new Dictionary
{
{ SeccionDePruebasAPIListaES.TextoPrincipal, "Línea 1" }
});
await dinaupClient.RunWriteOperationAsync(SeccionDePruebasAPIES._SectionIDGUID, wOp, false);
```
- **Editar, añadir o borrar líneas de un registro existente**
Las líneas se editan con el mismo `WriteOperation` de la cabecera. Cada línea de `DataListRows` lleva su `"id"`: el Guid de una línea existente la edita, vacío (o ausente) crea una nueva y `"eliminado"` a `"1"` la borra. Las líneas que no envías quedan como están.
```csharp
var wOp = new WriteOperation(rowId); // la cabecera, aunque no cambie ningún campo suyo
// Editar una línea: su id + los campos que cambian
wOp.DataListRows.Add(new Dictionary
{
{ "id", lineaId.ToString() },
{ SeccionDePruebasAPIListaES.TextoPrincipal, "Línea corregida" }
});
// Añadir una línea: id vacío
wOp.DataListRows.Add(new Dictionary
{
{ "id", "" },
{ SeccionDePruebasAPIListaES.TextoPrincipal, "Línea nueva" }
});
// Borrar una línea: su id + eliminado
wOp.DataListRows.Add(new Dictionary
{
{ "id", otraLineaId.ToString() },
{ "eliminado", "1" }
});
await dinaupClient.RunWriteOperationAsync(SeccionDePruebasAPIES._SectionIDGUID, wOp, false);
wOp.EnsureSuccess();
```
El SDK genera constantes también para la sección de lista (`SeccionDePruebasAPIListaES._SectionIDGUID`), pero escribir contra ella no está soportado: los scripts y cálculos viven en la sección principal. Las líneas viajan siempre en `DataListRows`. El detalle de este comportamiento, en [Escribir en secciones](/docs/desarrollo/dotnet/sdk/cliente/escritura-autorrellenado-y-scripts).
- **Editar un solo campo**
Para cambiar un valor sin montar el diccionario:
```csharp
await dinaupClient.RunInlineWriteOperationAsync(
SeccionDePruebasAPIES._SectionIDGUID, rowId,
SeccionDePruebasAPIES.TextoPrincipal, "Nuevo valor");
```
- **Relación por texto (selector dinámico)**
Si no tienes el Guid del registro relacionado, escribe `[Campo=Valor]` y el servidor lo resuelve buscando por ese campo.
```csharp
var data = new Dictionary
{
{ ProductosES.UnidadMedidaID, $"[{UnidadesMedidaES.TextoPrincipal}=Litros]" }
};
```
* **Alta 10 registros de golpe**
```csharp
var operaciones = new List();
for (int i = 0; i < 10; i++)
{
var fila = new Dictionary
{
{
SeccionDePruebasAPID.SeccionDePruebasAPIES.TextoPrincipal,
$"Lote {i}: {Guid.NewGuid()}"
}
};
operaciones.Add(new WriteOperation("", fila)); // alta
}
var batchAdd = await dinaupClient.RunWriteOperationAsync(sectionId, operaciones, false);
batchAdd.EnsureSuccess();
var ids = operaciones
.Where(o => o.WriteOperationResult != null)
.Select(o => o.WriteOperationResult.RowID)
.ToList();
```
* **Editar 10 registros**
```csharp
// Partiendo de la lista 'ids' creada en el ejemplo anterior
var operacionesEdicion = new List();
foreach (var id in ids)
{
var actualizado = new Dictionary
{
{
SeccionDePruebasAPID.SeccionDePruebasAPIES.TextoPrincipal,
$"Editado {DateTime.UtcNow.Ticks}"
}
};
operacionesEdicion.Add(new WriteOperation(id.ToString(), actualizado)); // edición
}
var batchEdit = await dinaupClient.RunWriteOperationAsync(sectionId, operacionesEdicion, false);
batchEdit.EnsureSuccess();
```
Cada llamada admite un máximo de 25 operaciones (`MaxItemsPerWriteOperation`). Si vas a procesar más, usa `.Chunk(25)` para dividir en bloques.
La escritura virtualizada permite que Dinaup ejecute la lógica de negocio definida en una sección. Al activarla, cualquier operación de escritura se comporta como si se hubiera realizado desde la interfaz web: con scripts, validaciones, eventos, y cálculos incluidos.
### ¿Qué hace la virtualización? [#qué-hace-la-virtualización]
Cuando se activa la virtualización en una operación de escritura (`RunWriteOperationAsync` con el tercer parámetro, ejecución de scripts, en `true`), Dinaup:
* Ejecuta scripts personalizados de la sección (`onBeforeSave`, `onAfterSave`, etc.)
* Recalcula campos automáticos (ej. totales, impuestos)
* Aplica reglas de validación y lógica de negocio
* Dispara eventos definidos en la sección
Cuando se desactiva (tercer parámetro en `false`), se guardan los valores tal como se reciben (creando histórico). **No se ejecuta ningún comportamiento adicional.**
La escritura virtualizada es más costosa en términos de rendimiento.\
Cada operación implica ejecutar scripts del backend y lógica personalizada, lo que puede afectar la velocidad si estás procesando muchos registros o usas esta opción innecesariamente.
### ¿Cuándo usar virtualización? [#cuándo-usar-virtualización]
Usa escritura virtualizada cuando la sección contiene lógica de negocio activa que debe ejecutarse. Esto incluye cálculos automáticos de totales en ventas, generación de fechas de vencimiento, o scripts que actualizan otras entidades relacionadas. Por ejemplo, al registrar una nueva venta, al cerrar un pedido o al generar una factura, la virtualización asegura que todo se procese correctamente.
### ¿Cuándo evitar virtualización? [#cuándo-evitar-virtualización]
Evita la virtualización cuando realizas modificaciones simples que no requieren ejecutar lógica adicional. Esto incluye acciones como cambiar el estado de una venta, asignar un técnico a un ticket de soporte, registrar una nota interna o marcar una tarea como completada. En estos casos, desactivarla mejora el rendimiento sin afectar el comportamiento esperado.
### Contexto de ejecución (atribuir operaciones a un usuario) [#contexto-de-ejecución-atribuir-operaciones-a-un-usuario]
Cuando la app conecta con credenciales de aplicación, las operaciones no tienen un usuario detrás. `DinaupContext.WithUser` establece uno para todo lo que ocurra dentro del bloque `using`: afecta al autor del alta, al histórico y a las anotaciones.
```csharp
// Solo userId
using (DinaupContext.WithUser(userId))
{
await dinaupClient.RunWriteOperationAsync(sectionId, wOp, false);
}
// Con IP y UserAgent del usuario final (quedan en el histórico)
using (DinaupContext.WithUser(userId, "192.168.1.1", "Mozilla/5.0..."))
{
await dinaupClient.RunWriteOperationAsync(sectionId, wOp, false);
}
```
El contexto es `AsyncLocal`: vale para el flujo async en curso y se restaura solo al salir del `using`.
### Fichajes (cronómetro) [#fichajes-cronómetro]
Los campos de tipo cronómetro registran tiempo sobre un registro: entrada, salida y latido de continuidad (fichajes de jornada, tiempo por tarea, etc.). Se operan con `Chronometer`, indicando el campo, el registro y la acción.
```csharp
Guid campoId = /* Id del campo cronómetro */;
Guid registroId = /* Id del registro (empleado, tarea…) */;
// Iniciar el fichaje
var inicio = dinaupClient.Chronometer(campoId, registroId, DinaupClientC.ChronometerActionE.actionStart);
// Latido periódico mientras el cronómetro corre
dinaupClient.Chronometer(campoId, registroId, DinaupClientC.ChronometerActionE.actionPing);
// Detener el fichaje
var fin = dinaupClient.Chronometer(campoId, registroId, DinaupClientC.ChronometerActionE.actionStop);
if (fin.Ok == false)
Console.WriteLine($"El fichaje no se registró: {fin.Description}");
```
Las tres acciones (`actionStart`, `actionPing`, `actionStop`) devuelven un `ChronometerResponse` con `Ok`, `Description`, `SuccessNotices` y `ErrorNotices`. `Chronometer` es síncrono.
# Funciones de agregación (/docs/desarrollo/flex/dinascript/funciones/agregacion)
Funciones del espacio `F.` que calculan sobre grupos de registros: totales, medias, primeros y últimos valores, rangos y recuentos de días. Todas las `Aggregate_*` ejecutan solo en [fórmulas de algoritmo](/docs/desarrollo/flex/algoritmos); las convenciones comunes (tipos, sufijos, contextos) están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Contar, sumar y promediar [#contar-sumar-y-promediar]
Las variantes `Distinct` descartan los valores repetidos antes de calcular.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------- | ---------- | -------- | ------------------------------------------- |
| `Aggregate_Count` | (dato) | Entero | Número total de valores del grupo. |
| `Aggregate_CountDistinct` | (dato) | Entero | Número de valores distintos del grupo. |
| `Aggregate_Sum` | (dato) | Decimal | Suma todos los valores decimales del grupo. |
| `Aggregate_SumDistinct` | (dato) | Decimal | Suma los valores decimales distintos. |
| `Aggregate_Average` | (dato) | Decimal | Media de los valores decimales del grupo. |
| `Aggregate_AverageDistinct` | (dato) | Decimal | Media de los valores decimales distintos. |
## Concatenar texto [#concatenar-texto]
| Función | Parámetros | Devuelve | Qué hace |
| -------------------------- | ---------- | -------- | ------------------------------------------ |
| `Aggregate_Concat` | (dato) | Texto | Une todos los textos del grupo en uno. |
| `Aggregate_ConcatDistinct` | (dato) | Texto | Une los textos distintos del grupo en uno. |
## Máximo y mínimo del grupo [#máximo-y-mínimo-del-grupo]
Sin sufijo operan sobre decimales (`Aggregate_Max`); sufijos `Date`, `DateTime` y `Time` para fechas y horas (`Aggregate_MaxDate`…). Devuelven el tipo de su variante.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------- | ---------- | -------------- | ------------------------- |
| `Aggregate_Max*` | (dato) | Según variante | Valor más alto del grupo. |
| `Aggregate_Min*` | (dato) | Según variante | Valor más bajo del grupo. |
## Primero, último y aleatorio [#primero-último-y-aleatorio]
Sin sufijo operan sobre texto (`Aggregate_First`); sufijos `Bool`, `Date`, `DateTime`, `Int`, `Numeric`, `Relation` y `Time` (`Aggregate_FirstDate`, `Aggregate_FirstNumeric`…). Cada variante devuelve su tipo; las `Bool` devuelven Entero (1/0).
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | ---------- | -------------- | --------------------------- |
| `Aggregate_First*` | (dato) | Según variante | Primer valor del grupo. |
| `Aggregate_Last*` | (dato) | Según variante | Último valor del grupo. |
| `Aggregate_Random*` | (dato) | Según variante | Un valor del grupo al azar. |
## Rango de valores [#rango-de-valores]
Sin sufijo opera sobre texto (`Aggregate_Range`); sufijos `Bool`, `Date`, `DateTime`, `Int`, `Numeric` y `Time`. No hay variante de relación. Todas devuelven un texto.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------ | ---------- | -------- | -------------------------------------------- |
| `Aggregate_Range*` | (dato) | Texto | Rango del grupo, del valor mínimo al máximo. |
## Días dentro de un rango [#días-dentro-de-un-rango]
Reciben las dos fechas que delimitan el rango. Variantes `_DateTime` y `_Date` según el tipo del campo.
| Función | Parámetros | Devuelve | Qué hace |
| -------------------------------------- | -------------- | -------- | -------------------------------------------- |
| `Aggregate_CountDaysInRange_*` | (desde, hasta) | Entero | Días dentro del rango de fechas en el grupo. |
| `Aggregate_CountDistinctDaysInRange_*` | (desde, hasta) | Entero | Días distintos dentro del rango en el grupo. |
## Mínimo y máximo de dos valores [#mínimo-y-máximo-de-dos-valores]
No son agregados: comparan dos valores sueltos y devuelven uno. Variantes por tipo: `_Int`, `_Num`, `_Text`, `_Time`, `_Date` y `_DateTime`. Se pueden usar en cualquier contexto DinaScript, no solo en fórmulas de algoritmo.
`Aggregate_Max` devuelve el máximo de un grupo de registros; `Max_Num` devuelve el mayor de dos valores. No son intercambiables.
| Función | Parámetros | Devuelve | Qué hace |
| ------- | ------------- | -------------- | ---------------------------- |
| `Max_*` | (dato, dato2) | Según variante | El mayor de los dos valores. |
| `Min_*` | (dato, dato2) | Según variante | El menor de los dos valores. |
```javascript
@ Limita el descuento entre 0 y 100
num acotado = F.Max_Num(v.descuento, 0)
v.descuento = F.Min_Num(acotado, 100)
```
```javascript
@ El vencimiento nunca cae antes de la fecha de emisión
v.vencimiento = F.Max_Date(v.vencimiento, v.emision)
```
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
# Funciones de controles y listas (/docs/desarrollo/flex/dinascript/funciones/controles-y-listas)
Funciones del espacio `F.` para controlar los campos de un formulario (bloquear, obligar, avisar, sugerir valores) y para operar sobre su lista de registros. Todas ejecutan en scripts de formulario; no están disponibles en fórmulas de algoritmo. Las convenciones comunes (tipos de datos, valores sí/no) están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Bloquear y limitar campos [#bloquear-y-limitar-campos]
Las funciones con parámetro `estado` activan la restricción con `true` y la retiran con `false`. El `motivo` se muestra al usuario cuando intenta saltarse el límite.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------ | -------------------------------------------------------------- |
| `Field_SetLockedWithReason` | (campo, motivo, estado) | — | Bloquea o desbloquea el campo mostrando el motivo. |
| `Field_IsLocked` | (campo) | Entero (1/0) | El campo está bloqueado ahora mismo. |
| `Field_SetMinValueWithReason` / `Field_SetMaxValueWithReason` | (campo, motivo, valor, estado) | — | Impone un valor mínimo o máximo con su motivo. |
| `Field_ForcePositive` / `Field_ForceNegative` | (campo, activado) | — | El campo numérico solo acepta positivos o negativos. |
| `Field_IndirectQuantityLimit` | (campoRelación, campoCantidad, mínimo, máximo, campoLimitado, afectaPositivamente, motivo, activa) | — | Limita una cantidad según el rango de un registro relacionado. |
## Obligar, validar y avisar [#obligar-validar-y-avisar]
| Función | Parámetros | Devuelve | Qué hace |
| ----------------------------- | ----------------------- | ------------ | --------------------------------------------------------- |
| `Field_SetRequiredWithReason` | (campo, motivo, estado) | — | Marca el campo como obligatorio u opcional con su motivo. |
| `Field_IsRequired` | (campo) | Entero (1/0) | El campo es obligatorio ahora mismo. |
| `Field_SetWarningWithReason` | (campo, aviso, estado) | — | Pone o quita un aviso sobre el campo. |
| `Field_ListDropdownWarning` | (aviso, estado) | — | Pone o quita un aviso en la lista desplegable. |
| `CheckFillUnique` | (campo) | Entero (1/0) | El valor del campo no se repite en otros registros. |
```javascript
num esUnica = F.CheckFillUnique("REFERENCIA")
if esUnica = 0
F.Field_SetWarningWithReason("REFERENCIA", "Esta referencia ya existe", true)
F.Field_SetFocus("REFERENCIA", true)
end
```
## Leer y escribir valores [#leer-y-escribir-valores]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------------------------------ | -------------------------- | --------------- | -------------------------------------------------------------------- |
| `Field_Clear` | (campo) | — | Vacía el campo. |
| `Field_ResetToDefault` | (campo) | — | Devuelve el campo a su valor inicial. |
| `Field_SuggestValue` | (campo, sugerencia, clave) | — | Muestra un valor sugerido; la clave permite sustituirlo o retirarlo. |
| `Field_GetInitialTextValue` / `Field_GetInitialNumericValue` | (campo) | Texto / Decimal | Valor guardado del campo, antes de los cambios sin guardar. |
| `Field_GetUnsavedNumericDifference` | (campo) | Decimal | Diferencia entre el valor actual sin guardar y el guardado. |
| `Field_IsModified` | (campo) | Entero (1/0) | El campo ha cambiado desde que se cargó. |
| `Field_IsAffectedBetweenTicks` | (campo) | Entero (1/0) | El campo ha cambiado entre ticks de procesamiento. |
| `Field_RecalculateAlgorithm` | (campo) | — | Fuerza el recálculo del algoritmo asignado al campo. |
| `Field_UrlAssistantReadValue` | (campo, parámetro) | Texto | Lee un parámetro de un campo asistente de URL. |
```javascript
@ Avisa si el ajuste de stock se dispara respecto a lo guardado
num ajuste = F.Field_GetUnsavedNumericDifference("STOCK")
¿ajuste > 100 ? F.Field_SetWarningWithReason("STOCK", "Ajuste inusualmente grande", true)
```
## Etiquetas, foco y aspecto [#etiquetas-foco-y-aspecto]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------ | --------------------------- | -------- | ----------------------------------------------------------------- |
| `Field_SetLabel` | (campo, etiqueta) | — | Cambia la etiqueta visible del campo. |
| `Field_SetExtraIdentifierText` | (campo, etiqueta) | — | Cambia el texto identificador extra del campo. |
| `Field_SetPlaceholder` | (campo, ejemplo) | — | Pone un texto de ejemplo en el campo vacío. |
| `Field_SetFocus` | (campo, seleccionar) | — | Lleva el cursor al campo, con opción de seleccionar su contenido. |
| `Field_CopyIconFromField` | (campoDestino, campoOrigen) | — | Copia el icono de un campo a otro. |
## Desplegables y autocompletado [#desplegables-y-autocompletado]
Las `Field_Dropdown*` sin parámetro de campo actúan sobre el desplegable que se está abriendo.
| Función | Parámetros | Devuelve | Qué hace |
| -------------------------------------------------- | -------------- | -------- | ------------------------------------------------------------ |
| `Field_DropdownApplyFilter` | (campo) | — | Filtra el desplegable según el valor de otro campo. |
| `Field_DropdownApplyAlternative` | () | — | Aplica una fuente de datos alternativa al desplegable. |
| `Field_DropdownApplySearchAlgorithm` | (algoritmo) | — | Aplica un algoritmo de búsqueda al desplegable. |
| `Field_DropdownAutoSelectFirst` | () | — | Selecciona automáticamente el primer elemento. |
| `Field_DropdownAutoSelectIfSingle` | () | — | Selecciona el elemento si el desplegable solo tiene uno. |
| `Field_DropdownCancel` | (motivo) | — | Cancela la apertura del desplegable y muestra el motivo. |
| `Field_DropdownClearFilters` | () | — | Quita todos los filtros aplicados al desplegable. |
| `Field_DropdownEnableFilterRemoval` | (títuloFiltro) | — | Ofrece al usuario quitar el filtro con ese título. |
| `Field_TextEnableCombo` / `Field_TextDisableCombo` | (campo) | — | Activa o desactiva el modo desplegable en un campo de texto. |
| `Field_TextAddAutoComplete` | (campo, valor) | — | Añade un valor memorizado al autocompletado del campo. |
| `Field_TextClearAutoComplete` | (campo) | — | Borra todos los valores memorizados del campo. |
## Relaciones [#relaciones]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------- | ----------------------- | -------- | ----------------------------------------------- |
| `AddRelation` | (campo, modoAutomático) | — | Añade una relación al campo indicado. |
| `Field_CopyOnAddRelation` | (campo, valor) | — | Copia un valor al campo al añadir una relación. |
`Field_CopyOnAddRelation` rellena campos, pero no los bloquea. Si la copia no debe modificarse, bloquea el campo de la sección de destino con `Field_SetLockedWithReason` en el script de esa sección.
## Precios, cronómetros y acciones [#precios-cronómetros-y-acciones]
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------- |
| `RecalculatePrice4F` | (pvpSin, pvpCon, impuestosIncluidos, porcentajeImpuesto) | — | Recalcula PVP sin y con impuestos. |
| `RecalculatePrice5F` | (precio, pvpSin, pvpCon, impuestosIncluidos, porcentajeImpuesto) | — | Como la anterior, con campo de precio combinado. |
| `RecalculatePrice9F` | (precio, pvpSin, pvpCon, dtoFijo, dtoPorciento, subtotal, total, impuestosIncluidos, porcentajeImpuesto) | — | Versión completa: descuentos, subtotal y total. |
| `Field_StopwatchStart` / `Field_StopwatchStop` | (campo) | — | Arranca o para el cronómetro de un campo temporizador. |
| `Field_StopwatchState` | (campo) | Entero | Estado del cronómetro: en marcha o parado. |
| `TriggerClick` | (campo) | — | Dispara el clic de un campo botón. |
| `EnableReportCompatibilityAlgorithm` / `DisableReportCompatibilityAlgorithm` | () | — | Activa o desactiva el algoritmo de compatibilidad de informes. |
## Operar con la lista [#operar-con-la-lista]
Trabajan sobre la lista de registros del formulario: totales y recuentos por columna, y carga o vaciado de la lista completa.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------------- | ---------- | ------------ | ------------------------------------------------------------ |
| `Column_Sum` | (campo) | Decimal | Suma todos los valores de la columna. |
| `Column_CountFilled` | (campo) | Entero | Cuenta los valores no vacíos de la columna. |
| `Column_CountDistinct` | (campo) | Entero | Cuenta los valores distintos de la columna. |
| `Column_CountDistinctFilled` | (campo) | Entero | Cuenta los valores distintos no vacíos. |
| `Column_MaxValue_*` | (campo) | Según sufijo | Valor máximo de la columna. |
| `Column_MinValue_*` | (campo) | Según sufijo | Valor mínimo de la columna. |
| `CountItemList` | () | Entero | Número de elementos de la lista. |
| `List_Count` | () | Entero | Número de registros de la lista. |
| `List_Clear` | () | — | Vacía la lista: elimina todos los registros. |
| `LoadList` | () | Entero | Carga la lista (informe) y devuelve cuántos registros cargó. |
Los sufijos de `Column_MaxValue_*` y `Column_MinValue_*` (`_Numeric`, `_Int`, `_Text`, `_Time`, `_Date`, `_DateTime`) siguen la convención de familias tipadas del [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
```javascript
@ Un pedido sin importe necesita explicación
num total = F.Column_Sum("IMPORTE")
¿total = 0 ? F.Field_SetRequiredWithReason("MOTIVO", "Explica por qué el pedido va sin importe", true)
```
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Funciones de texto](/docs/desarrollo/flex/dinascript/funciones/texto)
# Funciones de datos y listados (/docs/desarrollo/flex/dinascript/funciones/datos-y-listados)
Funciones del espacio `F.` para trabajar con listados de datos: cargar un informe o una sección con filtros, orden y paginación, recorrer sus filas una a una y escribir los valores como celdas de tabla HTML. Las convenciones comunes (tipos de datos, valores sí/no, contextos) están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
Todas las funciones de esta página ejecutan en formularios, en scripts independientes y vía API; no están disponibles en fórmulas de algoritmo. Salvo que se indique otra cosa, el primer parámetro es el GUID del informe o de la sección que alimenta el listado.
## Cargar un listado [#cargar-un-listado]
Carga datos desde un informe o una sección, con paginación, filtros y orden. Es la vía para recorrer registros existentes en lugar de construir una tabla a mano.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------------------- | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `DataListLoad` | (listado, página, resultadosPorPágina) | Entero | Carga el listado: qué página y cuántos resultados por página. |
| `DataListLoadAddFilter` | (listado, campo, operador, valor) | — | Filtra por un campo del informe. Operadores: `=`, `<>`, `>`, `<`, `>=`, `<=`. Con `*` sobre un campo de fecha, el valor es un intervalo. |
| `DataListLoadAddFilterAlternative` | (listado) | — | Añade un criterio de filtrado alternativo al listado. |
| `DataListLoadSetOrder` | (listado, campo, descendente) | — | Ordena por un campo. El tercer parámetro activa el orden descendente. |
| `DataListLoadSelectedItems` | (listado) | Entero | Carga los elementos seleccionados del listado. |
| `DataListApplyDynamicAgruptaion` | (listado) | — | Aplica la agrupación dinámica al listado. |
El filtro se aplica sobre los campos del informe con los operadores de comparación. Para acumular o resumir lo que cargas (un total, una cuenta), recórrelo y combínalo con un [algoritmo](/docs/desarrollo/flex/algoritmos).
## Recorrer las filas [#recorrer-las-filas]
`ProcessDataList_Ini` abre el único bucle de datos de DinaScript: todo lo que escribas entre `ProcessDataList_Ini` y `ProcessDataList_End` se ejecuta una vez por cada fila del listado cargado. Dentro del bloque, las funciones de posición te dicen en qué fila estás.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------ | ---------- | ------------ | --------------------------------------------- |
| `ProcessDataList_Ini` | (keyword) | — | Inicia el recorrido del listado, fila a fila. |
| `ProcessDataList_End` | () | — | Cierra el recorrido. |
| `DataListCurrentRowPosition` | (listado) | Entero | Posición de la fila actual en el listado. |
| `DataListCurrentRowRelativePosition` | (listado) | Entero | Posición relativa de la fila actual. |
| `DataListIsFirstRow` | (listado) | Entero (1/0) | La fila actual es la primera. |
| `DataListIsLastRow` | (listado) | Entero (1/0) | La fila actual es la última. |
```javascript
@ Carga la primera página del informe de ventas: 200 filas por página
F.DataListLoad(v.informeVentas, 1, 200)
F.DataListLoadAddFilter(v.informeVentas, "estado", "=", "pendiente")
F.DataListLoadSetOrder(v.informeVentas, "fecha", true)
num filas = 0
F.ProcessDataList_Ini("ventas")
@ Este bloque se ejecuta una vez por cada fila del listado
v.filas = v.filas + 1
¿F.DataListIsLastRow(v.informeVentas) = 1 ? v.estado = "Recorrido completo"
F.ProcessDataList_End()
```
## Información del listado [#información-del-listado]
Tras cargar, consulta el tamaño y la posición del listado para paginar o decidir si sigues cargando páginas.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------ | ---------- | -------- | ----------------------------------- |
| `DataListCountResults` | (listado) | Entero | Total de resultados. |
| `DataListCountPages` | (listado) | Entero | Total de páginas. |
| `DataListCountFilled` | (listado) | Entero | Número de filas rellenadas. |
| `DataListCurrentPage` | (listado) | Entero | Página actual. |
| `DataListResultsPerPage` | (listado) | Entero | Resultados por página configurados. |
## Escribir celdas de tabla HTML [#escribir-celdas-de-tabla-html]
Vuelcan un valor como celda de una tabla HTML, cada una con su formato. `WriteTD` no escapa el HTML: úsala solo con contenido que controlas; para texto libre, `WriteTDText`.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | -------------------- | -------- | ----------------------------------------------------------- |
| `WriteTD` | (texto) | — | Escribe el texto en la celda sin escapar HTML. |
| `WriteTDText` | (texto) | — | Texto plano: conserva saltos de línea y no interpreta HTML. |
| `WriteTDMoney` | (importe, decimales) | — | Importe con formato de moneda. |
| `WriteTDNum` | (valor, decimales) | — | Número con formato y los decimales indicados. |
| `WriteTDPercentage` | (valor, decimales) | — | Porcentaje formateado. |
## Localizar registros por ID [#localizar-registros-por-id]
Convierten un ID legible en el GUID interno del registro o del archivo, para usarlo después como relación.
| Función | Parámetros | Devuelve | Qué hace |
| ------------- | ------------- | --------------- | -------------------------------------------- |
| `GetRowById` | (sección, id) | Relación (GUID) | GUID del registro de esa sección con ese ID. |
| `GetFileById` | (id) | Relación (GUID) | GUID del archivo con ese ID. |
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Informes](/docs/desarrollo/flex/informes)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
# Funciones de documentos y gráficos (/docs/desarrollo/flex/dinascript/funciones/documentos-y-graficos)
Funciones del espacio `F.` para componer la salida de un documento: tablas en memoria, escritura en el flujo de salida, URLs firmadas de archivos, gráficos y mapas. Se usan sobre todo en [documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos); ninguna vale en fórmulas de algoritmo, y las convenciones comunes están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Tablas en memoria [#tablas-en-memoria]
Tablas que construyes a mano cuando el resultado no sale directo de una sección: creas la tabla, añades filas y rellenas celdas tipadas (el tipo condiciona cómo se formatea y exporta el valor). Funcionan en scripts independientes y en documentos dinámicos; para recorrer registros que ya existen usa [datos y listados](/docs/desarrollo/flex/dinascript/funciones/datos-y-listados).
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------ | ----------------------- | -------- | ------------------------------------------------------ |
| `DataTable_New` | () | Entero | Crea una tabla en memoria y devuelve su identificador. |
| `DataTable_AddRow` | (tabla) | Entero | Añade una fila y devuelve su índice. |
| `DataTable_SetValue` | (tabla, columna, valor) | — | Escribe un valor en una celda. |
| `DataTable_SetValueText` | (tabla, columna, valor) | — | Escribe texto escapando el HTML. |
| `DataTable_SetValueInt` | (tabla, columna, valor) | — | Escribe un entero. |
| `DataTable_SetValueNum` | (tabla, columna, valor) | — | Escribe un decimal. |
| `DataTable_SetValueMoney` | (tabla, columna, valor) | — | Escribe un importe monetario. |
| `DataTable_SetValuePercentage` | (tabla, columna, valor) | — | Escribe un porcentaje. |
| `DataTable_SetValueBool` | (tabla, columna, valor) | — | Escribe un valor sí/no. |
| `DataTable_SetValueDate` | (tabla, columna, valor) | — | Escribe una fecha y ajusta el formato de la columna. |
| `DataTable_SetValueDateTime` | (tabla, columna, valor) | — | Escribe una fecha y hora. |
| `DataTable_SetValueTime` | (tabla, columna, valor) | — | Escribe una hora. |
```javascript
num tabla = F.DataTable_New()
F.DataTable_AddRow(tabla)
F.DataTable_SetValueText(tabla, "Cliente", "Talleres Ruiz")
F.DataTable_SetValueMoney(tabla, "Importe", 1250.50)
txt html = F.DataTable_Build(tabla, "HTML")
```
## Columnas de la tabla [#columnas-de-la-tabla]
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------------- | ------------------------- | -------- | ------------------------------------------------------------------------------ |
| `DataTable_ColumnSetFormat` | (tabla, columna, formato) | — | Asigna el formato de una columna. |
| `DataTable_ColumnSetRole` | (tabla, columna, rol) | — | Asigna el [rol de campo](/docs/desarrollo/flex/roles-de-campo) de una columna. |
| `DataTable_ColumnDelete` | (tabla, columna) | — | Elimina una columna. |
| `DataTable_ColumnDeleteIfIsEmpty` | (tabla, columna) | — | Elimina la columna solo si está vacía. |
## Volcar la tabla [#volcar-la-tabla]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------ | ------------------- | -------- | ------------------------------------------------------------------------- |
| `DataTable_Build` | (tabla, formato) | Texto | Devuelve la tabla como texto: `JSONARRAY`, `JSON`, `HTML`, `CSV` o `XML`. |
| `DataTable_Export` | (tabla, formato) | — | Genera un archivo, preguntando al usuario formato y destino. |
| `DataTable_Import` | (tabla, silencioso) | — | Abre el importador de datos; detecta el informe por los ID de columna. |
`Build` funciona en scripts independientes y documentos dinámicos. `Export` e `Import` solo en el terminal, desde scripts de formulario o independientes.
## Escribir en el documento de salida [#escribir-en-el-documento-de-salida]
En documentos dinámicos y funciones API el resultado se construye escribiendo en un flujo de salida. Estas funciones solo ejecutan ahí.
| Función | Parámetros | Devuelve | Qué hace |
| ----------------- | -------------------------- | -------- | ------------------------------------------------------------------- |
| `Write` | (contenido) | — | Escribe contenido en bruto en la salida. |
| `WriteText` | (texto) | — | Escribe texto plano: conserva saltos de línea y no interpreta HTML. |
| `WriteBool` | (valor, textoSí, textoNo) | — | Escribe un sí/no con el texto que elijas para cada estado. |
| `WriteDate` | (fecha, formato) | — | Escribe una fecha con el formato indicado. |
| `WriteDateTime` | (valor, formato) | — | Escribe una fecha y hora con el formato indicado. |
| `WriteMoney` | (importe, máximoDecimales) | — | Escribe un importe como moneda con N decimales. |
| `WriteNum` | (valor, máximoDecimales) | — | Escribe un número con N decimales. |
| `WritePercentage` | (valor, máximoDecimales) | — | Escribe un porcentaje con N decimales. |
| `RemoveLastWrite` | () | — | Elimina el último elemento escrito en la salida. |
```javascript
F.Write("
Resumen del pedido
")
F.WriteText(v.observaciones)
F.Write("
Total: ")
F.WriteMoney(v.total, 2)
F.Write("
")
```
## Plantillas y metadatos [#plantillas-y-metadatos]
Ejecutan en documentos dinámicos y funciones API (`MetaData_Read` también en scripts independientes).
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------- | --------------------------- | -------- | -------------------------------------------------------------------------- |
| `Include` | (id) | — | Incluye y renderiza una plantilla de impresión HTML por su identificador. |
| `GetDynamicDocumentContent` | (id) | — | Inserta el contenido de un documento dinámico por su identificador. |
| `DataListInfoToHTML` | (informeOSeccionId, estilo) | Texto | Devuelve como HTML la información de un informe o una sección. |
| `RowToJson` | (seccionId) | Texto | Serializa un registro a JSON, sin los textos primarios de datos estáticos. |
| `MetaData_Read` | (clave) | Texto | Lee un parámetro de metadatos por su clave. |
| `MetaData_Set` | (clave, valor) | — | Asigna el valor de un parámetro de metadatos. |
## URLs firmadas de archivos [#urls-firmadas-de-archivos]
Para enseñar un archivo de Dinaup (una imagen, un PDF) a quien no tiene sesión: generan una URL temporal de acceso público. Solo en documentos dinámicos y funciones API.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------- | -------------------------------------------- | -------- | -------------------------------------------------------------------------- |
| `SignFileURL` | (archivoId, tamaño, validezSegundos) | Texto | URL firmada del archivo, accesible sin sesión durante la validez indicada. |
| `SignFileURL_Advanced` | (archivoId, tamaño, validezSegundos, nombre) | Texto | Igual, con nombre de archivo personalizado. |
El parámetro `tamaño` admite los valores `0`, `32`, `100`, `300`, `720` y `1080`.
Cualquiera con la URL accede al archivo sin autenticarse mientras dure la validez. Ajusta los segundos al mínimo que necesites.
## Gráficos [#gráficos]
Montas el gráfico por código y lo vuelcas a HTML para incrustarlo en el documento. Cada serie y valor lleva dos colores: uno para el tema claro y otro para el oscuro. Los gráficos y los mapas funcionan en scripts de formulario, scripts independientes y documentos dinámicos.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------- | --------------------------------------------------- | -------- | ------------------------------------------------------------- |
| `Chart_New` | (título) | Entero | Crea un gráfico y devuelve su identificador. |
| `Chart_AddSerie` | (gráfico, etiqueta, colorClaro, colorOscuro) | — | Añade una serie de datos con sus colores. |
| `Chart_AddValue` | (gráfico, etiqueta, valor, colorClaro, colorOscuro) | — | Añade un valor etiquetado con sus colores. |
| `Chart_ToHTML` | (gráfico, tipo, ancho, alto) | Texto | Devuelve el gráfico como HTML con el tipo y tamaño indicados. |
```javascript
num grafico = F.Chart_New("Ventas del trimestre")
F.Chart_AddValue(grafico, "Enero", 1200, "#2e86c1", "#5dade2")
F.Chart_AddValue(grafico, "Febrero", 1550, "#28b463", "#58d68d")
txt html = F.Chart_ToHTML(grafico, 1, 800, 400)
F.Write(html)
```
## Mapas [#mapas]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------ | ------------------------------------------------------- | -------- | ----------------------------------------------------------------- |
| `Maps_New` | (título) | Entero | Crea un mapa y devuelve su identificador. |
| `Maps_AddPoint` | (mapa, título, icono, ubicación) | — | Añade un punto con etiqueta e icono en las coordenadas indicadas. |
| `Maps_AddClickablePoint` | (mapa, título, icono, ubicación, secciónId, registroId) | — | Punto que al pulsarlo abre un registro de una sección. |
| `Maps_ToHTML` | (mapa, coordenadasIniciales, zoomInicial) | — | Renderiza el mapa como HTML con el centro y zoom iniciales. |
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos)
→ [Funciones de datos y listados](/docs/desarrollo/flex/dinascript/funciones/datos-y-listados)
# Funciones de fecha y hora (/docs/desarrollo/flex/dinascript/funciones/fecha-y-hora)
Funciones del espacio `F.` para trabajar con fechas, horas y periodos: montar y descomponer valores, desplazarlos en el tiempo, medir la distancia entre dos instantes y compararlos con el momento actual. Las convenciones comunes (tipos, sufijos, contextos) están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
Las funciones de «Sumar y restar» y las `GoTo` no ejecutan en fórmulas de algoritmo; el resto de la página sí, salvo las excepciones que marca cada sección.
## Construir fechas y horas [#construir-fechas-y-horas]
| Función | Parámetros | Devuelve | Qué hace |
| ----------------------- | --------------------------------- | ------------ | -------------------------------------------------------- |
| `BuildDate` | (año, mes, día) | Fecha | Monta una fecha desde sus tres componentes. |
| `BuildDateTime` | (año, mes, día, hora, minutos) | Fecha y hora | Monta una fecha y hora desde sus componentes. |
| `BuildTime` | (hora, minutos, segundos) | Hora | Monta una hora desde sus componentes. |
| `AddTimeToDate` | (fecha, tiempo) | Fecha y hora | Combina una fecha con un valor de hora. |
| `AddDetailedTimeToDate` | (fecha, horas, minutos, segundos) | Fecha y hora | Combina una fecha con horas, minutos y segundos sueltos. |
```javascript
@ Fecha del formulario con hora fija
v.cita = F.AddTimeToDate(v.fechaVisita, F.BuildTime(9, 30, 0))
@ cita vale la fecha de la visita a las 9:30:00
```
## Extraer componentes [#extraer-componentes]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------- | ------------ | -------- | ------------------------------------ |
| `Date_FromDatetime` | (fechaYHora) | Fecha | Parte de fecha de un valor con hora. |
| `DalteLocal_FromDatetime` | (fechaYHora) | Fecha | Parte de fecha en hora local. |
| `Time` | (fechaYHora) | Hora | Parte de hora de un valor con fecha. |
| `Year` | (fecha) | Entero | Año de la fecha. |
| `Month` | (fecha) | Entero | Número de mes (1-12). |
| `Day` | (fecha) | Entero | Día del mes. |
| `Hour` | (hora) | Entero | Hora de un valor de tipo Hora. |
| `Minute` | (hora) | Entero | Minutos de un valor de tipo Hora. |
Todas valen en fórmulas de algoritmo salvo `DalteLocal_FromDatetime`.
## Sumar y restar [#sumar-y-restar]
Cada función devuelve el mismo tipo que recibe: `Date_` una Fecha, `DateTime_` una Fecha y hora, `Time_` una Hora.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------------------------------- | ---------------- | -------------------- | -------------------------------------------------- |
| `Date_AddDays` / `DateTime_AddDays` | (fecha, días) | Fecha · Fecha y hora | Suma días. |
| `Date_AddMonths` / `DateTime_AddMonths` | (fecha, meses) | Fecha · Fecha y hora | Suma meses. |
| `Date_AddYears` / `DateTime_AddYears` | (fecha, años) | Fecha · Fecha y hora | Suma años. |
| `DateTime_AddHours` / `Time_AddHours` | (valor, horas) | Fecha y hora · Hora | Suma horas; un valor decimal se redondea a entero. |
| `DateTime_AddMinutes` / `Time_AddMinutes` | (valor, minutos) | Fecha y hora · Hora | Suma minutos; admite decimales. |
| `Date_SubtractDays` / `DateTime_SubtractDays` | (fecha, días) | Fecha · Fecha y hora | Resta días. |
| `Date_SubtractMonths` / `DateTime_SubtractMonths` | (fecha, meses) | Fecha · Fecha y hora | Resta meses. |
| `Date_SubtractYears` / `DateTime_SubtractYears` | (fecha, años) | Fecha · Fecha y hora | Resta años. |
| `DateTime_SubtractHours` / `Time_SubtractHours` | (valor, horas) | Fecha y hora · Hora | Resta horas. |
| `DateTime_SubtractMinutes` / `Time_SubtractMinutes` | (valor, minutos) | Fecha y hora · Hora | Resta minutos. |
```javascript
@ Vencimiento a 30 días y aviso una semana antes
v.vencimiento = F.Date_AddDays(v.fechaFactura, 30)
v.aviso = F.Date_SubtractDays(v.vencimiento, 7)
```
## Funciones GoTo: cambiar componentes y saltar de periodo [#funciones-goto-cambiar-componentes-y-saltar-de-periodo]
Mueven una fecha a un punto concreto del calendario. Para cambiar un componente suelto:
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------------- | ----------------------- | -------------------- | ---------------------------------------------------------- |
| `Date_GoToDay` / `DateTime_GoToDay` | (valor, nuevoDía) | Fecha · Fecha y hora | Cambia el día; si el mes no llega, salta al mes siguiente. |
| `Date_GoToMonth` / `DateTime_GoToMonth` | (valor, nuevoMes) | Fecha · Fecha y hora | Cambia el mes. |
| `Date_GoToYear` / `DateTime_GoToYear` | (valor, nuevoAño) | Fecha · Fecha y hora | Cambia el año. |
| `DateTime_GoToHour` / `Time_GoToHour` | (valor, nuevaHora) | Fecha y hora · Hora | Cambia la hora. |
| `DateTime_GoToMinutes` / `Time_GoToMinutes` | (valor, nuevosMinutos) | Fecha y hora · Hora | Cambia los minutos. |
| `DateTime_GoToSeconds` / `Time_GoToSeconds` | (valor, nuevosSegundos) | Fecha y hora · Hora | Cambia los segundos. |
| `DateTime_GoToDate` | (fechaYHora, fecha) | Fecha y hora | Sustituye la parte de fecha conservando la hora. |
| `DateTime_GoToTime` | (fechaYHora, hora) | Fecha y hora | Sustituye la parte de hora conservando la fecha. |
Para saltar al inicio o al final de un periodo. La tabla muestra la variante `Date_`, que recibe Fecha; cambia el prefijo a `DateTime_` para la que recibe Fecha y hora.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------------------------- | ---------- | ------------ | ------------------------------------------------ |
| `Date_GoToStartDay` / `Date_GoToEndDay` | (fecha) | Fecha y hora | Inicio o final del día. |
| `Date_GoToStartWeekMonday` / `Date_GotoEndSunday` | (fecha) | Fecha y hora | Lunes al inicio o domingo al final de la semana. |
| `Date_GoToStartOfFortnight` / `Date_GoToEndOfFortnight` | (fecha) | Fecha y hora | Inicio o final de la quincena. |
| `Date_GoToStartOfMonth` / `Date_GoToEndOfMonth` | (fecha) | Fecha y hora | Primer o último día del mes. |
| `Date_GoToStartOfQuarter` / `Date_GoToEndQuarter` | (fecha) | Fecha y hora | Inicio o final del trimestre. |
| `Date_GoToStartSemester` / `Date_GoToEndSemester` | (fecha) | Fecha y hora | Inicio o final del semestre. |
| `Date_GoToStartYear` / `Date_GoToEndYear` | (fecha) | Fecha y hora | 1 de enero o 31 de diciembre del año. |
Las variantes `Date_` de esta tabla también devuelven **Fecha y hora**, no Fecha: apuntan a un instante concreto, como las 23:59:59 del último día del periodo.
```javascript
@ Límites del mes de la fecha del pedido
v.desde = F.Date_GoToStartOfMonth(v.fechaPedido)
v.hasta = F.Date_GoToEndOfMonth(v.fechaPedido)
@ hasta apunta al último día del mes a las 23:59:59
```
## Diferencias entre fechas [#diferencias-entre-fechas]
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------------------- | -------------------------------------- | -------- | --------------------------------------------------------------------------------- |
| `DaysDifferenceBetweenDates` | (primeraFecha, segundaFecha) | Entero | Días entre dos fechas; positivo si la segunda es posterior. |
| `MinutesDifferenceBetweenDates` | (primeraFecha, segundaFecha) | Entero | Minutos entre dos fechas. |
| `MinutesDifferenceBetweenDatesAndTimes` | (primeraFechaYHora, segundaFechaYHora) | Entero | Minutos entre dos valores de fecha y hora. |
| `MinutesDifferenceBetweenTimes` | (primeraHora, segundaHora) | Entero | Minutos entre dos horas. |
| `SecondsDifferenceBetweenDatesAndTimes` | (primeraFechaYHora, segundaFechaYHora) | Entero | Segundos entre dos valores de fecha y hora. |
| `SecondsDifferenceBetweenTimes` | (primeraHora, segundaHora) | Entero | Segundos entre dos horas. |
| `CalculateAge` | (primeraFecha, segundaFecha) | Entero | Edad en años entre dos fechas. |
| `CalculateAge_WithDateTime` | (primeraFechaYHora, segundaFechaYHora) | Entero | Edad en años entre dos valores de fecha y hora. |
| `CalculateSeniorityDate` | (fechaAntigüedad, modoAntigüedad) | Fecha | Fecha de referencia de antigüedad según el modo (inicio de mes, trimestre o año). |
Todas valen en fórmulas de algoritmo salvo `CalculateSeniorityDate`.
## Semana y calendario [#semana-y-calendario]
| Función | Parámetros | Devuelve | Qué hace |
| -------------------------- | ------------------------- | ------------ | -------------------------------------------------------------- |
| `DayOfWeek` | (fecha) | Entero | Día de la semana: 1=lunes … 7=domingo. |
| `NameDayOfWeek_FromDate` | (fecha) | Texto | Nombre del día de la semana. |
| `NameDayOfWeek_FromNumber` | (díaSemana) | Texto | Nombre del día desde su número (1=lunes … 7=domingo). |
| `MonthName_FromDate` | (fecha) | Texto | Nombre del mes de la fecha. |
| `MonthName_FromInt` | (mes) | Texto | Nombre del mes desde su número (1-12). |
| `WeekOfMonth` | (fecha) | Entero | Semana del mes (1-5). |
| `Fortnight` | (fecha) | Entero | Quincena (1 o 2); el corte es el día 15. |
| `Bimester` | (fecha) | Entero | Bimestre del año (1-6). |
| `Quarter` | (fecha) | Entero | Trimestre del año (1-4). |
| `Semester` | (fecha) | Entero | Semestre del año (1 o 2). |
| `DaysInMonth_FromDate` | (fecha) | Entero | Días que tiene el mes de la fecha. |
| `DaysInMonth_FromNumber` | (año, mes) | Entero | Días que tiene un mes dado por año y número. |
| `IsLeapYear_FromDate` | (fecha) | Entero (1/0) | El año de la fecha es bisiesto. |
| `IsLeapYear_FromNumber` | (año) | Entero (1/0) | El año es bisiesto. |
| `IsQuarter` | (fecha, trimestre) | Entero (1/0) | La fecha cae en el trimestre indicado. |
| `IsYear` | (fecha, año) | Entero (1/0) | La fecha cae en el año indicado. |
| `CountWeeklyDaysInRange` | (desde, hasta, díaSemana) | Entero | Cuenta cuántas veces cae un día de la semana entre dos fechas. |
Todas valen en fórmulas de algoritmo salvo `CountWeeklyDaysInRange`.
## Eventos respecto al momento actual [#eventos-respecto-al-momento-actual]
Comprueban dónde cae un evento respecto a ahora y devuelven Entero (`1`/`0`), listas para usar en condiciones. Cada familia existe en cinco unidades (cambia `Days` por `Hours`, `Minutes`, `Months` o `Years` en el nombre) y con sufijo de tipo: `_Date` y `_DateTime` para días, meses y años; `_Time` y `_DateTime` para horas y minutos. La leyenda de sufijos está en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
| Función | Parámetros | Devuelve | Qué hace |
| -------------------------------------------- | ------------------ | ------------ | -------------------------------------------------------- |
| `EventStartedLessThanXDaysAgo_*` | (valor, intervalo) | Entero (1/0) | El evento ocurrió hace menos de N días. |
| `EventStartedMoreThanXDaysAgo_*` | (valor, intervalo) | Entero (1/0) | El evento ocurrió hace más de N días. |
| `EventStartsInLessThanXDays_*` | (valor, intervalo) | Entero (1/0) | El evento llega dentro de los próximos N días. |
| `EventStartsInMoreThanXDays_*` | (valor, intervalo) | Entero (1/0) | El evento está a más de N días vista. |
| `EventStartedOrEventStartsInLessThanXDays_*` | (valor, intervalo) | Entero (1/0) | El evento ocurrió o llega dentro de un margen de N días. |
```javascript
@ Clasificar clientes por su última compra
¿F.EventStartedMoreThanXMonthsAgo_Date(v.ultimaCompra, 6) = 1 ? v.estado = "Inactivo"
¿F.EventStartedLessThanXDaysAgo_Date(v.ultimaCompra, 30) = 1 ? v.estado = "Activo"
```
## Rangos dinámicos e intervalos [#rangos-dinámicos-e-intervalos]
Comprueban valores contra rangos dinámicos e intervalos definidos en tu cuenta, y obtienen sus fechas límite.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------- | ------------------------ | ------------ | --------------------------------------------------------------------------------- |
| `InDynamicRange_*` | (valor, intervalo) | Entero (1/0) | El valor cae dentro del rango dinámico. Sufijos `_Date` y `_DateTime`. |
| `InRange_DateTime_DateOnly` | (fechaYHora, intervalo) | Fecha y hora | Comprueba si el valor cae en el intervalo, comparando solo la fecha. |
| `IntervalStartDate_*` | (intervalo) | Según sufijo | Fecha de inicio del intervalo, como Fecha (`_Date`) o Fecha y hora (`_DateTime`). |
| `IntervalEndDate_*` | (intervalo) | Según sufijo | Fecha de fin del intervalo. |
| `IsInInterval_*` | (valor, intervaloRápido) | Entero (1/0) | El valor cae dentro del intervalo rápido indicado. Sufijos `_Date` y `_DateTime`. |
Todas valen en fórmulas de algoritmo; `IsInInterval_*` no está disponible en funciones API.
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Algoritmos](/docs/desarrollo/flex/algoritmos)
→ [DinaScript](/docs/desarrollo/flex/dinascript)
# Funciones (espacio F.) (/docs/desarrollo/flex/dinascript/funciones)
El espacio **`F.`** reúne todas las funciones de DinaScript. Llamas a cualquiera anteponiendo `F.` al nombre y, si devuelve un valor, lo asignas a una variable.
```javascript
txt etiqueta = F.Concat2("Pedido ", "1024")
num total = F.Round(1250.505, 2)
```
## Categorías [#categorías]
| Página | Qué encuentras |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| [Texto](/docs/desarrollo/flex/dinascript/funciones/texto) | Combinar, buscar, trocear y formatear texto. Diccionarios en memoria, JSON y NIF. |
| [Fecha y hora](/docs/desarrollo/flex/dinascript/funciones/fecha-y-hora) | Construir fechas, sumar periodos, saltar a inicios de mes, diferencias e intervalos. |
| [Lógica y comparación](/docs/desarrollo/flex/dinascript/funciones/logica-y-comparacion) | Condiciones en línea: If, Case y comparaciones tipadas. |
| [Matemáticas y conversión](/docs/desarrollo/flex/dinascript/funciones/matematicas-y-conversion) | Redondeo, porcentajes, signo y conversión entre tipos. |
| [Agregación](/docs/desarrollo/flex/dinascript/funciones/agregacion) | Sumas, cuentas, medias y extremos sobre grupos de registros, para fórmulas de algoritmo. |
| [Datos y listados](/docs/desarrollo/flex/dinascript/funciones/datos-y-listados) | Cargar registros de un informe o sección y recorrerlos con filtros, orden y paginación. |
| [Interacción y formulario](/docs/desarrollo/flex/dinascript/funciones/interaccion-y-formulario) | Mensajes, preguntas al usuario, abrir recursos y actuar sobre el formulario abierto. |
| [Controles y listas](/docs/desarrollo/flex/dinascript/funciones/controles-y-listas) | Bloquear, ocultar, obligar y colorear campos; operar con el grid del formulario. |
| [Documentos y gráficos](/docs/desarrollo/flex/dinascript/funciones/documentos-y-graficos) | Tablas en memoria, escritura al documento de salida, URLs firmadas de archivos y gráficos. |
| [Sistema y seguridad](/docs/desarrollo/flex/dinascript/funciones/sistema-y-seguridad) | Crear y modificar registros por script, peticiones HTTP, hashes, QR, TOTP y contabilidad. |
## Tipos de datos [#tipos-de-datos]
Las firmas de cada función usan estos tipos:
| Tipo | Qué es |
| --------------------------- | -------------------------------------------- |
| Texto | Cadena de caracteres, entre comillas dobles. |
| Entero | Número sin decimales. |
| Decimal | Número con decimales. |
| Sí/No | Booleano: `true` o `false`. |
| Fecha · Hora · Fecha y hora | Valores temporales. |
| Relación (GUID) | Identificador de un registro. |
Muchas funciones de comprobación devuelven **Entero (1/0)**: `1` si se cumple, `0` si no. Se usan directo en condiciones.
## Familias tipadas [#familias-tipadas]
Cuando una operación existe para varios tipos, la función se repite con un sufijo por tipo y en la referencia aparece como `Nombre_*`:
| Sufijo | Tipo |
| ----------- | --------------- |
| `_Text` | Texto |
| `_Int` | Entero |
| `_Num` | Decimal |
| `_Bool` | Sí/No |
| `_Date` | Fecha |
| `_DateTime` | Fecha y hora |
| `_Time` | Hora |
| `_Relation` | Relación (GUID) |
Ejemplo: `Case2_*` existe como `Case2_Text`, `Case2_Int`, `Case2_Num`, `Case2_Date`, `Case2_DateTime` y `Case2_Time`. Elige la variante del tipo que devuelve.
## Dónde ejecuta cada función [#dónde-ejecuta-cada-función]
No todas las funciones valen en todos los contextos. Los cuatro hábitats:
* **Fórmulas de algoritmo**: cálculos sobre tus datos. Ver [algoritmos](/docs/desarrollo/flex/algoritmos).
* **Scripts de formulario**: reaccionan a eventos de la ventana en la aplicación. Ver [scripts](/docs/desarrollo/flex/scripts).
* **Scripts independientes**: se lanzan a demanda, sin formulario abierto.
* **Documentos dinámicos y funciones API**: generan salida HTML, JSON o archivos. Ver [documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos).
Cada página de categoría indica el contexto cuando importa: por ejemplo, las funciones de controles solo tienen sentido con un formulario abierto, y las de agregación solo dentro de un algoritmo.
***
→ [Índice de DinaScript](/docs/desarrollo/flex/dinascript)
→ [Espacio de nombres S. (Schema)](/docs/desarrollo/flex/dinascript/s.-espacio-de-nombre-schema)
# Funciones de interacción y formulario (/docs/desarrollo/flex/dinascript/funciones/interaccion-y-formulario)
Funciones del espacio `F.` para dialogar con el usuario (mensajes, preguntas, abrir informes y formularios) y para actuar sobre el formulario abierto: guardar, disparar scripts, dar altas. Ejecutan en scripts del Terminal (de formulario o independientes), no en fórmulas de algoritmo; las convenciones comunes están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Mensajes y confirmaciones [#mensajes-y-confirmaciones]
El parámetro `acciónRest` indica la acción a aplicar cuando el script se ejecuta en emulación REST.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | ------------------------------ | ------------ | ------------------------------------------------------ |
| `MsgBox` | (texto, acciónRest) | — | Muestra un mensaje al usuario. |
| `PromptYesNo` | (título, pregunta, acciónRest) | Entero (1/0) | Pregunta Sí/No: devuelve `1` Sí, `0` No. |
| `PromptYesNoCancel` | (título, pregunta, acciónRest) | Entero | Pregunta Sí/No/Cancelar: `1` Sí, `0` No, `2` Cancelar. |
```javascript
num confirmar = F.PromptYesNo("Facturación", "¿Generar la factura?", 0)
¿v.confirmar = 0 ? F.CancelEvent()
```
## Pedir datos al usuario [#pedir-datos-al-usuario]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------ | ------------------------------------- | --------------- | ------------------------------------------------------------------------- |
| `PromptDecimalNumber` | (título, pregunta) | Decimal | Pide un número decimal y lo devuelve. |
| `PromptIntegerNumber` | (título, pregunta) | Entero | Pide un número entero y lo devuelve. |
| `PromptRecord` | (título, pregunta, sección) | Texto | Pide elegir un registro de la sección; devuelve su identificador. |
| `PromptRecordFromLoadedReport` | (título, pregunta, informeIdOSección) | Relación (GUID) | Pide elegir un registro de un informe cargado; devuelve su identificador. |
```javascript
num total = F.PromptDecimalNumber("Caja", "Importe contado al cierre")
F.MsgBox(F.Concat("Contado: ", F.FormatMoney(v.total)), 0)
```
## Abrir recursos [#abrir-recursos]
Abren un recurso de Dinaup identificándolo por su GUID.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------- | ------------ | -------- | --------------------------------------------------------------- |
| `OpenForm` | (sección) | — | Abre el formulario para ver o editar un registro de la sección. |
| `OpenReport` | (informeId) | — | Abre un informe por su identificador. |
| `OpenDynamicDocument` | (funciónApi) | — | Abre el documento dinámico que genera una función de API. |
## Acciones sobre el formulario actual [#acciones-sobre-el-formulario-actual]
Actúan sobre el registro abierto. Solo en scripts de formulario.
| Función | Parámetros | Devuelve | Qué hace |
| -------------------------- | ---------- | ------------ | ------------------------------------------------------------- |
| `Save` | () | — | Guarda el registro actual del formulario. |
| `CancelEvent` | () | — | Cancela el evento en curso e impide que continúe. |
| `CalculatePurchase` | () | — | Ejecuta el cálculo de compra del registro actual. |
| `CalculateSale` | () | — | Ejecuta el cálculo de venta del registro actual. |
| `Form_EnableSequentialAdd` | (activado) | Entero | Activa o desactiva el modo de alta secuencial del formulario. |
| `IsNew` | () | Entero (1/0) | El registro actual es nuevo. |
| `IsNew_Sequential` | () | Entero (1/0) | El registro se creó en modo de alta secuencial. |
| `IsVirtualForm` | () | Entero (1/0) | El formulario actual es virtual. |
## Disparadores y cambios de campo [#disparadores-y-cambios-de-campo]
Declaran cuándo se dispara el script y leen el valor implicado en el cambio.
| Función | Parámetros | Devuelve | Qué hace |
| ----------------------- | ---------- | -------- | ------------------------------------------------------------ |
| `InitializeTrigger` | (evento) | — | Inicializa el disparador del script para el evento indicado. |
| `TriggerOnFieldChange` | (campoId) | — | Dispara el script cuando cambia el campo indicado. |
| `TriggerIfFieldsFilled` | (campoId) | — | Dispara el script solo si el campo indicado tiene valor. |
| `TriggerIfNewRecord` | () | Sí/No | Dispara el script solo si el registro es nuevo. |
| `GetNewFieldValue` | (campoId) | Texto | Devuelve el valor nuevo del campo. |
| `GetPreviousFieldValue` | (campoId) | Texto | Devuelve el valor anterior del campo. |
```javascript
@ Corre solo cuando cambia el campo Estado
F.TriggerOnFieldChange(S.Fields.Pedidos.Estado.ID)
txt anterior = F.GetPreviousFieldValue(S.Fields.Pedidos.Estado.ID)
txt nuevo = F.GetNewFieldValue(S.Fields.Pedidos.Estado.ID)
```
## Alta de registros desde el script [#alta-de-registros-desde-el-script]
Dan de alta un registro por pasos: abres el alta, asignas campos y la confirmas. Solo en scripts de formulario.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------------- | -------------- | -------- | ----------------------------------------------------------------------------------- |
| `AddElement_Begin` | (sección) | — | Inicia el alta de un registro en la sección indicada. |
| `AddElement_SetValue` | (campo, valor) | — | Asigna el valor de un campo del alta en curso. El tipo del valor depende del campo. |
| `AddElement_Commit` | () | — | Finaliza el alta sin aceptar automáticamente el registro. |
| `AddElement_CommitAndAccept` | () | — | Finaliza el alta y acepta (guarda) el registro. |
## Destinadores y catálogos [#destinadores-y-catálogos]
Leen cantidades de un destinador de destino y controlan qué se muestra en el formulario. Solo en scripts de formulario.
| Función | Parámetros | Devuelve | Qué hace |
| ----------------------------- | ---------------------- | -------- | ------------------------------------------------------- |
| `Allocator_SourceQuantity` | () | Decimal | Cantidad de origen del destinador. |
| `Allocator_CompletedQuantity` | () | Decimal | Cantidad ya completada del destinador. |
| `Allocator_PendingQuantity` | () | Decimal | Cantidad pendiente del destinador. |
| `Allocator_RenderGeneric` | () | — | Pinta la representación visual genérica del destinador. |
| `Allocator_SetHidden` | (destinadorId, estado) | Entero | Oculta o muestra un destinador por su ID. |
| `Catalog_SetDisabled` | (catálogo, estado) | Entero | Desactiva o activa un catálogo por su ID. |
## Email y sistema [#email-y-sistema]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------- | ------------------------------ | -------- | -------------------------------------------------------------------------- |
| `EmailSend` | (origen, destino) | — | Envía un email desde la cuenta de origen a la dirección de destino. |
| `EmailSendReply` | (origen, destino, respuestaA) | — | Envía una respuesta enlazada al email original. |
| `EmailSend_CurrentBuffer` | () | — | Envía el documento actual por email. |
| `CurrencyChange` | (isoOrigen, isoDestino, fecha) | Decimal | Tipo de cambio entre dos divisas ISO en la fecha dada. |
| `OSRunCMD` | (comando, esperar, timeoutMs) | — | Ejecuta un comando del sistema operativo, con espera y timeout opcionales. |
`EmailSend` y `EmailSendReply` ejecutan solo en scripts de formulario; el resto también vale en scripts independientes.
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Funciones de texto](/docs/desarrollo/flex/dinascript/funciones/texto)
# Funciones de lógica y comparación (/docs/desarrollo/flex/dinascript/funciones/logica-y-comparacion)
Funciones del espacio `F.` para comparar valores y decidir resultados: igualdad, mayor/menor, rangos, condicionales de dos salidas y cadenas de casos. Casi todas son familias tipadas: el sufijo (`_Int`, `_Num`, `_Text`, `_Time`, `_Date`, `_DateTime`) indica el tipo de dato de cada variante. La leyenda de sufijos y las convenciones comunes están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Comparar dos valores [#comparar-dos-valores]
Cada comparación existe en dos formas con el mismo comportamiento: `Is…` devuelve Entero (`1`/`0`) y `Check…` devuelve Sí/No. Elige según el tipo que espere tu fórmula o campo.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------------------ | ---------------- | -------------------- | ------------------------------------------ |
| `IsEquals_*` / `CheckEquals_*` | (valor1, valor2) | Entero (1/0) · Sí/No | Los dos valores son iguales. |
| `IsDistinct_*` / `CheckDistinct_*` | (valor1, valor2) | Entero (1/0) · Sí/No | Los dos valores son distintos. |
| `IsGreater_*` / `CheckGreater_*` | (valor1, valor2) | Entero (1/0) · Sí/No | El primero es mayor que el segundo. |
| `IsGreaterOrEquals_*` / `CheckGreaterOrEquals_*` | (valor1, valor2) | Entero (1/0) · Sí/No | El primero es mayor o igual. |
| `IsSmaller_*` / `CheckSmaller_*` | (valor1, valor2) | Entero (1/0) · Sí/No | El primero es menor. |
| `IsSmallerOrEquals_*` / `CheckSmallerOrEquals_*` | (valor1, valor2) | Entero (1/0) · Sí/No | El primero es menor o igual. |
| `IsExact_*` | (valor1, valor2) | Entero (1/0) | Igualdad estricta, con comparación exacta. |
| `IsExactDirect_*` | (valor1, valor2) | Sí/No | Como `IsExact_*`, pero devuelve Sí/No. |
Sufijos disponibles: `_Int`, `_Num`, `_Text`, `_Time`, `_Date`, `_DateTime`.
```javascript
¿F.IsGreater_Num(v.total, 3000) = 1 ? v.descuento = 5
```
## Vacío o relleno [#vacío-o-relleno]
Solo existen para `_Text`, `_Time`, `_Date` y `_DateTime`. Misma pareja `Is…`/`Check…` que arriba.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------------------- | ---------- | -------------------- | --------------------------- |
| `IsEmpty_*` / `CheckEmpty_*` | (valor) | Entero (1/0) · Sí/No | El valor está vacío o nulo. |
| `IsNotEmpty_*` / `CheckNotEmpty_*` | (valor) | Entero (1/0) · Sí/No | El valor está relleno. |
## Rangos [#rangos]
Sufijos disponibles: `_Int`, `_Num`, `_Time`, `_Date`, `_DateTime` (sin variante de texto).
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------- | ----------------------------------------------------- | ------------ | ----------------------------------------------------- |
| `Between_MinMax_*` | (valor, desde, hasta) | Entero (1/0) | El valor cae dentro del rango, extremos incluidos. |
| `Between_MinMax_Advanced_*` | (valor, desde, desdeInclusive, hasta, hastaInclusive) | Entero (1/0) | Como la anterior, pero eliges si cada extremo cuenta. |
| `Intersect_*` | (rango1Desde, rango1Hasta, rango2Desde, rango2Hasta) | Entero (1/0) | Los dos rangos se solapan. |
## Buscar en una lista [#buscar-en-una-lista]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | -------------- | ------------ | --------------------------------------------- |
| `ExistIn_*` | (valor, lista) | Entero (1/0) | El valor está en la lista separada por comas. |
| `ExistIn_Reference` | (valor, lista) | Entero (1/0) | Igual, para relaciones (GUID). |
A diferencia del resto de la página, `ExistIn_*` y `ExistIn_Reference` solo ejecutan en fórmulas de algoritmo y vía API, no en formularios.
## Elegir entre dos valores [#elegir-entre-dos-valores]
El condicional básico: una condición Sí/No y dos posibles resultados.
| Función | Parámetros | Devuelve | Qué hace |
| ------------ | ------------------------------- | ------------ | ---------------------------------------------- |
| `If_*` | (condición, opciónSí, opciónNo) | Según sufijo | Devuelve una opción u otra según la condición. |
| `If_Numeric` | (condición, opciónSí, opciónNo) | Decimal | Versión decimal del condicional. |
`If_*` existe con sufijos `_Int`, `_Text`, `_Time`, `_Date` y `_DateTime`; para decimales usa `If_Numeric`.
## Comparar y elegir en una llamada [#comparar-y-elegir-en-una-llamada]
La familia `If___` combina comparación y condicional: compara dos valores del primer tipo y devuelve uno de dos resultados del segundo. Por ejemplo, `If_Num_IsGreater_Text` compara dos decimales y devuelve un texto.
| Comparación | Parámetros | Devuelve el valor Sí cuando… |
| ---------------------------- | --------------------------------------- | ------------------------------ |
| `If__IsEquals_*` | (valor1, valor2, valorSí, valorNo) | Los dos valores son iguales. |
| `If__IsDistinct_*` | (valor1, valor2, valorSí, valorNo) | Son distintos. |
| `If__IsGreater_*` | (valor1, valor2, valorSí, valorNo) | El primero es mayor. |
| `If__IsGreaterOrEquals_*` | (valor1, valor2, valorSí, valorNo) | El primero es mayor o igual. |
| `If__IsSmaller_*` | (valor1, valor2, valorSí, valorNo) | El primero es menor. |
| `If__IsSmallerOrEquals_*` | (valor1, valor2, valorSí, valorNo) | El primero es menor o igual. |
| `If__Between_*` | (valor, desde, hasta, valorSí, valorNo) | El valor cae dentro del rango. |
| `If__IsEmpty_*` | (valor, valorSí, valorNo) | El valor está vacío o nulo. |
| `If__IsNotEmpty_*` | (valor, valorSí, valorNo) | El valor está relleno. |
`` es el tipo comparado (`Int`, `Num`, `Text`, `Time`, `Date`, `DateTime`) y `*` el sufijo del tipo devuelto (`_Int`, `_Num`, `_Text`, `_Time`, `_Date`, `_DateTime`). Dos excepciones: `Between` no existe para `Text`, y `IsEmpty`/`IsNotEmpty` no existen para `Int` ni `Num`.
```javascript
txt aviso = F.If_Num_IsGreater_Text(v.total, 5000, "Revisar con dirección", "")
@ compara dos decimales y devuelve un texto
```
## Encadenar varios casos [#encadenar-varios-casos]
Las familias `Case2_*` a `Case10_*` encadenan de 2 a 10 pares evaluación-valor más un valor por defecto. Cada evaluación es un Entero (`1`/`0`), normalmente el resultado de una función `Is…`. Gana el primer par cuya evaluación se cumple; si ninguna se cumple, se devuelve `otro`.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------------- | --------------------------------------------------- | ------------ | ------------------------------------------------ |
| `Case2_*` … `Case10_*` | (evaluación1, valor1, …, evaluaciónN, valorN, otro) | Según sufijo | El valor del primer par que se cumple, u `otro`. |
Sufijos disponibles: `_Int`, `_Num`, `_Text`, `_Time`, `_Date`, `_DateTime` (tipo de los valores devueltos).
```javascript
txt tramo = F.Case2_Text(F.IsSmaller_Num(v.total, 100), "Pequeño", F.IsSmaller_Num(v.total, 1000), "Medio", "Grande")
@ menor de 100: "Pequeño" · menor de 1000: "Medio" · resto: "Grande"
```
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Funciones de texto](/docs/desarrollo/flex/dinascript/funciones/texto)
# Funciones matemáticas y de conversión (/docs/desarrollo/flex/dinascript/funciones/matematicas-y-conversion)
Funciones del espacio `F.` para operar con números y cambiar valores de tipo: redondeo, porcentajes, signo y conversiones. Todas ejecutan en cualquier contexto (fórmulas de algoritmo, formularios, campos independientes y API) salvo las excepciones marcadas en la última sección. Las convenciones comunes están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
¿Buscas el máximo o el mínimo de varios valores? Esas funciones (`Max_*`, `Min_*`) viven en [funciones de agregación](/docs/desarrollo/flex/dinascript/funciones/agregacion).
## Redondeo [#redondeo]
Cuatro criterios distintos para quitar decimales. Elige según hacia dónde quieres que caiga el resultado.
| Función | Parámetros | Devuelve | Qué hace |
| --------------- | ------------------ | -------- | --------------------------------------------------- |
| `Round` | (valor, decimales) | Decimal | Redondea al número de decimales indicado. |
| `Cast_NumToInt` | (valor) | Entero | Redondea al entero más cercano. |
| `Truncate` | (valor) | Entero | Parte entera: descarta los decimales sin redondear. |
| `Ceiling` | (valor) | Entero | Entero igual o superior más cercano. |
| `Floor` | (valor) | Entero | Entero igual o inferior más cercano. |
```javascript
num redondeado = F.Round(12.68, 1)
@ redondeado vale 12.7
num entero = F.Truncate(12.68)
@ entero vale 12; F.Ceiling(12.68) daría 13
```
## Porcentajes [#porcentajes]
Aplican o deshacen un porcentaje sin escribir la fórmula a mano.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------- | ----------------------------- | -------- | -------------------------------------------------------------- |
| `PercentageIncrease` | (valor, porcentaje) | Decimal | Incrementa el valor en el porcentaje dado. |
| `PercentageDecrease` | (valor, porcentaje) | Decimal | Reduce el valor en el porcentaje dado. |
| `PercentageReverse` | (valor, porcentaje) | Decimal | Deshace un porcentaje ya aplicado y devuelve la base original. |
| `CalculatePreDiscountValue` | (valorReferencia, porcentaje) | Decimal | Valor previo a un descuento del porcentaje indicado. |
| `PercentageDifference` | (dato, referencia) | Decimal | Diferencia porcentual entre un dato y su referencia. |
`PercentageReverse` no es lo mismo que `PercentageDecrease`: uno deshace, el otro resta.
```javascript
num conIva = F.PercentageIncrease(100, 21)
@ conIva vale 121
num base = F.PercentageReverse(conIva, 21)
@ base vale 100; F.PercentageDecrease(121, 21) daría 95.59
```
## Signo [#signo]
Fuerzan el signo de un número sin condicionales.
| Función | Parámetros | Devuelve | Qué hace |
| ---------------- | ---------- | -------- | ----------------------------------------------------- |
| `EnsurePositive` | (valor) | Decimal | Devuelve el valor en positivo, sea cual sea su signo. |
| `EnsureNegative` | (valor) | Decimal | Devuelve el valor en negativo, sea cual sea su signo. |
## Convertir entre tipos [#convertir-entre-tipos]
Pasan valores de un tipo a otro y comprueban si un texto es convertible.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------- | -------------------- | ------------ | ------------------------------------------------------------ |
| `Cast_TextToNum` | (valor) | Decimal | Convierte un texto en número decimal. |
| `Cast_TextToInt` | (valor) | Entero | Convierte un texto en entero. |
| `Cast_NumToText` | (valor) | Texto | Convierte un número en su representación de texto. |
| `Cast_DateToText` | (fecha, formato) | Texto | Convierte una fecha en texto con el formato indicado. |
| `Cast_DateTimeToText` | (fechaHora, formato) | Texto | Convierte una fecha y hora en texto con el formato indicado. |
| `ExtractFirstNumber` | (texto) | Decimal | Extrae el primer número que aparece en un texto. |
| `IsNumeric` | (cadena) | Entero (1/0) | El texto representa un número válido. |
| `IsInteger` | (cadena) | Entero (1/0) | El texto representa un entero válido. |
`Cast_TextToNum`, `Cast_TextToInt` y `Cast_NumToText` solo ejecutan en fórmulas de algoritmo. `IsNumeric`, `IsInteger` y `ExtractFirstNumber` ejecutan en el resto de contextos, pero no en algoritmos: no puedes validar con `IsNumeric` antes de convertir con `Cast_TextToNum`.
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Funciones de agregación](/docs/desarrollo/flex/dinascript/funciones/agregacion)
→ [Funciones de texto](/docs/desarrollo/flex/dinascript/funciones/texto)
# Funciones de sistema y seguridad (/docs/desarrollo/flex/dinascript/funciones/sistema-y-seguridad)
Funciones del espacio `F.` para operar con el sistema: crear y modificar registros desde un script, lanzar peticiones HTTP, codificar texto, generar claves y códigos, y localizar cuentas contables. Las convenciones comunes (tipos de datos, sufijos, contextos) están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Crear y modificar registros por script [#crear-y-modificar-registros-por-script]
Las funciones `API_` guardan registros desde el propio script. El flujo tiene tres pasos: abrir el registro con `API_BeginAddRecord` o `API_BeginModifyRecord`, asignar campos con `API_SetRecordFieldValue` y confirmar con `API_CommitSaveRecord`.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------- | ----------------------- | --------------- | -------------------------------------------------------------------------------------- |
| `API_BeginAddRecord` | (sección) | Relación (GUID) | Crea un registro nuevo en la sección y devuelve su GUID. |
| `API_BeginModifyRecord` | (sección) | — | Inicia la modificación de un registro existente de la sección. |
| `API_SetRecordFieldValue` | (sección, campo, valor) | — | Asigna el valor de un campo del registro abierto. El tipo del valor depende del campo. |
| `API_CommitSaveRecord` | () | Entero | Confirma y guarda en base de datos los cambios pendientes. |
| `API_DeleteRecord` | (sección) | — | Elimina definitivamente un registro de la sección. |
| `API_RestoreRecord` | (sección) | — | Restaura un registro eliminado de la sección. |
Sin `API_CommitSaveRecord` no se guarda nada: los cambios quedan pendientes hasta que lo llamas.
Tras el guardado, las `SaveInfo_` te dicen qué ha pasado:
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------ | ---------- | --------------- | --------------------------------------------------------- |
| `SaveInfo_AffectedCount` | (sección) | Entero | Registros afectados por el último guardado en la sección. |
| `SaveInfo_AffectedID` | (sección) | Relación (GUID) | GUID del registro afectado por el último guardado. |
| `SaveInfo_DurationMs` | (sección) | Entero | Duración del último guardado, en milisegundos. |
## Ejecutar scripts y servicios externos [#ejecutar-scripts-y-servicios-externos]
Todas ejecutan en scripts independientes.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------------------------ | ------------------------------- | -------- | ------------------------------------------------------------ |
| `ExecuteScript` | (script) | — | Ejecuta otro script por su identificador. |
| `WebClient_Request` | (endpoint, método, diccionario) | Texto | Lanza una petición HTTP al endpoint y devuelve la respuesta. |
| `IndexText` | (texto) | Entero | Añade un texto al índice en memoria y devuelve su posición. |
| `BuildArrayJSON` | () | Texto | Monta un array JSON con los valores indexados. |
| `Maps_KilometersBetween2Coordinates` | (desde, hasta) | Decimal | Kilómetros entre dos coordenadas geográficas. |
| `Maps_MinutesBetween2Coordinates` | (desde, hasta) | Entero | Minutos de viaje entre dos coordenadas geográficas. |
Los parámetros de la petición HTTP viajan en un diccionario de [funciones de texto](/docs/desarrollo/flex/dinascript/funciones/texto):
```javascript
num parametros = F.DicT_New()
F.DicT_Add(parametros, "email", v.email)
txt respuesta = F.WebClient_Request("https://api.ejemplo.com/altas", "POST", parametros)
```
## Equipo local: solo en el Terminal [#equipo-local-solo-en-el-terminal]
Operan sobre la máquina donde corre la aplicación: portapapeles, archivos y procesos. Solo ejecutan en el Terminal, en scripts independientes.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | -------------------------------------------------- | ------------ | ---------------------------------------------------------------- |
| `ClipboardGet` | () | Texto | Lee el texto del portapapeles. |
| `ClipboardSet` | (texto) | — | Copia el texto al portapapeles. |
| `IOFileExists` | (ruta) | Entero (1/0) | El archivo existe en la ruta indicada. |
| `IODirectoryExists` | (ruta) | Entero (1/0) | La carpeta existe en la ruta indicada. |
| `OSProcessStart` | (directorio, archivo, comando, esperar, timeoutMs) | — | Arranca un proceso del sistema, con espera y timeout opcionales. |
| `RunCMD` | (comando) | Texto | Ejecuta un comando de sistema predefinido y devuelve su salida. |
## Codificar y descodificar [#codificar-y-descodificar]
Escapan texto para incrustarlo en HTML, URLs o JSON sin romper la sintaxis. Ejecutan en documentos dinámicos y funciones API; `URLEncode` también vale en scripts de formulario e independientes.
| Función | Parámetros | Devuelve | Qué hace |
| ------------ | ---------------- | -------- | ---------------------------------------------------------- |
| `HtmlEncode` | (texto) | Texto | Escapa los caracteres especiales de HTML. |
| `HtmlDecode` | (texto) | Texto | Deshace la codificación HTML y recupera el texto original. |
| `URLEncode` | (texto) | Texto | Escapa un texto para usarlo en una URL. |
| `URLDecode` | (texto) | Texto | Deshace la codificación URL y recupera el texto original. |
| `JSONEncode` | (texto) | Texto | Escapa un texto para usarlo como valor JSON. |
| `GetBase64` | (imagen, tamaño) | Texto | Devuelve una imagen en Base64, al tamaño indicado. |
## Códigos QR [#códigos-qr]
Ambas ejecutan en documentos dinámicos y funciones API.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | ------------------------------- | -------- | ------------------------------------------------------------- |
| `BuildQR` | (url) | Texto | Genera un código QR a partir de una URL. |
| `BuildQR_Verifactu` | (nif, numSerie, fecha, importe) | Texto | Genera el QR Verifactu de una factura con sus datos fiscales. |
## Hashes, claves y códigos [#hashes-claves-y-códigos]
Todas valen en scripts independientes salvo `ToSHA1`, que solo ejecuta en documentos dinámicos y funciones API. `NewGuid` vale en cualquier contexto.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------- | ---------------------- | -------- | ----------------------------------------------------------------- |
| `NewGuid` | () | Texto | Genera un GUID aleatorio nuevo. |
| `NewPassword` | (longitud, especiales) | Texto | Genera una contraseña aleatoria, con o sin caracteres especiales. |
| `ToSHA1` | (texto) | Texto | Hash SHA-1 del texto. |
| `CreateSecretKeyTotp` | (longitud) | Texto | Genera una clave secreta para códigos TOTP. |
| `ComputeCodeTotp` | (claveSecreta) | Texto | Calcula el código TOTP vigente para una clave secreta. |
El secreto TOTP se genera una vez; el código se recalcula a partir de él cada vez que lo necesitas:
```javascript
txt secreto = F.CreateSecretKeyTotp(32)
txt codigo = F.ComputeCodeTotp(secreto)
```
## Contabilidad [#contabilidad]
Localizan grupos, cuentas y subcuentas del plan contable por su código. Las `Detect*` ejecutan en scripts de formulario; `IsAccountOrSubAccount` también en algoritmos y scripts independientes.
| Función | Parámetros | Devuelve | Qué hace |
| ----------------------- | -------------------- | --------------- | ------------------------------------------------------------------------------- |
| `DetectAccount` | (código) | Relación (GUID) | GUID de la cuenta a partir del código de cuenta o subcuenta. |
| `DetectAccountByType` | (código, tipo) | Relación (GUID) | GUID del grupo, cuenta o subcuenta, según el tipo a extraer. |
| `DetectAccountGroup` | (código) | Relación (GUID) | GUID del grupo contable a partir del código. |
| `DetectSubAccount` | (código) | Relación (GUID) | GUID de la subcuenta a partir de su código. |
| `IsAccountOrSubAccount` | (cuenta, subcuentas) | — | Comprueba si la cuenta coincide con los códigos indicados, separados por comas. |
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Scripts](/docs/desarrollo/flex/scripts)
→ [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos)
# Funciones de texto (/docs/desarrollo/flex/dinascript/funciones/texto)
Funciones del espacio `F.` para trabajar con texto: combinar valores, buscar dentro de una cadena, trocearla por un separador, formatear números como texto y montar estructuras JSON. Las convenciones comunes (tipos de datos, valores sí/no, contextos) están en el [índice de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Combinar y transformar [#combinar-y-transformar]
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------- | ---------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `Concat` … `Concat6` | (texto1, …, textoN) | Texto | Une de 1 a 6 valores de texto en uno. |
| `Replace` | (cadena, búsqueda, nuevoValor) | Texto | Sustituye todas las apariciones de un texto por otro. |
| `ToUppers` | (texto) | Texto | Pasa a mayúsculas. |
| `ToLower` | (texto) | Texto | Pasa a minúsculas. |
| `Length` | (texto) | Entero | Número de caracteres. |
| `Substring` | (texto, inicio, longitud) | Texto | Extrae un trozo desde una posición. |
| `RemoveStart` / `RemoveEnd` | (cadena, cantidad) | Texto | Quita N caracteres del inicio o del final. |
| `PadLeft` / `PadRight` | (texto, cantidad, relleno, cortar) | Texto | Rellena hasta una longitud fija por la izquierda o la derecha. El último parámetro corta el texto si ya es más largo. |
```javascript
txt codigo = F.PadLeft("7", 5, "0", false)
@ codigo vale "00007"
txt etiqueta = F.Concat3("Pedido ", codigo, " confirmado")
```
## Buscar dentro de un texto [#buscar-dentro-de-un-texto]
Las tres devuelven un entero: `1` si se cumple, `0` si no. La comparación ignora mayúsculas y acentos.
| Función | Parámetros | Devuelve | Qué hace |
| ------------ | ------------------ | ------------ | --------------------------------------- |
| `Contains` | (cadena, búsqueda) | Entero (1/0) | La cadena contiene el texto buscado. |
| `StartsWith` | (cadena, búsqueda) | Entero (1/0) | La cadena empieza por el texto buscado. |
| `EndsWith` | (cadena, búsqueda) | Entero (1/0) | La cadena termina en el texto buscado. |
```javascript
¿F.Contains(v.email, "@") = 0 ? v.error = "El email no es válido"
```
## Trocear por separador [#trocear-por-separador]
Parten la cadena por un separador y devuelven o eliminan segmentos. `A ignorar` salta los primeros N trozos; `A recibir` limita cuántos coges.
| Función | Parámetros | Devuelve | Qué hace |
| ----------------- | -------------------------------------- | -------- | -------------------------------------------------- |
| `GetFirstPart` | (valor, separador, aIgnorar, aRecibir) | Texto | Coge los primeros segmentos tras partir la cadena. |
| `GetLastPart` | (valor, separador, aIgnorar, aRecibir) | Texto | Coge los últimos segmentos. |
| `RemoveFirstPart` | (valor, separador, aEliminar) | Texto | Quita los primeros N segmentos. |
| `RemoveLastPart` | (valor, separador, aEliminar) | Texto | Quita los últimos N segmentos. |
```javascript
txt dominio = F.GetLastPart("ana@dinaup.com", "@", 0, 1)
@ dominio vale "dinaup.com"
```
## Formatear números como texto [#formatear-números-como-texto]
Aplican el formato de presentación de tu cuenta: separadores de miles, símbolo de moneda, signo de porcentaje.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------- | ------------ | -------- | -------------------------------------------------------------------------------------------- |
| `FormatMoney` | (importe) | Texto | Importe monetario: `1.234,56 €`. |
| `FormatNumeric` | (importe) | Texto | Número con separadores: `1.234,56`. |
| `FormatPercentage` | (importe) | Texto | Porcentaje: `25%`. |
| `FormatNumericByRole` | (valor, rol) | Texto | Formatea según el formato del [rol de campo](/docs/desarrollo/flex/roles-de-campo) indicado. |
| `FormatTime` | (minutos) | Texto | Minutos como hora: `90` → `1:30`. |
| `WriteTime` | (minutos) | Texto | Minutos como texto legible por personas. |
## Diccionarios en memoria [#diccionarios-en-memoria]
Pares clave-valor para acumular resultados antes de exportarlos. Dos sabores: texto (`DicT_`) y numérico (`DicN_`). `_New` devuelve la referencia del diccionario, que pasas al resto de funciones.
| Función | Parámetros | Devuelve | Qué hace |
| --------------------------------------- | --------------------- | --------------- | ----------------------------------------------------------- |
| `DicT_New` / `DicN_New` | () | Referencia | Crea el diccionario. |
| `DicT_Add` / `DicN_Add` | (dic, clave, valor) | — | Añade o actualiza una clave. |
| `DicT_Get` / `DicN_Get` | (dic, clave, defecto) | Texto / Decimal | Lee una clave; si no existe, devuelve el valor por defecto. |
| `DicT_ContainsKey` / `DicN_ContainsKey` | (dic, clave) | Entero (1/0) | La clave existe. |
| `DicT_Count` / `DicN_Count` | (dic) | Entero | Número de entradas. |
| `DicT_RemoveItem` / `DicN_RemoveItem` | (dic, clave) | — | Elimina una clave. |
| `DicT_Clear` / `DicN_Clear` | (dic) | — | Vacía el diccionario. |
| `DicT_ToJson` / `DicN_ToJson` | (dic) | Texto | Vuelca el diccionario a JSON. |
```javascript
num dic = F.DicN_New()
F.DicN_Add(dic, "enero", 1200)
F.DicN_Add(dic, "febrero", 1550)
txt json = F.DicN_ToJson(dic)
```
## Construir JSON [#construir-json]
Para montar un JSON a mano con objetos anidados, sin pelearte con comillas. Abres un documento, vas asignando claves tipadas y lo lees al final.
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | -------------- | -------- | ----------------------------------------------------------- |
| `Json_DocIni` | (keyword) | — | Abre un documento JSON identificado por keyword. |
| `Json_ObjectIni` | (clave) | — | Abre un objeto anidado. Con clave vacía, es el objeto raíz. |
| `Json_SetValueText` | (clave, valor) | — | Asigna un valor de texto. |
| `Json_SetValueN` | (clave, valor) | — | Asigna un valor numérico. |
| `Json_SetValueB` | (clave, valor) | — | Asigna un valor sí/no. |
| `Json_SetValueJson` | (clave, json) | — | Anida un JSON ya construido como valor. |
| `Json_ObjectEnd` | () | — | Cierra el objeto actual. |
| `Json_DocEnd` | () | — | Cierra el documento. |
| `Json_ReadDoc` | (keyword) | Texto | Devuelve el JSON generado. |
```javascript
F.Json_DocIni("respuesta")
F.Json_ObjectIni("")
F.Json_SetValueText("estado", "ok")
F.Json_SetValueN("total", 1250.50)
F.Json_ObjectEnd()
F.Json_DocEnd()
txt json = F.Json_ReadDoc("respuesta")
```
## NIF españoles [#nif-españoles]
| Función | Parámetros | Devuelve | Qué hace |
| ------------------- | ---------- | ------------ | ---------------------------------- |
| `ValidateNIF` | (nif) | Entero (1/0) | El NIF tiene un formato válido. |
| `NIFIsPersonal` | (nif) | Entero (1/0) | El NIF es de persona física. |
| `DetectTypeNIF` | (nif) | Texto | Nombre del tipo de NIF. |
| `IdentifyIDTypeNIF` | (nif) | Entero | Código del tipo de identificación. |
## Utilidades web [#utilidades-web]
| Función | Parámetros | Devuelve | Qué hace |
| --------------- | ---------- | -------- | --------------------------------------------------------------------------- |
| `ToFriendlyUrl` | (valor) | Texto | Convierte un texto en slug para URL, sin espacios ni caracteres especiales. |
| `JSEncode` | (texto) | Texto | Escapa un texto para incrustarlo en JavaScript. |
***
→ [Índice de funciones](/docs/desarrollo/flex/dinascript/funciones)
→ [Espacio de nombres S. (Schema)](/docs/desarrollo/flex/dinascript/s.-espacio-de-nombre-schema)
# Impresión de factura emitida (/docs/desarrollo/flex/documentos-dinamicos/ejemplos/impresion-factura-emitida)
## Contexto [#contexto]
Este documento genera un PDF de factura.
## Variables [#variables]
Define las variables:
* Factura (Relacionado con ventas)
## DinaScript [#dinascript]
```
.
.
Condiciones de pago:
Vencimiento:
SALDO
¡Ha acumulado
de saldo promocional con esta compra!
* A fecha
dispone de
de saldo promocional que puede aplicar como descuentos en compras futuras.
```
# Ejemplos (/docs/desarrollo/flex/documentos-dinamicos/ejemplos)
Estos ejemplos son **plantillas reales** de documentos dinámicos, con su DinaScript completo. Copia el que más se parezca a lo que necesitas y adáptalo a tu caso.
Cada ejemplo muestra el patrón de principio a fin: qué **variables** define, cómo recorre los datos con DinaScript y cómo construye la salida final.
¿Es tu primer documento dinámico? Empieza por **[Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)** para entender el flujo básico (código + variables) y vuelve aquí cuando quieras un ejemplo completo.
***
## Plantillas disponibles [#plantillas-disponibles]
Listado HTML de compras/gastos filtrado por rango de fechas y tipo de operación, con desglose de bases, IVA, RE y retenciones más una tabla de totales.
Factura de venta lista para imprimir o enviar por email: conceptos, bases imponibles, totales, condiciones de pago y notas, a partir de una factura concreta.
***
## Cuál te conviene [#cuál-te-conviene]
Los dos ejemplos resuelven necesidades distintas. Elige según el resultado que buscas:
| | Libro registro (HTML) | Impresión de factura (PDF) |
| ------------------ | ------------------------------------------- | ------------------------------------------- |
| Qué genera | Un **listado** con muchos registros | Un **documento** de un único registro |
| Entrada | Variables de filtro: rango de fechas y tipo | Una variable: la factura a imprimir |
| Cómo recorre datos | Carga y procesa una lista de compras/gastos | Carga las líneas de la factura seleccionada |
| Uso típico | Consulta fiscal, exportación, revisión | Entregar o enviar la factura al cliente |
Ambos comparten el mismo esqueleto: definir variables, recorrer los datos con DinaScript y volcar el HTML resultante.
***
## Cómo adaptar un ejemplo [#cómo-adaptar-un-ejemplo]
### Crea el documento [#crea-el-documento]
Sigue los pasos de **[Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)** para dar de alta una plantilla nueva y abrir su editor de código.
### Pega el ejemplo [#pega-el-ejemplo]
Copia el DinaScript de la plantilla que hayas elegido y pégalo en el editor, sustituyendo el contenido inicial.
### Declara sus variables [#declara-sus-variables]
Cada ejemplo indica en su apartado **Variables** las que necesita (por ejemplo, las fechas del libro registro o la factura a imprimir). Créalas con el mismo nombre desde la pestaña de variables.
### Ajústalo a tu caso [#ajústalo-a-tu-caso]
Cambia las secciones, campos, columnas y textos para que reflejen tus datos. Guarda y prueba el resultado.
***
→ [Crear documento dinámico](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
→ [Documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos)
→ [Dinaup Flex](/docs/desarrollo/flex)
# Libro registro de facturas recibidas (HTML) (/docs/desarrollo/flex/documentos-dinamicos/ejemplos/libro-registro-de-facturas-recibidas-html)
## Contexto [#contexto]
Este documento dinámico muestra las facturas recibidas filtradas por variables globales:
* Rango de fecha
* Tipo de compra / gasto
## Variables [#variables]
Define las variables:
* Fecha\_Desde
* Fecha\_Hasta
* Tipo
## DinaScript [#dinascript]
```
💼 - 📄 Libro registro
Compras / Gastos -
Totales
Concepto
Total
Suma B.I
Suma IVA
Suma R.E
Suma Retenciones
Suma Totales
```
# Crear y configurar informes (/docs/desarrollo/recursos/dinaup-terminal/ventanas/crear-informes)
Un informe nace siempre de una sección de datos. Se afina desde dos ventanas del Terminal: **Configuración de informe** (el informe entero) y **Editar Columna** (cada columna). Esta página lista qué controla cada opción. Para el concepto de informe, roles, visibilidad y filtrado, ver [informes en Flex](/docs/desarrollo/flex/informes).
## Crear informe [#crear-informe]
Se abre desde una sección de datos: el informe parte siempre de esa sección origen. El panel lateral **Secciones relacionadas** lista la sección base y sus plantillas derivadas. Solo aparecen las que tu permiso de creación te deja usar. Eliges sobre cuál crear.
| Campo | Qué es |
| -------------------------- | -------------------------------------------------- |
| Sección de origen de datos | La sección de la que salen los datos. Obligatorio. |
| Nombre informe | Nombre visible del informe. Obligatorio. |
| Categoría | Dónde se agrupa el informe. Obligatorio. |
| Subcategoría | Agrupación de segundo nivel. Opcional. |
Al aceptar, Dinaup crea el informe y lo abre. Valida que haya sección origen, nombre y categoría.
### Asistente de nombre [#asistente-de-nombre]
Desde **Asistente nombre** (en Configuración de informe) construyes el nombre uniendo hasta cinco partes con espacios.
| Parte | Contenido |
| ----------------------------- | ------------------------------------------------------------------------------------------------ |
| Prefijo | Sugiere `Top` (rankings), `Listado` (listados), `Resumen` (con gráficas) o `Board` (modo board). |
| Sujeto, Condición, Agrupación | Texto libre. |
| Pregunta | Si la rellenas, se añade al final precedida de `\| `. |
## Configurar informe [#configurar-informe]
La ventana **Configuración de informe** reúne todos los ajustes del informe en paneles. Los botones de pie son **Aceptar**, **Cancelar**, **Ver Informe**, **Exportar** (guardar en archivo), **Agregar columna** y **Asistente nombre**.
En informes principales o de sistema (combos, destinadores, alertas) muchos campos aparecen bloqueados con su motivo. El sistema autogestiona su tipo. Un informe que creas a mano casi siempre es de tipo Ordinario.
### Datos e identificación [#datos-e-identificación]
| Panel / campo | Qué controla |
| ----------------------------------------- | ------------------------------------------------------------ |
| Nombre informe, Descripción | Nombre y una descripción opcional para reconocer su función. |
| Sección de datos, Categoría, Subcategoría | Origen y clasificación del informe. |
| Tipo | Destino del informe. Casi siempre Ordinario. |
| Tipo de clasificación | Clasificación general (Funcionalidad, etc.). |
| Resultados por página | Numérico. Máximo 1.000; hasta 10.000 si aceptas con Shift. |
### Orden y agrupación [#orden-y-agrupación]
| Panel | Qué controla |
| ------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Orden | Hasta 5 campos de orden, cada uno con casilla de descendente. Si el campo es fecha u hora, se marca descendente solo. |
| Agrupación de datos | Hasta 5 agrupaciones, cada una con su Modo (el criterio de agrupado). |
Algunos tipos de informe no permiten agrupar: en ese caso los selectores se bloquean con el motivo. Si rellenas una agrupación, debes elegir un modo válido antes de aceptar.
### Filtrado [#filtrado]
| Panel | Qué controla |
| ----------------- | ---------------------------------------------------------------------------------------------------- |
| Filtrado rápido | Condiciones directas sobre campos, más un Algoritmo de filtrado para condiciones que son un cálculo. |
| Filtrado avanzado | Editor de condiciones con las variables del informe (las preguntas dinámicas). |
Las variables de un informe ya publicado o en uso no pueden cambiarse, para no romper la compatibilidad con quien ya lo usa.
Ver [filtrado por algoritmo](/docs/desarrollo/flex/algoritmos), [preguntas dinámicas](/docs/desarrollo/flex/informes) y el how-to de [filtrar por rango de fechas](/docs/desarrollo/flex/informes/filtrar-informe-por-rango-de-fechas).
### Renderizado y representación [#renderizado-y-representación]
| Campo | Opciones |
| ---------------- | ------------------------------------------------------------------------- |
| Modo renderizado | Lista, Barras, Tarta, Polar, Board. |
| Modo multilinea | Automático, Activado, Desactivado, Siempre Activado, Siempre Desactivado. |
| Alto fila | Altura de cada fila. |
La representación avanzada añade columnas propias de cada modo:
| Modo | Columnas que añade |
| ----------------- | -------------------------------- |
| Board | Columnas de agrupación. |
| Calendario, Gantt | Columnas de inicio, fin y texto. |
| Gráfica | Columna de agrupación. |
### Aviso, permisos, complemento y destinador [#aviso-permisos-complemento-y-destinador]
| Panel | Qué controla |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Aviso | Texto de aviso más su Tipo de aviso. Si escribes texto pero el tipo es Ninguno, se avisa de que no se mostrará. |
| Permisos | Casilla para ocultar el informe en principal (solo en informes reales). |
| Complemento en principal | Acceso rápido: Título, Etiqueta Singular y Etiqueta Plural (obligatorios si lo expandes), hasta 4 pares Campo/Valor de autorrellenado y una opción de incrustar. |
| Destinador Informe | Campo y sección destino; valida que el campo pertenezca a la sección elegida. |
Otros campos del panel: Informe relacionado y su etiqueta, Impresión por defecto, Objeto relacionado, Widget CFG y Categorías secundarias (hasta 8 categoría/subcategoría extra).
## Editar columna [#editar-columna]
La ventana **Editar Columna** define una columna. Los paneles que ves dependen del tipo de dato que produce la columna (texto, numérico, fecha, bool, imagen). Botones: **Aceptar**, **Cancelar**, **Ver informe**, **Personalizar** e **Ir a combo en sección** (si la columna sale de un combo).
### Dato e identificación [#dato-e-identificación]
| Campo | Qué es |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Dato | Campo o cadena mágica que representa la columna. Obligatorio. Admite campos directos, de sesión, de empresa, constantes y algoritmos. |
| Título columna, Abreviatura, Subtitulo | Textos de cabecera de la columna. |
| Prefijo, Sufijo, Color | Adornan el valor mostrado. |
| Información | Texto que aparece al pasar el cursor sobre la columna. |
### Comportamiento [#comportamiento]
| Campo | Opciones |
| ----------- | ---------------------------------------------------------------------------------------------------- |
| Rol | Automático por defecto, más los [roles de columna](/docs/desarrollo/flex/informes). |
| Visibilidad | Siempre visible por defecto, más el resto de [modos de visibilidad](/docs/desarrollo/flex/informes). |
| Relevancia | Normal, Alta, Secundaria. |
| Orden | Normal, Ascendente, Descendente. |
**Resúmenes de pie** (según el tipo de dato): Resumen Total, Resumen Filtrado y Resumen Seleccionado, con opciones Ninguno, Con dato, Vacías, Resultados y, según tipo, Media y Sumar (numérico), Contar distintos (texto) o Sí/No (bool).
**Agrupación (Dinámica)**: criterio de agrupado que depende del tipo de dato: Iguales, Vacíos, Parte entera, Parte decimal, Par/Impar, Horas, Días, Día de la semana, Meses, Trimestre, Bimensual, Año, Letra o Palabra inicial/final. Se acompaña de Orden (Dinámico) y Representación agrupada.
Al guardar, si el tipo de dato no admite monitorización, Dinaup avisa de que el informe la perderá.
### Opciones por tipo de dato [#opciones-por-tipo-de-dato]
| Tipo | Opciones propias |
| -------------------- | ------------------------------------------------------------ |
| Numérico | Decimales Visibles, Modo límite, Máximo valor, Mínimo valor. |
| Fecha / Fecha y hora | Modo de representación de la fecha. |
| Bool | Texto Sí, Texto No, Representación Sí, Representación No. |
| Texto | Representación del texto. |
| Imagen | Representación Imagen (Automático más el resto). |
## Enlaces relacionados [#enlaces-relacionados]
* → [Informes en Flex: concepto, roles y visibilidad](/docs/desarrollo/flex/informes)
* → [Filtrar un informe por rango de fechas](/docs/desarrollo/flex/informes/filtrar-informe-por-rango-de-fechas)
* → [Consumir un informe por API](/docs/desarrollo/flex/informes/informes-api)
* → [Diseñar secciones y campos](/docs/desarrollo/recursos/dinaup-terminal/ventanas/disenar-secciones-y-campos)
* → [Terminal de Dinaup](/docs/desarrollo/recursos/dinaup-terminal)
# Diseñar secciones y campos (/docs/desarrollo/recursos/dinaup-terminal/ventanas/disenar-secciones-y-campos)
Al modelar datos en Terminal trabajas con dos ventanas: el Asistente de Secciones y el Editor de Campos. Esta página es la referencia de sus opciones.
Para el concepto de sección o campo, ve a [Secciones](/docs/desarrollo/flex/secciones) y [Campos](/docs/desarrollo/flex/campos). Aquí tienes qué significa cada opción de la pantalla. Para el orden en que se usan, mira el [flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo).
Editar la estructura de una sección afecta a todos los usuarios del tenant. Antes de tocarla, repasa las cautelas del [flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo).
## Asistente de Secciones [#asistente-de-secciones]
Crea o edita una sección, es decir, una tabla de datos.
| Opción | Qué hace |
| ----------------------------------------- | ----------------------------------------------------------------------- |
| Título | Nombre identificativo de la sección. |
| Etiqueta singular / plural | Cómo se nombra un registro y muchos (Cliente / Clientes). |
| Es femenino | Ajusta el género de las etiquetas automáticas. |
| Icono / Color | Imagen y color con que se identifica la sección. |
| Campo Legible | Campo que representa cada registro como texto al referenciarlo. |
| Imagen de vista previa | Campo con la imagen que se muestra como previa del registro. |
| Se pueden crear derivadas / Derivable | Permite que otras secciones hereden de esta como base. |
| Datos exportables | Incluye los datos de la sección al empaquetar un módulo. |
| Control por fecha / por empleado | Campos con los que se filtran los datos por fecha o responsable. |
| Impedir agregar / mensajes de restricción | Bloquea crear, editar o eliminar y define el mensaje que ve el usuario. |
## Editor de Campos [#editor-de-campos]
Configura un campo al completo. Está organizado en pestañas.
### Identificación [#identificación]
| Opción | Qué hace |
| ----------------------------- | --------------------------------------------- |
| Etiqueta / Etiqueta abreviada | Nombre del campo y su versión corta. |
| Valor de ejemplo | Texto de ejemplo que orienta a quien rellena. |
| Ayuda | Instrucciones que se muestran junto al campo. |
### Tipo y rol [#tipo-y-rol]
| Opción | Qué hace |
| -------------------- | --------------------------------------------------------------------------------------------- |
| Formato | Tipo base: Texto, Número decimal, Número entero, Sí/No, Fecha, Fecha y hora, Hora o Relación. |
| Rol especial | Afina el tipo base (Email, Teléfono, NIF, Moneda, Porcentaje…). |
| Renderizado especial | Cómo se muestra en pantalla (genérico, selector Sí/No, selector múltiple…). |
El Formato define el [tipo de campo](/docs/desarrollo/flex/campos); el Rol especial lo afina, con más detalle en [roles de campo](/docs/desarrollo/flex/roles-de-campo).
### Comportamiento [#comportamiento]
| Opción | Qué hace |
| ----------------------------------- | ------------------------------------------------------------ |
| Visible / Visible a la derecha | Si se muestra el campo y dónde. |
| Obligatorio / Rellenado obligatorio | Si hace falta para guardar y si hay que rellenarlo al crear. |
| Bloqueado | Solo lectura: lo pone el sistema o un cálculo. |
| Indexar | Acelera las búsquedas por ese campo. |
| Sin valores repetidos | Exige que el valor sea único. |
| Valor por defecto | Valor inicial al crear un registro. |
### Auto-calculado [#auto-calculado]
Marca **Auto-calculado** y el valor lo produce un [algoritmo](/docs/desarrollo/flex/algoritmos) en vez de escribirse a mano. La lógica se escribe con [DinaScript](/docs/desarrollo/flex/dinascript/funciones).
### Campos numéricos [#campos-numéricos]
Aparecen cuando el Formato es un número.
| Opción | Qué hace |
| ------------------------------------- | --------------------------------------------------- |
| Decimales visibles / en base de datos | Cuántos decimales se muestran y cuántos se guardan. |
| Parte entera | Dígitos de la parte entera. |
### Campos de relación [#campos-de-relación]
Aparecen cuando el Formato es Relación.
| Opción | Qué hace |
| ------------------------------------- | -------------------------------------------------- |
| Sección relacionada / preferente | A qué otra sección apunta el campo. |
| Copiar valor principal al pulsar \[+] | Autorrellena datos al crear la relación. |
| Campo de texto de relación | Qué campo de la otra sección se muestra al buscar. |
## Agregar Campo Rápido [#agregar-campo-rápido]
Atajo para crear un campo con lo mínimo (Etiqueta, Formato, Rol, decimales) sin abrir el editor completo.
* **Aceptar** crea el campo.
* **Aceptar Avanzado** abre el Editor de Campos para afinar el resto de opciones.
## Duplicar Tabla [#duplicar-tabla]
Copia una sección a otra: eliges origen y destino, y se copian los campos con su configuración y las columnas del informe principal. Útil para partir de algo parecido en vez de empezar de cero.
## Relacionado [#relacionado]
→ [Secciones](/docs/desarrollo/flex/secciones)
→ [Campos](/docs/desarrollo/flex/campos)
→ [Roles de campo](/docs/desarrollo/flex/roles-de-campo)
→ [Flujo de desarrollo en Terminal](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo)
# Documentos dinámicos y API (/docs/desarrollo/recursos/dinaup-terminal/ventanas/documentos-dinamicos-y-api)
El Terminal trae un editor para crear y editar documentos dinámicos y funciones API. Esta página es la referencia de esas ventanas: el diálogo de alta rápida, el editor del documento y el asistente que escribe el código de un endpoint por ti. Para saber qué es un documento dinámico y sus tipos, ve a [documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos). Para el lenguaje, ve a [DinaScript](/docs/desarrollo/flex/dinascript).
## Elegir tipo de plantilla [#elegir-tipo-de-plantilla]
Al dar de alta un documento se abre el diálogo **Agregar Documentos dinámicos**. Ofrece cuatro atajos que crean directamente un documento de lectura libre y le cargan un ejemplo listo para editar:
| Botón | Extensión de salida |
| ------------ | ------------------- |
| Plantilla A4 | `.pdf` |
| Reporte HTML | `.html` |
| Archivo CSV | `.csv` |
| Archivo JSON | `.json` |
Los cuatro crean el tipo *Documento de lectura libre*; solo cambia la extensión y el ejemplo inicial. Cada botón descarga su plantilla y abre el editor con ese código puesto. **Cancelar** cierra sin crear. Para crear otros tipos (API de escritura, diseño de informe) fijas el campo **Clase** dentro del editor.
Si no hay conexión y la descarga del ejemplo falla, el editor se abre igual, pero vacío.
## El editor del documento [#el-editor-del-documento]
La ventana se titula **Agregar documento dinámico** al crear y **Editor documento dinámico** al editar. Es grande y redimensionable, y en ella defines todo el documento.
### Identificación [#identificación]
| Campo | Qué es |
| ------------------------ | ------------------------------------------ |
| Título | Nombre del documento en el listado. |
| Categoría · Subcategoría | Agrupan el documento en el listado. |
| Descripción | Texto libre que explica para qué sirve. |
| Ruta Keyword · ID | Identificadores para invocar el documento. |
Las categorías predefinidas son *Páginas / Informes*, *Exportación*, *Librerías*, *API*, *Ejemplos / Plantillas*, *Otros*, *Tareas programadas* y *Webhook*. Puedes añadir las tuyas.
### Tipo y salida [#tipo-y-salida]
| Campo | Qué controla |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Clase | El tipo de documento. Fija el título, el icono y el ejemplo de código inicial. |
| Extensión | Extensión del archivo generado (`.html`, `.pdf`, `.csv`, `.txt`, `.xml`, `.json`, `.css`, `.js`, `.svg`, `.md`, `.yaml` y más). |
| Encoding | Codificación del documento generado. |
| Protección | Nivel de acceso al documento (por ejemplo, *Cualquier empleado*). |
Los tipos disponibles en **Clase** y qué hace cada uno están en la [tabla de tipos de documento dinámico](/docs/desarrollo/flex/documentos-dinamicos).
### Pestañas de trabajo [#pestañas-de-trabajo]
| Pestaña | Para qué |
| --------- | ------------------------------------------------------------------------------------ |
| Inicio | Configuración general del documento. |
| Código | Editor DinaScript: colorea la sintaxis, detecta errores en vivo y lleva un contador. |
| Variables | Variables del documento con su formato, valor por defecto y etiqueta. |
| Previa | Vista previa del HTML renderizado. |
## La barra de variables [#la-barra-de-variables]
Bajo el editor de código, una barra muestra cada variable definida (`V.NombreVariable`) con su número de usos. Si una variable no se usa en ningún sitio, aparece en rojo.
* **Bloque Script:** inserta un bloque de script vacío donde está el cursor.
* **Menú `+`:** *Formatear* el código, *Convertir a Nativo*, *Convertir a Keyword*, *Reiniciar Código HTML* y *Reiniciar Código VUE* (regenera el ejemplo desde cero).
* **Presets:** al pulsar sobre las zonas de la barra insertas código de lectura (*Registro* o *Informe*: eliges una sección o un informe y vuelca sus campos) o abres el asistente de escritura (*Edición*).
* **ERRORES:** al hacer clic en el contador se despliega la lista de errores del script sobre el editor.
## Disponibilidad [#disponibilidad]
Este bloque marca dónde puede usarse el documento. Las casillas **Ticket**, **Impresión** y la de informe solo aparecen cuando la Clase es *Documento de lectura libre*; para otros tipos están ocultas.
* **Email:** marca el documento como válido para envío por email.
* **Obsoleto:** retira el documento sin borrarlo.
## Asistente de escritura API [#asistente-de-escritura-api]
El asistente **Asistente Agregar registro** / **Asistente modificador** genera automáticamente el código de un endpoint que crea o modifica un registro, para que no lo escribas a mano. Se abre desde el editor con el preset *Edición*: primero eliges Agregar o Modificar, y luego la sección de destino con el selector de secciones.
El asistente lista los campos de la sección como casillas, agrupados por pestaña y con un icono por tipo. Puedes filtrar qué campos ves:
| Filtro | Muestra los campos de tipo |
| ----------- | -------------------------- |
| Textos | Texto. |
| Sí/No | Casilla verdadero/falso. |
| Relaciones | Enlace a otra sección. |
| Numéricos | Número o moneda. |
| Hora | Hora. |
| Fecha | Fecha. |
| Fech y Hora | Fecha con hora. |
También hay un buscador por nombre. Los campos obligatorios y el texto principal salen marcados y bloqueados. Los campos que no se pueden modificar desde REST salen deshabilitados, con el motivo.
Dos botones de salida:
* **Aceptar:** inserta solo el código (las funciones `API_BeginAddRecord` / `API_BeginModifyRecord`, un `API_SetRecordFieldValue` por campo, `API_CommitSaveRecord` y el bloque de respuesta JSON).
* **Aceptar y Crear variables:** además da de alta las variables `V.*` correspondientes a cada campo.
El detalle de esas funciones está en la [referencia de funciones](/docs/desarrollo/flex/dinascript/funciones).
## Botones de la ventana [#botones-de-la-ventana]
| Botón | Qué hace |
| -------- | ------------------------------------------------------------- |
| Aceptar | Guarda el documento y cierra. |
| Aplicar | Guarda sin cerrar (solo al editar un documento existente). |
| Duplicar | Crea una copia con toda su configuración, código y variables. |
| Exportar | Exporta el documento. |
| Cancelar | Cierra sin guardar. |
Al aceptar, el código keyword se convierte a nativo y se validan las variables. Si la configuración de variables ocupa demasiado, el editor avisa y no guarda.
## Enlaces relacionados [#enlaces-relacionados]
* → [Documentos dinámicos: concepto y tipos](/docs/desarrollo/flex/documentos-dinamicos)
* → [Crear un documento dinámico: código y variables](/docs/desarrollo/flex/documentos-dinamicos/crear-documento-dinamico)
* → [Ejemplos completos](/docs/desarrollo/flex/documentos-dinamicos/ejemplos)
* → [Referencia de funciones (F.Write, API\_BeginAddRecord…)](/docs/desarrollo/flex/dinascript/funciones)
* → [Editor de scripts y algoritmos](/docs/desarrollo/recursos/dinaup-terminal/ventanas/editor-de-scripts-y-algoritmos)
# Editor de scripts y algoritmos (/docs/desarrollo/recursos/dinaup-terminal/ventanas/editor-de-scripts-y-algoritmos)
El Terminal trae un editor para escribir la lógica de tu solución. Con él creas scripts, que reaccionan a lo que pasa en un formulario, y algoritmos, que calculan valores. Esta página es la referencia de esa herramienta. Para el lenguaje en sí, ve a [DinaScript](/docs/desarrollo/flex/dinascript).
## El editor de scripts [#el-editor-de-scripts]
El área de escritura colorea la sintaxis y detecta errores mientras escribes. Debajo tienes el panel de errores: lista cada fallo con su número de línea, y al hacer clic saltas directo a esa línea.
El autocompletado te acompaña a medida que tecleas. Cuando escribes un prefijo y un punto (`S.`, `F.`, `V.`, `C.`…), te sugiere lo disponible en ese contexto. Y mientras escribes una función, te muestra sus parámetros. El catálogo completo está en la [referencia de funciones](/docs/desarrollo/flex/dinascript/funciones).
El panel de variables administra las variables locales del script. Con los atajos de teclado del editor revalidas el código y lo ejecutas sin salir de la pantalla.
## Cuándo se ejecuta un script [#cuándo-se-ejecuta-un-script]
El selector de evento decide cuándo corre el script. Según el evento que elijas, asocias uno o varios campos, o un informe. Estas son las familias de evento y cuándo disparan:
| Familia | Cuándo dispara |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Independiente | A demanda, sin ningún formulario abierto. |
| De formulario | Al crear un registro, antes de guardar, antes de cancelar, al cargar, en el recálculo periódico, al autoguardar o con un atajo de teclado. |
| De campo | Cuando un campo cambia, gana o pierde el foco, al abrir o cerrar una relación, o al filtrar un desplegable. |
| De informe | Sobre el informe entero o sobre las filas que el usuario ha seleccionado. |
Para el detalle conceptual de cada disparador, ve a [scripts](/docs/desarrollo/flex/scripts).
Algunas funciones solo tienen sentido en ciertos eventos, y el editor te lo avisa. Por ejemplo, filtrar un desplegable solo vale en el evento que filtra ese desplegable.
## Definir parámetros del script [#definir-parámetros-del-script]
Puedes declarar los parámetros que el script recibe. Mientras los usas dentro del código, el editor te muestra su información.
## El editor de algoritmos [#el-editor-de-algoritmos]
Un algoritmo se define en dos partes. La cabecera fija su identidad; el diseñador de fórmula, su cálculo.
En la cabecera indicas el nombre, la categoría y subcategoría, el rol (el tipo de dato que devuelve: texto, moneda, porcentaje…) y una descripción. El diseñador de fórmula es el editor DinaScript donde escribes el cálculo.
Al crear el algoritmo eliges su tipo. De él depende qué paneles aparecen:
| Tipo | Para qué sirve |
| ----------------- | ------------------------------------------------ |
| Lineal | Cálculo directo sobre una sección. |
| De dato | Devuelve un valor de un registro. |
| Compuesto | Cruza una sección principal con una relacionada. |
| De cálculo | Opera sobre resultados agregados. |
| De compatibilidad | Mantiene algoritmos de versiones anteriores. |
Según el tipo verás paneles de filtrado previo, criterios de relación (en los compuestos, entre la sección principal y la relacionada), orden y límites. Los conceptos de cada tipo están en [algoritmos](/docs/desarrollo/flex/algoritmos).
Además puedes configurar:
* **Referencia de fecha:** eliges un campo de fecha y el algoritmo filtra automáticamente por periodo.
* **Preguntas del algoritmo:** defines variables que el usuario responde justo al ejecutarlo.
## Probar y depurar [#probar-y-depurar]
* **Probar algoritmo:** lo ejecutas con datos reales y ves el resultado antes de guardarlo. Si tiene preguntas o referencia de fecha, el editor te las pide primero.
* **Ver el SQL:** muestra, ya formateada, la consulta que Dinaup genera a partir de tu algoritmo. Útil para entender o depurar qué hace por dentro.
Para probar el algoritmo o ver su SQL cuando tiene preguntas, primero tienes que guardarlo.
Cada variable que definas debe usarse en alguna fórmula. Si sobra una, el editor no te deja guardar.
## Enlaces relacionados [#enlaces-relacionados]
* → [DinaScript, el lenguaje](/docs/desarrollo/flex/dinascript)
* → [Referencia de funciones](/docs/desarrollo/flex/dinascript/funciones)
* → [Scripts: los disparadores](/docs/desarrollo/flex/scripts)
* → [Algoritmos: los tipos](/docs/desarrollo/flex/algoritmos)
# Gestión de archivos (/docs/desarrollo/recursos/dinaup-terminal/ventanas/gestion-de-archivos)
Cada campo de rol Archivo o Imagen guarda su contenido como un archivo del sistema. El Terminal lo maneja con cuatro ventanas encadenadas: Administrador de archivos, Subir archivo, Detalles de archivo y Vista previa.
Estas ventanas son la interfaz del operador. Para servir un archivo a alguien sin sesión (web pública, email, documento), no se usan aquí sino la función `SignFileURL`.
## Administrador de archivos [#administrador-de-archivos]
Lista todos los archivos e imágenes de una sección. Al pulsar un archivo se abre su ventana de Detalles.
| Elemento | Qué hace |
| --------------------- | ------------------------------------------------------------------------------------------------------- |
| Casilla **Ver todos** | Por defecto solo muestra la última versión de cada archivo. Activada muestra el histórico de versiones. |
| Arrastrar y soltar | Acepta soltar archivos sobre la lista para subirlos directamente. |
| Botón **Cerrar** | Cierra la ventana. |
## Subir archivo [#subir-archivo]
Ventana modal que sube el archivo al almacenamiento en segundo plano. Muestra el progreso de cada subida y no tiene más opción que el botón **Cancelar**, que aborta la subida en curso.
* **Deduplicación.** Antes de subir calcula la huella del archivo. Si el servidor ya lo tiene, lo reutiliza sin volver a subirlo.
* **Imágenes.** Genera y sube varios tamaños a la vez. Si no es imagen, sube el archivo tal cual.
* **Tamaño máximo.** Rechaza los archivos muy grandes con el aviso *La imagen es demasiado grande.*
## Detalles de archivo [#detalles-de-archivo]
Muestra la miniatura del archivo y una ficha de metadatos:
| Dato | Contenido |
| ----------------------------------------- | ---------------------------------------------- |
| Nombre / Nombre Original | Nombre en el sistema y el original al subirlo. |
| Ruta Original | Ruta de origen del archivo. |
| Tamaño | Tamaño formateado. |
| Extensión / Formato | Extensión y formato detectado. |
| Fecha de creación / modificación / subida | Fechas del archivo (subida en hora local). |
| Resolución / EsFlat | Solo imágenes: ancho por alto y si es plana. |
Si consta el usuario, muestra el empleado que subió el archivo con su avatar y nombre.
### Acciones [#acciones]
| Botón | Qué hace |
| ---------------- | ------------------------------------------------------------------------------ |
| **Descargar** | Descarga el archivo. Se habilita según el permiso del servidor. |
| **Vista previa** | Abre la ventana de Vista previa. Solo si el archivo la soporta en el Terminal. |
| **Copiar ID** | Copia el identificador del archivo al portapapeles. |
Si no tienes permiso de descarga, el Terminal responde *No tiene permisos para descargar este archivo.* El servidor revalida el permiso al servir el archivo, no solo al abrir la ventana.
* **Otras versiones.** Lista el histórico de versiones del mismo archivo. Al elegir otra versión, recarga la ficha para esa versión.
* **Comentarios internos.** Panel de comentarios sobre el archivo, sujeto a permisos para verlos y comentar.
* **Exportar en módulos** (solo desarrolladores). Marca si el archivo se incluye al empaquetar un módulo.
## Vista previa [#vista-previa]
Visor incrustado que muestra imágenes y PDFs a pantalla completa. Para imágenes pide al servidor el tamaño Original.
| Atajo | Acción |
| --------------- | ------------------------------------------------------ |
| Escape | Cierra la ventana. |
| F2 (**Fijar**) | Ancla la ventana arriba a la derecha, siempre visible. |
| F3 (**Venta**) | Crea un registro de venta a partir del archivo. |
| F4 (**Compra**) | Crea un registro de compra a partir del archivo. |
Los atajos **Venta** y **Compra** solo aparecen si tienes permiso para agregar en esas secciones. Con Shift al abrir, la ventana arranca ya en modo fijado.
## Formatos y tamaños [#formatos-y-tamaños]
Al subir una imagen, el sistema genera y almacena varios tamaños. Al descargar o previsualizar se pide el que corresponda: miniatura para la lista, Original para la vista previa.
Los tamaños disponibles (alto en píxeles) son **Original**, **32**, **100**, **300**, **720** y **1080**. Son los mismos valores que acepta el parámetro `tamaño` de `SignFileURL`.
Estas ventanas son para el operador del Terminal. Para acceder a un archivo por código sin sesión de usuario, usa la función DinaScript `SignFileURL`.
## Relacionado [#relacionado]
→ [Roles de campo: Archivo](/docs/desarrollo/flex/roles-de-campo)
→ [SignFileURL: servir archivos por código](/docs/desarrollo/flex/dinascript/funciones/documentos-y-graficos)
→ [Dinaup Terminal](/docs/desarrollo/recursos/dinaup-terminal)
→ [Diseñar secciones y campos](/docs/desarrollo/recursos/dinaup-terminal/ventanas/disenar-secciones-y-campos)
# Instalar y gestionar módulos (/docs/desarrollo/recursos/dinaup-terminal/ventanas/instalar-y-gestionar-modulos)
El Terminal tiene tres ventanas para instalar y mantener módulos. La galería elige qué instalar, la ventana de instalación ejecuta el plan, y la de Integridad repara objetos rotos. Es el reverso de [publicar un módulo](/docs/desarrollo/recursos/dinaup-terminal/ventanas/publicar-un-modulo), que cubre el lado productor. El concepto está en [módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales).
## Dónde se abre cada ventana [#dónde-se-abre-cada-ventana]
| Ventana | Cómo llegas |
| ---------------------------------------- | ------------------------------------------------------------------------------- |
| Galería (**Dinaup Módulos**) | Configuración global → **Módulos**, o desde la ventana de Módulos en desarrollo |
| Instalación (**Instalación de módulos**) | Se abre sola al instalar desde la galería |
| Integridad (**Integridad Sistema**) | Panel principal, acción Errores del panel de widgets |
## La galería de módulos disponibles [#la-galería-de-módulos-disponibles]
La ventana **Dinaup Módulos** (subtítulo *Panel de gestión de Módulos Dinaup*) lista todo lo que puedes instalar. Mientras carga muestra *Cargando galería...*.
La lista se agrupa por módulo y muestra la versión más reciente disponible en tu canal. Columnas:
| Columna | Qué muestra |
| --------- | -------------------------------- |
| Estado | Badge azul **Disponible** |
| Módulo | Nombre del módulo |
| Versión | Versión más reciente en tu canal |
| Autor | Quién lo publicó |
| Publicado | Fecha de publicación |
| Canal | Canal de distribución del módulo |
El canal queda fijado por tu licencia: la galería solo muestra los módulos de ese canal. Para entender qué implica cada canal, consulta [módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales).
Botones del pie:
* **Instalar Selección**: instala la fila marcada.
* **Visitar galeria de módulos**: abre la galería web en [www.dinaup.com/modulos](http://www.dinaup.com/modulos).
* **Cerrar**: cierra la ventana.
Para instalar haz doble clic sobre una fila, o márcala y pulsa **Instalar Selección**. Si no hay nada seleccionado, avisa: *Debe seleccionar al menos un elemento del listado*.
Al cerrar la galería, si has instalado algún módulo, el Terminal se reinicia solo para aplicar los cambios. Guarda tu trabajo antes.
## La ventana de instalación [#la-ventana-de-instalación]
Al lanzar la instalación se abre **Instalación de módulos**. Primero muestra *Cargando información necesaria...* mientras el servidor calcula el plan.
La cabecera resume el módulo: su icono, el nombre grande, la etiqueta **Desarrollado por:** con el autor y la versión (formato `vN`, por ejemplo `v2`).
Debajo va el plan de instalación, con una fila por cada pieza que hace falta:
| Columna | Qué muestra |
| ------- | ----------------------------------------- |
| Módulo | Pieza a instalar |
| Versión | Versión que se instalará |
| Estado | **Pendiente de instalar** (badge naranja) |
| Acción | Qué se hará con esa pieza |
Pulsa **Instalar módulos necesarios** para ejecutar el plan. El servidor resuelve las dependencias, descarga e instala, y al terminar bien la ventana se cierra sola. Mientras trabaja, el botón cambia a **Instalando** y la lista se bloquea para que no lances la instalación dos veces.
No puedes instalar dos módulos a la vez. Si ya hay uno en proceso, verás *Ya existe otro módulo en proceso de instalación*. En modo seguro tampoco se instala: cierra y reabre la ventana.
### Progreso cuando toca la base de datos [#progreso-cuando-toca-la-base-de-datos]
Si la instalación modifica la base de datos, aparece una ventana de progreso con avance por fases. Muestra tres fases que se marcan al completarse, una barra de porcentaje global y un contador de sub-acción del tipo *tantos de tantos*. Puede pedirte la contraseña de administrador para instalar o actualizar la base de datos.
## Reparar la integridad de objetos [#reparar-la-integridad-de-objetos]
La ventana **Integridad Sistema** localiza y arregla objetos rotos o con avisos: campos, algoritmos, secciones, destinaciones, scripts, informes y columnas. Su título es dinámico y resume la salud del sistema (errores, avisos e ignorados). Mientras calcula muestra *Comprobando integridad...*.
Columnas de la lista:
| Columna | Qué muestra |
| -------- | ----------------------------- |
| Nombre | Nombre del objeto |
| Tipo | Clase de objeto, con su icono |
| Seccion | Sección a la que pertenece |
| Tipo Adv | Tipo de aviso |
| Error ID | Identificador del error |
| Error | Descripción del problema |
Sobre el objeto seleccionado tienes tres acciones:
* **Autorreparar**: solo aparece si el error tiene una reparación automática conocida. Cubre casos como el nombre de una columna, la relación con la base, las etiquetas singular y plural invertidas, o quitar el icono de un campo.
* **Eliminar**: solo se ofrece cuando es seguro (ver aviso).
* **Aceptar**: cierra la ventana.
Atajos de teclado:
| Tecla | Acción |
| ----- | -------------------------------------------- |
| F4 | Desactiva el aviso seleccionado |
| F5 | Recalcula la integridad de todos los objetos |
| Supr | Elimina el objeto seleccionado, si es seguro |
No puedes eliminar un objeto publicado en un módulo, ni uno con referencias externas. Al borrar una sección se marcan también como eliminados sus campos, informes, algoritmos, scripts, destinadores y catálogos, previa confirmación.
Cada vez que reparas o eliminas, la lista se recarga y los contadores del título reflejan la nueva situación.
## Para seguir [#para-seguir]
* → [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales)
* → [Publicar un módulo](/docs/desarrollo/recursos/dinaup-terminal/ventanas/publicar-un-modulo)
* → [Flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo)
# Permisos y roles (/docs/desarrollo/recursos/dinaup-terminal/ventanas/permisos-y-roles)
Esta pantalla del Terminal (Configuración > Roles) administra un rol y define, sección por sección, qué puede hacer quien lo tenga asignado. Aquí tienes la referencia de todas sus opciones.
No es el concepto de usuarios y niveles ni el cómo asignar roles. Para eso:
* El recorrido completo de niveles, permisos y roles → [Usuarios, roles y permisos](/docs/guias/usuarios-roles-y-permisos)
* Los pasos generales y cómo asignar un rol a un usuario → [Permisos y roles](/docs/cuenta/permisos-y-roles)
Editar un rol afecta a todos los usuarios que lo tienen asignado. Un cambio aquí se aplica a todos ellos a la vez.
## Cabecera y controles del rol [#cabecera-y-controles-del-rol]
| Control | Qué hace |
| ------------------ | ----------------------------------------------------------------------- |
| Rol a gestionar | Nombre del rol que estás editando. |
| Todos los Permisos | Concede acceso total. Al activarlo se oculta el resto de configuración. |
| Ver auto-generados | Muestra también las secciones generadas de forma automática. |
| ¿Qué configurar? | Cambia entre dos modos: Secciones y Avanzado. |
| Opciones... | Menú con Administrar Secciones y Acceso Total. |
El pie tiene tres acciones: **Aplicar** (guarda sin cerrar), **Guardar** (guarda y cierra) y **Cancelar** o **Cerrar** según haya cambios pendientes.
## Modo Secciones [#modo-secciones]
En el panel izquierdo aparecen solo las secciones activadas en el rol, con sus columnas ID, Nombre y Módulo. Si está vacío, el rol no tiene ninguna sección. Las secciones se añaden y quitan desde Administrar Secciones. Un icono junto a cada fila abre el registro de esa sección.
### Permisos por sección [#permisos-por-sección]
Al seleccionar una sección aparece su matriz de permisos. Cada permiso se activa o desactiva por separado.
| Permiso | Qué habilita |
| ------------------------------ | ------------------------------------------------------ |
| Agregar | Crear registros nuevos en la sección. |
| Acceso | Entrar en la sección y ver sus registros. |
| Modificar | Editar registros existentes. |
| Ver eliminados | Ver los registros que están eliminados. |
| Eliminar | Eliminar registros. |
| Restaurar | Recuperar registros eliminados. |
| Ver histórico | Consultar el histórico de cambios del registro. |
| Compartir por chat | Enviar registros por el chat interno. |
| Imprimir | Imprimir el listado de la sección. |
| Exportar | Exportar el listado de la sección. |
| Ver comentarios | Leer los comentarios de los registros. |
| Comentar | Escribir comentarios en los registros. |
| Imprimir registro | Imprimir un registro concreto. |
| Opciones de control de lectura | Marcar registros como leídos y ver quién los ha leído. |
Dos botones aplican combinaciones de golpe:
| Botón | Qué activa |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Todo | Todos los permisos de la sección. |
| Solo lectura | Solo los de consulta (Acceso, Ver histórico, Ver comentarios, Comentar, Imprimir y Exportar listado, Imprimir registro, Opciones de control de lectura). Desactiva los de escritura. |
Si una sección queda sin Acceso ni Agregar, su fila se muestra bloqueada y rayada: el rol no puede hacer nada en ella.
### Informes y diseño por sección [#informes-y-diseño-por-sección]
Cada sección tiene ajustes propios de presentación:
| Ajuste | Qué controla |
| ---------------------------- | ------------------------------------------------------------------------------------------- |
| Informe Principal | Informe que ve el rol al abrir un registro. |
| Informe Búsqueda | Informe usado en la búsqueda de la sección. |
| Informe Principal Lista | Informe de lista, solo si la sección contiene lista. |
| Configuración predeterminada | Dos selectores: el diseño que ve el rol al crear (Agregar) y al editar (Editar). |
| Condición | Filtra a qué registros accede el rol dentro de la sección: por registro, grupo o condición. |
El diseño que fija Configuración predeterminada se crea aparte → [Crear un diseño de sección](/docs/cuenta/permisos-y-roles/crear-diseno-de-seccion).
## Administrar Secciones [#administrar-secciones]
Se abre desde **Opciones... > Administrar Secciones** (no está disponible con Todos los Permisos activado). Lista todas las secciones configurables, agrupadas por tipo y por módulo.
Cada sección tiene un conmutador con dos estados: **Accesible** y **Sin Acceso**. Al guardar, las secciones marcadas Accesible se añaden al rol y las demás se quitan.
## Modo Avanzado [#modo-avanzado]
El modo Avanzado reúne casillas que afectan a todo el rol, no a una sección concreta.
Los textos exactos de estas casillas pueden variar en pantalla. Ábrela en el Terminal para contrastarlos.
* **Sesión**: Administrar sesiones (ver favoritos e histórico de otros usuarios y finalizar sus sesiones y turnos), Importador de datos.
* **Ocultar accesos**: Ocultar acceso a informes, a históricos y a configuración; Ocultar registros y comentarios internos.
* **Bloqueos del alta**: Bloquear campos de autor del alta, campos de fecha de alta y el campo de ubicación principal; Bloquear históricos.
* **Disposiciones**: Administrar disposiciones públicas, Administrar disposiciones personales.
* **Datos relacionados**: Bloquear datos relacionados de informes, relaciones o datos. Marcar Bloquear todo fuerza y deshabilita las opciones individuales.
## Presets de rol [#presets-de-rol]
Al pulsar el botón de presets se abre una ventana que aplica un conjunto de permisos de golpe a todo el rol.
| Preset | Estado |
| ---------------------------- | ----------------------------------------- |
| Ninguno | Operativo. Deja el rol sin acceso a nada. |
| Máximo | Operativo. Concede acceso total. |
| Privada, Compañeros, Pública | No disponibles todavía en esta versión. |
Además, **Opciones... > Acceso Total** aplica el preset Máximo a las secciones seleccionadas o a todas.
## Empieza por el mínimo [#empieza-por-el-mínimo]
La ventana está pensada para conceder lo justo. Una sección nueva entra Sin Acceso por defecto, tienes el botón Solo lectura para dar solo consulta, y los presets van de Ninguno a Máximo.
Recomendación: activa solo las secciones y permisos que el rol necesite, y usa Solo lectura salvo que haga falta escritura. Es el mismo principio de empezar por el nivel más bajo que se explica en la [guía de usuarios, roles y permisos](/docs/guias/usuarios-roles-y-permisos).
La Condición de acceso permite además agrupar registros de forma dinámica para condicionar a cuáles llega el rol; es un ajuste de acceso, no una tabla de permisos.
## Relacionado [#relacionado]
* → [Permisos y roles: pasos y asignación](/docs/cuenta/permisos-y-roles)
* → [Usuarios, roles y permisos](/docs/guias/usuarios-roles-y-permisos)
* → [Crear un diseño de sección](/docs/cuenta/permisos-y-roles/crear-diseno-de-seccion)
* → [Cómo crear y asignar roles de usuario](/docs/cuenta/permisos-y-roles/como-crear-y-asignar-roles-de-usuario-en-dinaup)
* → [Diseñar secciones y campos](/docs/desarrollo/recursos/dinaup-terminal/ventanas/disenar-secciones-y-campos)
# Publicar un módulo (/docs/desarrollo/recursos/dinaup-terminal/ventanas/publicar-un-modulo)
Cuando tu trabajo en Flex está listo, lo empaquetas como módulo y lo publicas por un canal. Esta página es la referencia de la ventana de publicación: qué pide, cómo decide la versión y por qué a veces no puedes publicar. Para el concepto de módulos y canales, ve a [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales); para el ciclo completo, a [Flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo).
## La ventana de publicación [#la-ventana-de-publicación]
Accedes desde el **Estado módulo**, con el botón **Publicar módulo**. La ventana pide cuatro cosas y tiene dos botones: **Publicar módulo** y **Cancelar**.
Mientras se envía, los controles se bloquean. Así no publicas dos veces por error.
## Los cuatro campos [#los-cuatro-campos]
| Campo | Qué es | ¿Lo editas? |
| --------------------------------------- | -------------------------------------------------------------------- | ----------------------------- |
| Nombre del módulo | El del módulo en desarrollo. Solo hay un módulo activo por licencia. | No. Lo determina tu proyecto. |
| Versión | El número que tendrá esta publicación. | No. Se calcula sola. |
| Canal de publicación | Quién recibe el módulo: Desarrollo (dev), Beta o Estable (release). | Sí. Por defecto, Desarrollo. |
| Descripción de funcionalidad del módulo | Resume qué trae el módulo para quien lo instale. | Sí. Es obligatoria. |
El nombre del módulo no puede ser numérico.
**Cómo se calcula la versión.** Terminal toma la más alta que ya exista del módulo, mirando todos los canales a la vez, y le suma uno. Si en desarrollo hay una v2 y en producción una v3, la siguiente es v4.
**Qué hace el canal.** El canal decide quién recibe el módulo. La versión es la misma se publique donde se publique. Elige el destino en [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales).
**La descripción.** Escribe qué trae esta versión, para quien la instale o para tu yo del futuro. Admite textos largos.
## Antes de publicar: dependencias [#antes-de-publicar-dependencias]
Antes de dejarte publicar, Terminal comprueba que el módulo esté completo. Un módulo depende de piezas: secciones, campos, algoritmos, informes. Si alguna de ellas apunta a algo que no incluyes o que quedó huérfano, la publicación se bloquea hasta que lo resuelvas.
Esto evita el problema clásico: instalar un módulo que "casi" funciona porque le faltaba algo de origen.
Desde el **Estado módulo** puedes:
* Revisar la lista de lo que se va a exportar: secciones, campos, algoritmos e informes.
* En una actualización, ver qué ha cambiado respecto a la versión anterior.
* Revisar que las columnas de tus informes no dependan de otros módulos.
## Por qué a veces no puedes publicar [#por-qué-a-veces-no-puedes-publicar]
* Falta la descripción, que es obligatoria.
* Hay objetos rotos o dependencias sin resolver: arréglalos y vuelve.
* El nombre del módulo es numérico, y eso no se permite.
* Tu licencia no tiene el desarrollo de módulos activo.
## Qué pasa al publicar [#qué-pasa-al-publicar]
Al pulsar **Publicar módulo**, Terminal valida y envía el módulo; el empaquetado final lo hace el servidor. Si va bien, la ventana te lo confirma y el botón pasa a **Aceptar**. Si algo falla, te muestra el motivo y puedes reintentar.
En una actualización, la versión sube sola y es la misma para todos los canales. El canal solo decide el destino, no el número de versión.
## Siguiente paso [#siguiente-paso]
→ [Módulos y canales](/docs/desarrollo/recursos/dinaup-terminal/modulos-y-canales)
→ [Flujo de desarrollo](/docs/desarrollo/recursos/dinaup-terminal/flujo-de-desarrollo)
→ [Instalar Terminal y publicar un módulo](/docs/guias/instalar-terminal-y-publicar-modulo)
# Categorías de Compra (/docs/rtg/pymes/facturacion/compras/categorias-de-compra)
Una **categoría de compra** es una etiqueta que clasifica tus compras y gastos según su tipo o finalidad: suministros, servicios profesionales, alquiler, combustible, material de oficina, etc. Sirve para dos cosas a la vez: **analizar en qué gastas** y que cada gasto **se contabilice solo**, porque cada categoría puede ligarse a una cuenta contable.
Es el hermano de las [categorías de venta](/docs/rtg/pymes/facturacion/ventas/categorias-de-venta): funcionan igual, pero unas clasifican lo que entra y otras lo que sale.
***
## Para qué sirven [#para-qué-sirven]
* **Analizar tus gastos por tipo.** Saber cuánto se va en alquiler, en suministros o en servicios profesionales, en lugar de ver solo un total de compras.
* **Contabilizar automáticamente.** Si ligas una categoría a una cuenta contable, cada gasto que asignes a esa categoría se asienta en la cuenta correcta sin decidirlo factura a factura.
* **Detectar gastos sin clasificar.** Un gasto sin categoría no encaja en ningún informe. Tenerlos todos categorizados deja los libros listos para el asesor.
Cuando subes una factura de gasto en PDF, Dinaup propone una **categoría sugerida** junto al resto de datos. Tú revisas y confirmas.
***
## Categoría y cuenta contable [#categoría-y-cuenta-contable]
Una categoría de compra y una cuenta contable son cosas distintas que trabajan juntas:
| | Categoría de compra | Cuenta contable |
| ---------- | ------------------------------------------------ | --------------------------------------------- |
| Qué es | Una etiqueta de negocio para clasificar el gasto | La cuenta del plan contable donde se registra |
| Para quién | Para ti: análisis y control interno | Para la contabilidad y tu asesor |
| Relación | Se **liga** a una cuenta contable | Recibe los apuntes de las categorías ligadas |
Al asociar la categoría a una cuenta, el sistema sabe a qué cuenta del [plan contable](/docs/rtg/pymes/contabilidad) llevar cada gasto que clasifiques con ella. Así la categorización que haces pensando en tu negocio se traduce sola en un asiento correcto.
***
## Crear una categoría de compra [#crear-una-categoría-de-compra]
### Abre las categorías de compra [#abre-las-categorías-de-compra]
Ve a **Pymes → Compras y gastos** y entra en la configuración de **categorías de compra**.
### Añade una categoría nueva [#añade-una-categoría-nueva]
Crea la categoría y dale un nombre claro que identifique el tipo de gasto (por ejemplo, *Suministros*, *Alquiler* o *Servicios profesionales*). El nombre es lo que verás al clasificar cada compra, así que cuanto más reconocible, mejor.
### Lígala a una cuenta contable [#lígala-a-una-cuenta-contable]
Asocia la categoría a la **cuenta contable** que le corresponda. Es el paso que activa la contabilización automática: a partir de ahí, todo gasto que asignes a esta categoría se asienta en esa cuenta.
### Úsala al registrar gastos [#úsala-al-registrar-gastos]
Con la categoría creada, ya aparece como opción al registrar una compra o un gasto. Asígnala y el gasto queda clasificado para análisis y listo para contabilizar.
Crea pocas categorías y claras antes que muchas y solapadas. Un puñado de categorías bien definidas es más útil que una lista interminable donde nunca sabes cuál elegir.
***
## Cómo se usan en el día a día [#cómo-se-usan-en-el-día-a-día]
Cada vez que registras una compra o un gasto, le asignas su categoría. A partir de ese momento:
* El gasto **suma en su categoría** y aparece agrupado en los informes por tipo de gasto.
* Si la categoría está ligada a una cuenta, el gasto **se contabiliza solo** en la cuenta correcta.
* Al revisar el periodo, puedes detectar los **gastos sin categoría** y clasificarlos antes de cerrar.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La categoría es una etiqueta de negocio que usas tú para clasificar el gasto por tipo. La cuenta contable es la cuenta del plan contable donde se registra. Ligas una categoría a una cuenta para que la clasificación se contabilice sola.
No. Puedes usar las categorías solo para analizar tus gastos por tipo. Ligarlas a una cuenta es lo que añade la contabilización automática, así que es muy recomendable si llevas la contabilidad en Dinaup.
Funcionan igual, pero clasifican cosas distintas: las de compra etiquetan tus gastos y las de venta etiquetan tus ingresos. Las dos sirven para analizar y para que la contabilización salga sola.
Las que necesites. Lo recomendable es mantener una lista corta y clara, con una categoría por cada tipo de gasto relevante de tu negocio.
***
→ [Gestión de compras y gastos](/docs/rtg/pymes/facturacion/compras/gestion-de-compras-y-gastos)
→ [Categorías de venta](/docs/rtg/pymes/facturacion/ventas/categorias-de-venta)
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
# Gestión de Compras y Gastos (/docs/rtg/pymes/facturacion/compras/gestion-de-compras-y-gastos)
### Inicia sesión en Play.Dinaup.com [#inicia-sesión-en-playdinaupcom]
[Play.dinaup.com](https://play.dinaup.com/)
### Accede a la App de Pymes [#accede-a-la-app-de-pymes]
### Entra al apartado de "Gastos" [#entra-al-apartado-de-gastos]
# Compras (/docs/rtg/pymes/facturacion/compras)
Registro y gestión de facturas recibidas y gastos:
* [Categorías de Compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra): clasificación analítica.
* [Gestión de Compras y Gastos](/docs/rtg/pymes/facturacion/compras/gestion-de-compras-y-gastos): alta y trabajo diario.
# Categorías de Venta (/docs/rtg/pymes/facturacion/ventas/categorias-de-venta)
Una **categoría de venta** clasifica tus ventas e ingresos por línea de negocio o por tipo de producto o servicio. Es una etiqueta analítica: agrupa lo que facturas para que veas, por ejemplo, cuánto ingresas por "Servicios", cuánto por "Productos" y cuánto por "Cursos". También sirve para que la contabilización automática sepa a qué cuenta llevar cada venta.
No tiene nada que ver con el régimen fiscal de la factura: de eso se encarga el [tipo de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos). La categoría dice **a qué línea de negocio pertenece** la venta; el tipo de venta dice **cómo se comporta fiscalmente**.
***
## Categoría de venta frente a tipo de venta [#categoría-de-venta-frente-a-tipo-de-venta]
Son dos clasificaciones distintas y complementarias. En una misma factura conviven las dos: el tipo de venta decide el IVA, las validaciones y la numeración; la categoría decide en qué grupo de negocio cuenta ese ingreso.
| | Categoría de venta | [Tipo de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) |
| -------------- | ------------------------------------------------- | ------------------------------------------------------------------------------ |
| Para qué sirve | Agrupar ventas por línea de negocio o producto | Definir el régimen fiscal y el comportamiento de la factura |
| Qué responde | "¿De qué es esta venta?" | "¿Cómo se factura esta venta?" |
| Ejemplos | Servicios, Productos, Cursos, Mantenimientos | Nacional, Simplificada, Intracomunitaria, OSS, Exportación |
| Dónde se usa | Informes de ingresos y contabilización automática | IVA, retenciones, validaciones de NIF, numeración |
Si nunca has separado tus ventas por línea de negocio, no pasa nada: puedes empezar con unas pocas categorías generales (por ejemplo "Productos" y "Servicios") y afinarlas más adelante.
***
## Para qué sirven [#para-qué-sirven]
Una categoría bien puesta trabaja para ti en dos sitios:
* **Análisis de ingresos**: los informes agrupan tus ventas por categoría, así que sabes qué línea de negocio te aporta más. En el informe de **Pérdidas y Ganancias** ves los ingresos repartidos por categoría, igual que los gastos.
* **Contabilización automática**: la categoría sirve de criterio para llevar cada venta a su cuenta contable. Cuando generas los asientos de forma masiva, Dinaup usa la categoría para asignar la cuenta de ingresos correcta sin que tengas que decidirlo factura a factura.
→ [Contabilidad y contabilización automática](/docs/rtg/pymes/contabilidad)
***
## Crear una categoría de venta [#crear-una-categoría-de-venta]
### Abre la configuración de ventas [#abre-la-configuración-de-ventas]
Ve a **Pymes → Configuras → Ventas**. Ahí gestionas los elementos que clasifican tu facturación, entre ellos las categorías de venta.
### Crea una categoría nueva [#crea-una-categoría-nueva]
Añade una categoría y dale un nombre claro que identifique la línea de negocio (por ejemplo, "Servicios profesionales" o "Venta de material"). El nombre es lo que verás luego en los informes, así que cuanto más reconocible, mejor.
### Asígnala a tus productos y servicios [#asígnala-a-tus-productos-y-servicios]
En la ficha de cada producto o servicio elige su categoría de venta. A partir de ahí, cada vez que vendas ese producto, la línea de la factura hereda la categoría: no tienes que indicarla a mano.
La categoría parte del producto, pero un **tipo de venta** puede sobrescribirla. Si configuras una categoría en la ficha de un tipo de venta, esa categoría sustituye a la del producto para todas las facturas de ese tipo. Útil cuando un mismo producto debe contar en líneas distintas según el escenario de venta.
***
## Cómo se asigna la categoría a una venta [#cómo-se-asigna-la-categoría-a-una-venta]
La categoría llega a la factura por sí sola, siguiendo este orden:
1. **Desde el producto o servicio**: cada línea hereda la categoría definida en la ficha del producto que vendes.
2. **Desde el tipo de venta** (si lo sobrescribe): si el tipo de venta tiene una categoría configurada, manda sobre la del producto.
3. **Ingresos sin factura**: un ingreso que no es una venta (una subvención, una devolución de impuestos) también puede clasificarse con su categoría para que cuente en el sitio correcto del análisis y la contabilidad.
Al analizar o contabilizar, cada venta ya está clasificada en su línea de negocio.
***
## Preguntas frecuentes [#preguntas-frecuentes]
La categoría clasifica la venta por línea de negocio o tipo de producto (para análisis y contabilización). El tipo de venta define el comportamiento fiscal de la factura: IVA, retenciones, validaciones de NIF y numeración. Son cosas distintas y conviven en la misma factura.
No. La categoría se hereda del producto o servicio que vendes, o del tipo de venta si lo sobrescribe. Solo defines la categoría una vez, en la ficha del producto.
Sirve de criterio en la contabilización automática: Dinaup usa la categoría para llevar cada venta a su cuenta de ingresos al generar los asientos de forma masiva.
Sí. Las compras y gastos se clasifican con [categorías de compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra), que funcionan igual pero para el lado de los gastos.
***
→ [Tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
→ [Categorías de compra](/docs/rtg/pymes/facturacion/compras/categorias-de-compra)
→ [Contabilidad](/docs/rtg/pymes/contabilidad)
# Devoluciones y Abonos (/docs/rtg/pymes/facturacion/ventas/devoluciones-y-abonos)
Cuando un cliente te devuelve mercancía o le reintegras un importe, no borras ni editas la venta original: creas una **devolución** ligada a ella. Esa devolución mueve el stock y el dinero en sentido contrario. A efectos fiscales, genera una **factura rectificativa** (el abono) que corrige la venta inicial.
Hay dos conceptos que conviene no mezclar:
* **Devolución**: el hecho real. La mercancía vuelve a tu almacén y/o le devuelves dinero al cliente.
* **Rectificativa**: el documento fiscal que respalda esa devolución. Es una factura con su propia numeración que rectifica la original.
Una devolución en Dinaup genera siempre su rectificativa: así el almacén, la tesorería y los libros oficiales cuadran a la vez.
***
## Devolución total o parcial [#devolución-total-o-parcial]
No tienes que devolver la venta entera. Al iniciar la devolución, eliges **cuántas unidades de cada línea** se devuelven:
* **Total**: devuelves todas las unidades de la venta. La rectificativa anula el importe completo.
* **Parcial**: devuelves solo parte (algunas unidades de una o varias líneas). La rectificativa corrige únicamente lo devuelto, y el resto de la venta sigue en pie.
Dinaup sabe en todo momento cuánto queda por devolver de cada producto: si ya rectificaste parte, solo te deja devolver lo que aún no habías devuelto. Así no puedes abonar de más por error.
***
## Cómo hacer una devolución [#cómo-hacer-una-devolución]
Una devolución se crea **desde la propia venta**, no como un documento suelto. Eso es lo que mantiene atada la trazabilidad: la rectificativa nace vinculada a la factura que corrige.
### Abre la venta a devolver [#abre-la-venta-a-devolver]
Localiza la factura de venta original y ábrela. Dentro verás su detalle, con el cobro, las salidas de mercancía y el bloque de **Devolución**.
### Inicia la devolución [#inicia-la-devolución]
Pulsa **Iniciar devolución**. Dinaup prepara una rectificativa **vinculada a esa venta**, que hereda el cliente, sus datos fiscales, los impuestos y el resto de condiciones de la factura original.
### Indica qué se devuelve [#indica-qué-se-devuelve]
Ajusta las unidades de cada línea que el cliente devuelve. Déjalas todas para una devolución total, o reduce las cantidades para una devolución parcial.
### Confirma la rectificativa [#confirma-la-rectificativa]
Al grabar, queda creada la factura rectificativa de abono. La mercancía devuelta vuelve a entrar en tu almacén y el importe queda registrado a favor del cliente.
La rectificativa se marca de forma bien visible con la etiqueta **Rectificativa** para que nadie la confunda con una venta normal.
***
## Qué cambia en stock y tesorería [#qué-cambia-en-stock-y-tesorería]
Una devolución es el reflejo en espejo de la venta:
| | En la venta | En la devolución |
| ------------- | ------------------------- | --------------------------------- |
| **Mercancía** | Sale del almacén (salida) | Vuelve al almacén (entrada) |
| **Dinero** | Lo cobras del cliente | Lo abonas / reintegras al cliente |
| **Documento** | Factura de venta | Factura rectificativa (abono) |
Al confirmar la devolución, el producto vuelve a estar disponible para vender y el saldo del cliente refleja el importe que le corresponde.
***
## La rectificativa: el documento fiscal [#la-rectificativa-el-documento-fiscal]
La **rectificativa** es el documento que hace válida la devolución de cara a Hacienda. Es una factura con serie y numeración propias que **corrige** la original.
Cuando inicias la devolución, eliges (o Dinaup propone) la forma de rectificar:
* **Por diferencias**: la rectificativa recoge solo lo que cambia respecto a la factura original (el importe devuelto). Es lo habitual en una devolución de mercancía.
* **Por sustitución**: la rectificativa reemplaza por completo la factura original por una nueva. Útil cuando la primera era inválida y hay que rehacerla entera.
**No puedes rectificar una rectificativa.** Si necesitas corregir de nuevo, crea una nueva rectificativa vinculada a la **factura original**, no a la de abono.
El tipo concreto de rectificativa (las claves R1, R2… y los criterios "por sustitución" / "por diferencias") es una cuestión fiscal que Dinaup gestiona por ti según el caso. El detalle de cada tipo está en la página de Verifactu.
→ [Verifactu y tipos de factura rectificativa](/docs/rtg/pymes/facturacion/ventas/verifactu)
***
## Trazabilidad: la venta y su abono, conectados [#trazabilidad-la-venta-y-su-abono-conectados]
Devolver desde la venta deja las dos **enlazadas**:
* Desde la **venta original** ves el historial de sus devoluciones: cada rectificativa con su estado, su número, su fecha, las unidades y el importe devuelto.
* Cada **rectificativa** apunta a la factura que corrige.
Así, ante cualquier revisión, sabes qué se devolvió, cuándo y contra qué venta. Nada queda huérfano: una venta parcialmente devuelta muestra tanto lo que se vendió como lo que volvió.
Puedes hacer **varias devoluciones parciales** sobre la misma venta a lo largo del tiempo. Todas se acumulan en el historial de esa factura, y Dinaup controla que entre todas no devuelvas más de lo vendido.
***
## Devoluciones en el TPV (cobro rápido) [#devoluciones-en-el-tpv-cobro-rápido]
En el TPV puedes resolver una devolución sin salir de la pantalla de cobro. Cuando una operación es una devolución, su total es **negativo**, y el cobro rápido cambia de modo: en lugar de "cobrar", **devuelve dinero**.
La pantalla se adapta para que el operario no tenga que hacer cuentas raras:
* En vez de **A cobrar**, ves **A devolver al cliente**.
* En vez de **Pago recibido**, tecleas el **dinero entregado al cliente** (siempre en positivo, sin signos).
* Dinaup calcula **lo que el cliente debe reintegrarte** si le entregas de más, igual que calcularía el cambio en una venta normal.
Esto registra el efectivo real que sale del cajón, de modo que el **arqueo de caja sigue cuadrando**: la devolución resta de la caja exactamente lo que entregaste.
Como el efectivo de una devolución **sale** de la caja, cuéntalo en el cierre igual que cuentas las entradas. El cierre lo tiene en cuenta para que el recuento físico cuadre con lo esperado.
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
***
## Preguntas frecuentes [#preguntas-frecuentes]
La devolución es el hecho real: la mercancía vuelve y/o reintegras dinero. La rectificativa es el documento fiscal (una factura de abono con su propia numeración) que respalda esa devolución corrigiendo la venta original. En Dinaup, hacer una devolución genera su rectificativa.
Sí. Al iniciar la devolución eliges cuántas unidades de cada línea se devuelven. Puedes hacer varias devoluciones parciales sobre la misma factura; Dinaup controla que entre todas no superes lo vendido.
No. Abres la venta original, pulsas Iniciar devolución y Dinaup prepara la rectificativa ya vinculada, con el cliente, los impuestos y las condiciones heredados de la factura inicial.
No se puede rectificar una rectificativa. Crea una nueva rectificativa vinculada a la factura de venta original, no a la de abono.
Cuando la operación es una devolución, su total es negativo y la pantalla de cobro pasa a modo devolución: indica el dinero que entregas al cliente y Dinaup ajusta la caja. El efectivo sale del cajón, así que el cierre seguirá cuadrando.
La mercancía devuelta vuelve a entrar en tu almacén y queda otra vez disponible para vender. Es el movimiento inverso de la salida que provocó la venta.
***
→ [Ventana de Factura](/docs/rtg/pymes/facturacion/ventas/ventana-de-factura)
→ [Verifactu y rectificativas](/docs/rtg/pymes/facturacion/ventas/verifactu)
→ [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
→ [Cobrar en el TPV](/docs/rtg/tpv/procesos/cobro)
# Fechas en facturas (/docs/rtg/pymes/facturacion/ventas/fechas-en-facturas)
En Dinaup, cada factura (ya sea de **ventas** o de **compras**) utiliza tres fechas distintas, cada una con un propósito propio.
### 1. Fecha Principal [#1-fecha-principal]
Corresponde a la **fecha de expedición** de la factura, es decir, la que figura en el propio documento.
* Al crear una factura, Dinaup rellena este campo con la **fecha actual**.
* Si la factura incluye otra fecha, como “15 de enero”, esa es la que deberías indicar.
### 2. Fecha Contable [#2-fecha-contable]
Define el periodo en el que la factura se refleja en el **Libro Registro de Facturas** (tanto emitidas como recibidas).
* Si no indicas una fecha, Dinaup asigna la **fecha actual** al guardar.
* Si estás registrando una factura de un trimestre pasado pero necesitas declararla en el trimestre actual, asegúrate de que la **Fecha Contable** sea la del trimestre en curso.
### 3. Fecha de Operación [#3-fecha-de-operación]
Es la fecha en la que se realizó la operación (entrega del bien o prestación del servicio).
* Si no indicas ninguna, Dinaup utiliza la **Fecha Principal**.
* Solo necesitas modificarla cuando la fecha de expedición y la fecha de la operación no coinciden.
# Gestión Archivos (/docs/rtg/pymes/facturacion/ventas/gestion-archivos)
Los empleados cargan archivos en el sistema y quedan disponibles en una cola de revisión. Al pulsar el botón **“+”**, se abre el formulario con los campos ya completados por la IA.
El flujo es: se sube el archivo, la IA interpreta los datos clave y el responsable valida o descarta.
# Ventas (/docs/rtg/pymes/facturacion/ventas)
Emisión y gestión de facturas a clientes:
* [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos): nacional, intracomunitaria, exportación, OSS, etc.
* [Categorías de Venta](/docs/rtg/pymes/facturacion/ventas/categorias-de-venta): clasificación analítica.
* [Fechas en facturas](/docs/rtg/pymes/facturacion/ventas/fechas-en-facturas): fecha de expedición vs. fecha registro.
* [Libros Registro y Tipos de Venta](/docs/rtg/pymes/facturacion/ventas/libros-registro-y-tipos-de-venta): relación entre tipos y libros oficiales.
* [Verifactu](/docs/rtg/pymes/facturacion/ventas/verifactu): cumplimiento del Real Decreto 1007/2023.
* [Gestión Archivos](/docs/rtg/pymes/facturacion/ventas/gestion-archivos): buzón de documentos con IA.
* [Ventana de Factura](/docs/rtg/pymes/facturacion/ventas/ventana-de-factura): referencia de campos del formulario.
# Libros Registro y Tipos de Venta (/docs/rtg/pymes/facturacion/ventas/libros-registro-y-tipos-de-venta)
Tres conceptos que verás al facturar en Dinaup: **libros registro, tipos de venta y ventas**.
## Libros [#libros]
Un **libro registro** es el listado de todas tus facturas agrupadas por su naturaleza fiscal. Es la forma tradicional de clasificar la facturación para tenerla siempre lista ante Hacienda o tu asesoría. [Puedes exportar estos libros a Excel](/docs/rtg/pymes/procesos/exportacion).
| Ejemplo de libro registro | ¿Qué agrupa? |
| ---------------------------------- | ------------------------------------------- |
| **Ventas nacionales** | Facturas emitidas dentro de España. |
| **Ventas simplificadas (tickets)** | Facturas simplificadas o tickets. |
| **Ventas intracomunitarias** | Facturas a clientes de la UE con NIF-IVA. |
| **Exportaciones fuera de la UE** | Operaciones con clientes extracomunitarios. |
Desde `Pymes` > `Configuras` > `Ventas` > `Libros de venta` puedes crear libros nuevos y editar los existentes.
## Tipos [#tipos]
Un **tipo de venta** no es un libro registro, sino la *configuración* que determina cómo se comporta cada factura dentro de Dinaup.
| Ejemplo de tipo | ¿Qué hace diferente? |
| ---------------------------- | ------------------------------------------------- |
| **Factura simplificada** | Usa una serie numérica específica. |
| **Venta online** | Aplica una plantilla de impresión distinta. |
| **Factura intracomunitaria** | Activa *inversión del sujeto pasivo* por defecto. |
Puedes crear tantos tipos de venta como necesites, uno por cada escenario fiscal o flujo habitual. Cada vez que factures, eliges el tipo y Dinaup rellena el resto.
# Presupuestos (/docs/rtg/pymes/facturacion/ventas/presupuestos)
Un **presupuesto** es la oferta que mandas a un cliente antes de vender: los conceptos, sus precios y el total, sin efecto fiscal. Es el primer paso de la pre-venta. Cuando el cliente lo acepta, el presupuesto se convierte en [pedido](/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos) o directamente en [venta](/docs/rtg/pymes/facturacion/ventas).
Llegas desde **Pymes → Pre Venta → Presupuestos**.
***
## Qué ves en la pantalla [#qué-ves-en-la-pantalla]
La pantalla organiza los presupuestos en pestañas:
| Pestaña | Qué muestra |
| ---------------- | -------------------------------------------------------------- |
| **Presupuestos** | El listado de presupuestos con sus importes, estados y fechas. |
| **Notas** | Anotaciones y ayuda de la sección. |
Desde el listado filtras y buscas para localizar un presupuesto concreto, y lo abres para editarlo o cambiarle el estado.
***
## Qué acciones tienes [#qué-acciones-tienes]
En la barra de herramientas aparece **un botón por cada tipo de venta** que tengas habilitado. Cada botón abre la ventana de presupuesto con ese tipo ya aplicado (numeración, serie e impuestos). Si un tipo está marcado como táctil, su botón usa el modo TPV.
Los botones que ves dependen de tus [tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos). Si no aparece ninguno, crea o habilita un tipo de venta primero.
***
## Del presupuesto a la venta [#del-presupuesto-a-la-venta]
El presupuesto no factura: es una propuesta. Su recorrido habitual es:
1. **Creas el presupuesto** con el botón de su tipo y se lo envías al cliente.
2. **El cliente lo acepta.**
3. **Lo conviertes** en un [pedido](/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos) (si hay que preparar o servir algo) o directamente en una [factura de venta](/docs/rtg/pymes/facturacion/ventas).
***
## Preguntas frecuentes [#preguntas-frecuentes]
No. Es una oferta sin efecto fiscal ni de inventario. El stock se mueve y la factura se emite cuando el presupuesto se convierte en venta.
Porque no tienes ningún tipo de venta habilitado. Los botones de la barra salen de tus tipos de ventas e ingresos: crea o activa uno y aparecerá.
***
→ [Gestión de pedidos](/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos)
→ [Facturación de ventas](/docs/rtg/pymes/facturacion/ventas)
→ [Tipos de ventas e ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
# Ventana de Factura (/docs/rtg/pymes/facturacion/ventas/ventana-de-factura)
## Fechas [#fechas]
1. **Fecha de Expedición**
1. Si se deja vacía se asigna la fecha actual en el momento de guardar
2. **Fecha Registro**
1. Si se deja vacía se asigna la fecha de expedición.
# Verifactu (/docs/rtg/pymes/facturacion/ventas/verifactu)
Con el cumplimiento en Verifactu, la ventana de factura cambia: algunos campos pasan a ser obligatorios, otros se bloquean y, al aceptar, Dinaup comprueba que el registro sea válido antes de firmarlo y enviarlo a la AEAT. Esta página es la referencia de ese comportamiento y de las claves de tipo de factura. Para activar Verifactu y seguir el estado de los envíos, ver la [guía de facturación y Verifactu](/docs/guias/verifactu).
***
## Qué cambia en la ventana de factura [#qué-cambia-en-la-ventana-de-factura]
Dinaup ajusta la ventana en cuanto la empresa factura bajo Verifactu. No son errores: es el formulario guiándote hacia un registro válido.
| Comportamiento | Cuándo ocurre |
| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| **Serie**, **Número**, **Número completo** y **ES - Tipo de Factura** pasan a obligatorios | Cuando escribes la numeración a mano en vez de elegir una serie de numeración automática. |
| **Serie** y **Número** se bloquean como "Automático" | Cuando la factura tiene una serie de numeración asignada: los rellena la serie, no tú. |
| **NIF** y **Nombre del emisor** (tercero) se vacían y bloquean | Mientras **Expedida por tercero** no esté marcada. Al marcarla, ambos pasan a ser exigidos. |
| Los **datos fiscales del receptor** se vacían y bloquean | Cuando el tipo es **F2** o **R5** (simplificadas): una factura simplificada no identifica al destinatario. |
## Comprobaciones al aceptar [#comprobaciones-al-aceptar]
Al aceptar la factura, Dinaup valida el registro. Si algo no cuadra, muestra el motivo y no guarda; el mismo control aplica a las escrituras por API.
| Comprobación | Qué exige |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Numeración completa** | Si rellenas alguno de **Número**, **Serie** o **Número completo**, deben estar los tres. |
| **Expedida por tercero** | Con la casilla marcada, **NIF del emisor** y **Nombre del emisor** son obligatorios. |
| **Coherencia del tipo** | Una factura **rectificativa** debe llevar clave **R1–R5**; una no rectificativa, **F1–F3**. |
| **Impuestos preparados para Verifactu** | Cada impuesto usado en la venta debe tener valor en **ES - Tipo**, **ES - Clasificación de la Operación**, **ES - Clave de Régimen** y **ES - Causa de Sujeción**. Se corrige en la ficha del [impuesto](/docs/rtg/pymes/configuracion/impuestos), no en la factura. |
## Una vez enviada a la AEAT [#una-vez-enviada-a-la-aeat]
Un registro remitido a la AEAT deja de ser editable: los campos que alteran importes (descuentos, retención, inclusión de impuestos, recargo de equivalencia) se bloquean con el motivo a la vista. Si necesitas corregir la operación, el camino es una **factura rectificativa**, no editar la original. La única excepción es una factura cuyo envío quedó **Rechazada**: esa sí se corrige y se reenvía, como cuenta la [guía de Verifactu](/docs/guias/verifactu).
***
## Tipos de factura: claves de la AEAT [#tipos-de-factura-claves-de-la-aeat]
El campo **ES - Tipo de Factura** clasifica el registro ante la AEAT. Claves para facturas normales:
| Clave | Cuándo se usa |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F1** | Factura completa (arts. 6, 7.2 y 7.3 del RD 1619/2012), con destinatario identificado. Incluye las simplificadas *cualificadas* que sí identifican al destinatario. |
| **F2** | Factura simplificada o sin identificación del destinatario (art. 6.1.d del RD 1619/2012). |
| **F3** | Factura emitida en sustitución de facturas simplificadas ya facturadas y declaradas. |
Y para rectificativas:
| Clave | Cuándo se usa |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| **R1** | Error fundado en derecho o causas del art. 80 Uno, Dos y Seis LIVA: devoluciones, descuentos posteriores, resolución de operaciones. |
| **R2** | Modificación de la base imponible por concurso de acreedores (art. 80.Tres LIVA). |
| **R3** | Modificación de la base imponible por crédito incobrable (art. 80.Cuatro LIVA). |
| **R4** | El resto: modificaciones fuera del art. 80 sin error fundado en derecho, o error en datos no monetarios. |
| **R5** | Rectificación de una factura simplificada, sea cual sea el motivo. |
### Notas sobre rectificativas [#notas-sobre-rectificativas]
* Las rectificativas llevan **serie específica** y se identifican como rectificación **"S" por sustitución** o **"I" por diferencias**.
* Como **fecha de operación** se indica la de la entrega o prestación original; si una rectificativa corrige varias facturas, la más reciente.
* La devolución de mercancías o envases con ocasión de un suministro posterior al mismo destinatario y tipo no exige rectificativa: se resta del importe de esa operación posterior.
* Identificar las facturas rectificadas es opcional; si se identifican, se informa su número y fecha de expedición.
***
→ [Guía: activar Verifactu y resolver rechazos](/docs/guias/verifactu)
→ [Emisión de facturas](/docs/rtg/pymes/procesos/emision-de-facturas)
→ [Impuestos](/docs/rtg/pymes/configuracion/impuestos)
→ [QR Verifactu en documentos dinámicos](/docs/desarrollo/flex/documentos-dinamicos/qr-verifactu)
# Emitir Factura con Suplidos (/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-con-suplidos)
Las **ventas con gastos suplidos** son aquellas en las que facturas al cliente un importe que no es un ingreso propio de la empresa. Es dinero pagado en nombre del cliente: tasas, registros o servicios de terceros. El importe se traslada al cliente **sin aplicar margen comercial ni impuestos**, ya que la empresa actúa como intermediaria. Para que Dinaup gestione bien este tipo de ventas, configura la categoría y el impuesto correspondientes.
## Registrar una venta con gastos suplidos [#registrar-una-venta-con-gastos-suplidos]
Agrega el gasto suplido como concepto en la factura y selecciona el impuesto `Suplido` y la categoría `Suplido`.
## Gasto suplido en análisis [#gasto-suplido-en-análisis]
El importe del suplido **no se suma a las ventas ni al beneficio**, pero sí aparece en “**Suplidos Ventas**” para dejar constancia de lo que el cliente debe reembolsar.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Emitir Factura Exportación (/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-exportacion)
En Dinaup, las **exportaciones** son operaciones de venta realizadas **a clientes fuera de la Unión Europea**. Estas operaciones están **exentas de IVA**, según el **artículo 21 de la Ley del IVA**, siempre que puedas acreditar que los bienes han salido efectivamente del territorio aduanero de la UE.
## Requisitos [#requisitos]
1. Un **libro registro de facturas** exportaciones: [Libro de Ventas Exportaciones](/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-exportaciones)
2. Un [**impuesto**](/docs/rtg/pymes/configuracion/impuestos) específico.
3. Un **tipo de Venta**: [Tipo de Venta: Exportación](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion)
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Emitir Factura Intracomunitarias (/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-intracomunitarias)
En Dinaup, las **ventas intracomunitarias** son, por defecto, **entregas o servicios realizados a clientes de la UE que están dados de alta en el VIES**.
No deben confundirse con:
* Las [**ventas OSS**](/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-oss), que aunque se hagan a países de la UE, **siguen un régimen distinto** y se declaran aparte.
* Las **ventas a particulares (B2C)** en la UE, cuando el cliente **no tiene NIF-IVA intracomunitario**. En estos casos, la operación se **registra como nacional**, aplicando el **IVA español**.
## Requisitos [#requisitos]
1. Un **Libro registro de facturas** intracomunitarias: [Libro de Ventas Intracomunitarias](/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-intracomunitarias)
2. Un [**Impuesto** ](/docs/rtg/pymes/configuracion/impuestos)específico, recomendado: [Impuesto: VIES](/docs/rtg/pymes/configuracion/impuestos/impuesto-vies)
3. Un **Tipo de Venta**: [Tipo de Venta: Intracomunitaria (VIES)](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-intracomunitaria-vies)
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Emitir Factura Nacional (/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-nacional)
En Dinaup, las **ventas nacionales** son, por defecto, aquellas realizadas a clientes establecidos en España, ya sea a empresas, profesionales o particulares. Estas operaciones **llevan IVA español**, salvo que estén exentas por algún motivo legal.
## Requisitos [#requisitos]
1. Un **libro registro de facturas** Nacionales: [Libro de Ventas Nacionales](/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-nacionales)
2. Un [**impuesto** ](/docs/rtg/pymes/configuracion/impuestos)específico, recomendado.
3. Un **tipo de Venta**: [Tipo de Venta: Nacional](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-nacional)
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Emitir Factura OSS (/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-oss)
De manera predeterminada, **Dinaup no incluye un libro registro específico para operaciones OSS**. Si tu empresa vende a consumidores finales en la UE bajo el régimen de ventanilla única (One Stop Shop), es necesario **crear manualmente la estructura** para registrar correctamente este tipo de ventas.
### **Crear el libro registro OSS** [#crear-el-libro-registro-oss]
Desde la aplicación de Pymes, accede a:\
**Configuración > Ventas / Ingresos > Libros**\
Añade un nuevo libro llamado `OSS` o `Ventas OSS`, que agrupará exclusivamente estas operaciones.
### **Crear un tipo de venta OSS** [#crear-un-tipo-de-venta-oss]
**Configuración > Ventas / Ingresos > Tipos**\
Crea un tipo de venta específico y asígnalo al libro que acabas de crear. Esto permitirá que cada factura OSS se clasifique automáticamente.
### **Crear los impuestos OSS por país** [#crear-los-impuestos-oss-por-país]
Crea un impuesto por cada país de destino, con el porcentaje de IVA correspondiente y aplicando:
Puedes nombrarlos, por ejemplo, `IVA Francia OSS (20%)`, `IVA Alemania OSS (19%)`, etc.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Emitir Factura Simplificada / Ticket (/docs/rtg/pymes/procesos/emision-de-facturas/emitir-factura-simplificada-ticket)
En Dinaup, las **facturas simplificadas** son aquellas operaciones documentadas sin identificar al cliente, normalmente para **ventas al por menor**, **tickets de TPV** o **servicios sin necesidad de facturación nominativa**. Estas operaciones están **sujetas al IVA correspondiente**, igual que una factura completa.
## Requisitos [#requisitos]
1. Un **libro registro de facturas** Simplificadas: [Libro de Ventas Simplificadas / Tickets](/docs/rtg/pymes/libros-registros-de-venta/libro-de-ventas-simplificadas-tickets)
2. Un [**impuesto** ](/docs/rtg/pymes/configuracion/impuestos)específico, recomendado.
3. Un **tipo de Venta**: [Tipo de Venta: Simplificada](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-simplificada)
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Emisión de Facturas (/docs/rtg/pymes/procesos/emision-de-facturas)
En Dinaup, la emisión de facturas se adapta a distintos tipos de operación: nacionales, intracomunitarias, exportaciones, simplificadas, OSS, entre otras. Cada factura se clasifica sola según el [tipo de venta](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos) seleccionado. Así queda asignada a su [Libro registro](/docs/rtg/pymes/libros-registros-de-venta) **correspondiente** y recibe el **tratamiento fiscal adecuado**.
Elige el escenario que se ajusta a tu operación:
# Otros supuestos: España (/docs/rtg/pymes/procesos/emision-de-facturas/otros-supuestos-espana)
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
## Factura normal régimen general [#factura-normal-régimen-general-]
Las facturas ordinarias nacionales usan la clave `F1` e identifican al receptor. El sistema tiene preconfigurado el [Tipo de Venta: Nacional](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-nacional) y aplica el [Impuesto: IVA 21% Régimen general](/docs/rtg/pymes/configuracion/impuestos/impuesto-iva-21-regimen-general) (`IVA`, `S1`, `01`, `Sin Exención`).
```csharp
var invoice = new Invoice("FCO-5", new DateTime(2024, 11, 15), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "PRESTACION SERVICIOS DESARROLLO SOFTWARE",
TaxItems = new List() {
new TaxItem()
{
TaxRate = 4,
TaxBase = 10,
TaxAmount = 0.4m
},
new TaxItem()
{
TaxRate = 21,
TaxBase = 100,
TaxAmount = 21
}
}
};
```
***
## Factura simplificada [#factura-simplificada-]
Las facturas simplificadas usan la clave `F2` y no identifican al receptor. El sistema tiene preconfigurado el [Tipo de Venta: Simplificada](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-simplificada) y aplica el [Impuesto: IVA 21% Régimen general](/docs/rtg/pymes/configuracion/impuestos/impuesto-iva-21-regimen-general) (`IVA`, `S1`, `01`, `Sin Exención`).
```csharp
var invoice = new Invoice("FSO-24", new DateTime(2024, 12, 4), "B72877814")
{
InvoiceType = TipoFactura.F2,
SellerName = "WEFINZ GANDIA SL",
Text = "PRESTACION SERVICIOS DESARROLLO SOFTWARE",
TaxItems = new List() {
new TaxItem()
{
TaxRate = 4,
TaxBase = 10,
TaxAmount = 0.4m
},
new TaxItem()
{
TaxRate = 21,
TaxBase = 100,
TaxAmount = 21
}
}
};
```
***
## Factura recargo de equivalencia [#factura-recargo-de-equivalencia-]
Las facturas con recargo de equivalencia usan la clave `F1` e identifican al receptor. El sistema tiene preconfigurado el [Tipo de Venta: Nacional](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-nacional), aplicando [Impuesto: IVA 21% Régimen general](/docs/rtg/pymes/configuracion/impuestos/impuesto-iva-21-regimen-general) (`IVA`, `S1`, `01`, `Sin Exención`).
Aunque existe la clave de régimen `18: L8A: Recargo de equivalencia...`, no es necesario seleccionarla: Dinaup trata igual la clave `01` y la `18`. En ventas existe un campo llamado `Aplica recargo de equivalencia`, y en función de ese campo Dinaup informa correctamente a la AEAT.
Para activar el recargo de equivalencia en una venta se debe marcar el checkbox `Recargo de equivalencia` en la pestaña de `Parámetros`
Se puede marcar `Vender con recargo de equivalencia`, en la ficha del cliente para que se marque automáticamente en las ventas.
```csharp
var invoice = new Invoice("FCO-6", new DateTime(2024, 10, 14), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "VENTA A COMERCIO MINORISTA",
TaxItems = new List() {
new TaxItem()
{
TaxScheme = ClaveRegimen.RecEquivPeqEmp,
TaxType = CalificacionOperacion.S1,
TaxRate = 21,
TaxBase = 1000,
TaxAmount = 210m,
TaxRateSurcharge = 5.2m, // Tipo recargo equivalencia
TaxAmountSurcharge = 52m // Cuota recargo equivalencia
}
}
};
```
***
## Factura rectificativa [#factura-rectificativa-]
```csharp
// Creamos una instacia de la clase factura para la factura rectificativa
var invoiceRectif = new Invoice("GIT-AB-0076", new DateTime(2024, 12, 10), "B72877814")
{
InvoiceType = TipoFactura.R1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "ABONO ERROR PRECIO FACTURA GIT-EJ-0065",
TaxItems = new List()
{
new TaxItem()
{
TaxRate = 21,
TaxBase = -100,
TaxAmount = -21
}
},
RectificationItems = new List()
{
new RectificationItem()
{
InvoiceID = "GIT-EJ-0076",
InvoiceDate = new DateTime(2024, 12, 4)
}
}
};
```
***
## Factura rectificativa sustitutiva [#factura-rectificativa-sustitutiva-]
```csharp
// Creamos una instacia de la clase factura para la factura rectificativa
var invoiceRectif = new Invoice("GIT-AB-0085", new DateTime(2025, 3, 12), "B72877814")
{
InvoiceType = TipoFactura.R1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "ABONO ERROR PRECIO FACTURA GIT-EJ-00651",
TaxItems = new List()
{
new TaxItem()
{
TaxRate = 21,
TaxBase = 100,
TaxAmount = 21
}
},
RectificationItems = new List()
{
new RectificationItem()
{
InvoiceID = "GIT-EJ-00651",
InvoiceDate = new DateTime(2025, 3, 12)
}
}
};
```
***
## Factura a la Administración con IVA diferido [#factura-a-la-administración-con-iva-diferido-]
Las facturas a Administración Pública con IVA diferido usan la clave `F1`, identifican al receptor y requieren clave de régimen `14`. Se aplica el [Impuesto: IVA para la Administración pública con IVA diferido](/docs/rtg/pymes/configuracion/impuestos/impuesto-iva-para-la-administracion-publica-con-iva-diferido) (`IVA`, `S1`, `14`, `Sin Exención`).
```csharp
var invoice = new Invoice("FCO-7", new DateTime(2024, 10, 10), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "P1203200I",
BuyerName = "AYUNTAMIENTO DE BURRIANA",
Text = "CONSTRUCCION NUEVAS OFICINAS",
OperationDate = new DateTime(2024, 12, 10), // Fecha operación obligatoria
TaxItems = new List() {
new TaxItem()
{
TaxScheme = ClaveRegimen.ObraPteDevengoAdmonPublica,
TaxType = CalificacionOperacion.S1,
TaxRate = 21,
TaxBase = 1000,
TaxAmount = 210m,
}
}
};
```
***
## Factura operación No Sujeta artículo 7, 14, otros [#factura-operación-no-sujeta-artículo-7-14-otros-]
Se aplican los **impuestos correspondientes** (`Otro`, `N1`, `01`, `Sin Exención`)
```csharp
// Creamos una instacia de la clase factura
var invoice = new Invoice("FCO-8", new DateTime(2024, 10, 14), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "123456789",
BuyerName = "CLIENTE EXTRANJERO SERVICIOS INFORMATICOS",
BuyerIDType = IDType.PASAPORTE,
BuyerCountryID = "US",
Text = "SERVICIOS INFORMATICOS",
TaxItems = new List() {
new TaxItem()
{
Tax = Impuesto.OTROS,
TaxType = CalificacionOperacion.N1,
TaxBase = 1000,
}
}
};
```
***
## Factura operación No Sujeta por Reglas de localización [#factura-operación-no-sujeta-por-reglas-de-localización-]
Las facturas no sujetas por reglas de localización usan la clave `F1` con calificación `N2`. El sistema tiene preconfigurado el [Tipo de Venta: Exportación](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion) y se aplica el [Impuesto: No Sujeto por reglas de Localización](/docs/rtg/pymes/configuracion/impuestos/impuesto-no-sujeto-por-reglas-de-localizacion) (`Otro`, `N2`).
```csharp
// Creamos una instacia de la clase factura
var invoice = new Invoice("FEO-1", new DateTime(2024, 10, 14), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "123456789",
BuyerName = "CLIENTE EXTRANJERO SERVICIOS INFORMATICOS",
BuyerIDType = IDType.PASAPORTE,
BuyerCountryID = "US",
Text = "CLIENTE EXTRANJERO SERVICIOS INFORMATICOS",
TaxItems = new List() {
new TaxItem()
{
Tax = Impuesto.OTROS,
TaxType = CalificacionOperacion.N2,
TaxBase = 1000,
}
}
};
```
***
## Factura con Suplidos [#factura-con-suplidos-]
***
## Factura exenta articulo 20 LIVA (Exenciones en operaciones interiores) [#factura-exenta-articulo-20-liva-exenciones-en-operaciones-interiores-]
Las facturas exentas por el artículo 20 de la LIVA (operaciones interiores exentas) usan la clave `F1` con causa de exención `E1`.
```csharp
var invoice = new Invoice("FCO-9", new DateTime(2024, 12, 11), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "C# PROGRAMMING COURSE",
TaxItems = new List() {
new TaxItem()
{
TaxException = CausaExencion.E1,
TaxBase = 200,
}
}
};
```
***
## Factura exenta articulo 25 LIVA (Entrega intracomunitaria) [#factura-exenta-articulo-25-liva-entrega-intracomunitaria-]
[Impuesto: VIES](/docs/rtg/pymes/configuracion/impuestos/impuesto-vies)
```csharp
var invoice = new Invoice("FIO-2", new DateTime(2025, 2, 7), "B12959755")
{
InvoiceType = TipoFactura.F1,
SellerName = "IRENE SOLUTIONS SL",
BuyerID = "IE3668997OH",
BuyerName = "GOOGLE CLOUD EMEA LIMITED",
BuyerCountryID = "IE",
BuyerIDType = IDType.NIF_IVA,
Text = "ENTREGA INTRACOMUNITARIA: COMPONENTES HARDWARE",
TaxItems = new List() {
new TaxItem()
{
TaxException = CausaExencion.E5,
TaxBase = 200,
}
}
};
```
***
## Factura a cliente con VAT number de la UE [#factura-a-cliente-con-vat-number-de-la-ue-]
```csharp
// Creamos una instacia de la clase factura
var invoice = new Invoice("FCO-10", new DateTime(2025, 1, 9), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "IE3668997OH",
BuyerName = "GOOGLE CLOUD EMEA LIMITED",
BuyerIDType = IDType.NIF_IVA,
BuyerCountryID = "IE",
Text = "SERVICIOS INFORMATICOS",
TaxItems = new List() {
new TaxItem()
{
TaxRate = 21,
TaxBase = 100,
TaxAmount = 21
}
}
};
```
***
## Factura a cliente con pasaporte como identificador [#factura-a-cliente-con-pasaporte-como-identificador-]
```csharp
var invoice = new Invoice("FCO-11", new DateTime(2025, 1, 9), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "P4366918",
BuyerName = "ESTIVE SOTANO MENGANO",
BuyerIDType = IDType.PASAPORTE,
BuyerCountryID = "US",
Text = "SERVICIOS INFORMATICOS",
TaxItems = new List() {
new TaxItem()
{
TaxRate = 21,
TaxBase = 100,
TaxAmount = 21
}
}
};
```
***
## Factura IGIC Canarias [#factura-igic-canarias-]
**Impuesto IGIC**
```csharp
var invoice = new Invoice("FCO-12", new DateTime(2024, 12, 4), "B72877814")
{
InvoiceType = TipoFactura.F1,
SellerName = "WEFINZ GANDIA SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "PRESTACION SERVICIOS DESARROLLO SOFTWARE",
TaxItems = new List() {
new TaxItem()
{
TaxScheme = ClaveRegimen.RegimenGeneral,
Tax = Impuesto.IGIC,
TaxRate = 7,
TaxBase = 100,
TaxAmount = 7
}
}
};
```
***
## Factura REBU (Régimen especial de los bienes usados, objetos de arte, antigüedades y objetos de colección) [#factura-rebu-régimen-especial-de-los-bienes-usados-objetos-de-arte-antigüedades-y-objetos-de-colección-]
[Impuesto: REBU (Régimen especial de los bienes usados...)](/docs/rtg/pymes/configuracion/impuestos/impuesto-rebu-regimen-especial-de-los-bienes-usados...)
```csharp
var invoice = new Invoice("GIT-EJ-00809", new DateTime(2025, 2, 27), "B12959755")
{
InvoiceType = TipoFactura.F1,
SellerName = "IRENE SOLUTIONS SL",
BuyerID = "B44531218",
BuyerName = "WEFINZ SOLUTIONS SL",
Text = "VENTA SMARTPHONE REACONDICIONADO",
TaxItems = new List() {
new TaxItem()
{
TaxScheme = ClaveRegimen.Rebu,
TaxBase = 1000m,
}
}
};
```
# Empieza a gestionar pedidos (/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos/guia-inicio-pedidos)
La sección **Pedidos** centraliza las solicitudes de productos o servicios de tus clientes (online, internos o externos) antes de convertirlas en [ventas](/docs/rtg/pymes/facturacion/ventas).
### Revisa estados de Pedidos [#revisa-estados-de-pedidos]
En **`TPV > Configuración > Pedidos`** encontrarás la pestaña `Estados`. Agrega los estados en los que pueden encontrarse los pedidos según tu negocio.
**Ejemplo de configuración de estado:**
**Ejemplo sencillo:** crear 3 estados.
1. **Abierto**
1. `Texto Principal`: Abierto
2. `Estado`: Pendiente
3. `Estilo`: 15
2. **Facturado**
1. `Texto Principal`: Facturado
2. `Estado`: Tramitado
3. `Estilo`: 14
3. **Cancelado**
1. `Texto Principal`: Cancelado
2. `Estado`: Cancelado
3. `Estilo`: 20
### Configura un estado como Predeterminado [#configura-un-estado-como-predeterminado]
Navega hacia `Pymes > Configuración > Empresas Administradas` y en el Listado pulsa en el nombre de tu empresa.
En la pestaña de `Pedidos` puedes configurar el `Estado inicial de pedidos` para que se rellene solo.
### Pulsa sobre Agregar Pedidos [#pulsa-sobre-agregar-pedidos]
### Convertir en venta o cancelar [#convertir-en-venta-o-cancelar]
#### Cancelar [#cancelar]
Cambia el estado del pedido a `Cancelado`.
#### Convertir en venta [#convertir-en-venta]
1. Para convertirlo en Venta, abre el pedido y pulsa sobre Flujo
2. Se abre la ventana de [**Flujo de Pedidos**](/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos). Pulsa el botón `+ Agregar venta`: se abre una vista previa de la venta. Pulsa `Aceptar`.
# Gestión de Pedidos (/docs/rtg/pymes/inventario-y-precios/gestion-de-pedidos)
La sección **Pedidos** centraliza todas las solicitudes de productos o servicios realizadas por tus clientes, ya sea desde canales online, internos o externos. Es la forma en la que tu empresa recibe y organiza las intenciones de compra antes de convertirlas en [ventas](/docs/rtg/pymes/facturacion/ventas).
# Impuesto: Exportación (Canarias, Ceuta y Melilla) (/docs/rtg/pymes/configuracion/impuestos/impuesto-exportacion-canarias-ceuta-y-melilla)
| Campo | Val |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo` |
| **Clave de régimen** | `02: Exportación.` |
| **Causa (Sujeción)** | `E2: Exenta por el artículo 21 de la Ley de IVA` |
| **Valor %** | `0` |
| **Recargo de Equivalencia %** | `0` |
| **Limitar a tipo de Venta 1** | [Tipo de Venta: Exportación (Canarias, Ceuta y Melilla)](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion-canarias-ceuta-y-melilla) |
# Impuesto: Exportación (/docs/rtg/pymes/configuracion/impuestos/impuesto-exportacion)
| Campo | Val |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo` |
| **Clave de régimen** | `02: Exportación.` |
| **Causa (Sujeción)** | `E2: Exenta por el artículo 21 de la Ley de IVA` |
| **Valor %** | `0` |
| **Recargo de Equivalencia %** | `0` |
| **Limitar a tipo de Venta 1** | [Tipo de Venta: Exportación](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion) |
# Impuesto: IVA 21% Régimen general (/docs/rtg/pymes/configuracion/impuestos/impuesto-iva-21-regimen-general)
Este impuesto corresponde al **IVA General del 21%**, aplicable en la mayoría de operaciones sujetas y no exentas dentro del territorio nacional.
| Campo | Val |
| ------------------------------ | -------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo` |
| **Clave de régimen** | `01: Operación de régimen general` |
| **Causa (Sujeción)** | `Sin Exención` |
| **Valor %** | `21` |
| **Recargo de Equivalencia %** | `5,2` |
En Dinaup no hace falta seleccionar expresamente la clave de régimen `18 (L8A)`. El sistema considera idénticas las claves `01` y `18`, de modo que basta con marcar el campo **«Aplica recargo de equivalencia»** al introducir la factura. A partir de ese dato, la propia factura decide si debe incluir el recargo.
Cuando dicha factura se exporta a **Verifactu**, Dinaup incorpora la información fiscal correspondiente (con o sin recargo) y la envía con el formato que exige la AEAT, sin pasos adicionales por tu parte.
**Limitar a tipo de Venta**\
En la mayoría de casos, se puede limitar este impuesto a Facturas simplificadas y Nacionales. De este modo no aparecerá el impuesto en otros tipos de venta.
# Impuesto: IVA para la Administración pública con IVA diferido (/docs/rtg/pymes/configuracion/impuestos/impuesto-iva-para-la-administracion-publica-con-iva-diferido)
| Campo | Val |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo` |
| **Clave de régimen** | `14: L8A: Factura con IVA pendiente de devengo en certificaciones de obra a Administraciones Públicas. L8B: Factura con IGIC pendiente de devengo` |
| **Causa (Sujeción)** | `Sin Exención` |
| **Valor %** | `21` |
| **Recargo de Equivalencia %** | `0` |
# Impuesto: No Sujeto por reglas de Localización (/docs/rtg/pymes/configuracion/impuestos/impuesto-no-sujeto-por-reglas-de-localizacion)
| Campo | Val |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `N2: Operación No Sujeta por Reglas de localización.` |
| **Clave de régimen** | `01: Operación de régimen general.` |
| **Causa (Sujeción)** | `Sin Exención` |
| **Valor %** | `0` |
| **Recargo de Equivalencia %** | `0` |
| **Limitar a tipo de Venta 1** | [Tipo de Venta: Exportación](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion) |
# Impuesto: OSS (/docs/rtg/pymes/configuracion/impuestos/impuesto-oss)
Impuesto de otro país de la Unión Europea con el IVA del país de destino, bajo el régimen OSS (One Stop Shop).
| Campo | Val |
| ------------------------------ | ----------------------------------------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo.` |
| **Clave de régimen** | `17: L8A: OSS e IOSS IVA. L8B: Régimen especial de comerciante minorista.` |
| **Causa (Sujeción)** | `Sin Exención` |
| **Valor %** | `20` |
| **Recargo de Equivalencia %** | `0` |
| **País** | `Francia` |
| **Limitar a tipo de Venta 1** | [Tipo de Venta: OSS](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-oss) |
# Impuesto: REBU (Régimen especial de los bienes usados...) (/docs/rtg/pymes/configuracion/impuestos/impuesto-rebu-regimen-especial-de-los-bienes-usados...)
| Campo | Val |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| Tipo | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo.` |
| **Clave de régimen** | `03: Operaciones a las que se aplique el régimen especial de bienes usados, objetos de arte, antigüedades y objetos de colección.` |
| **Causa (Sujeción)** | `Sin Exención` |
| **Valor %** | `0` |
| **Recargo de Equivalencia %** | `0` |
| **Limitar a tipo de Venta 1** | [Tipo de Venta: REB](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-reb) |
# Impuesto: VIES (/docs/rtg/pymes/configuracion/impuestos/impuesto-vies)
Configuración del impuesto al 0% para **ventas intracomunitarias** a empresas con número de IVA válido en VIES.
| Campo | Val |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tipo** | `IVA` |
| **Clasificación de operación** | `S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo` |
| **Clave de régimen** | `01: Operación de régimen general` |
| **Causa (Sujeción)** | `E5: Exenta por artículo 25` |
| **Valor %** | `0` |
| **Recargo de Equivalencia %** | `0` |
| **Limitar a tipo de Venta 1** | [Tipo de Venta: Intracomunitaria (VIES)](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-intracomunitaria-vies) |
# Impuestos (/docs/rtg/pymes/configuracion/impuestos)
### Campos del impuesto [#campos-del-impuesto]
Es el nombre que se mostrará en la factura (por ejemplo, "IVA", "IGIC", "IPSI"...).
El porcentaje del impuesto. En casos exentos o no sujetos, este valor está al 0%.
Porcentaje de recargo de equivalencia para este tipo impositivo. El recargo se activa en las facturas con la casilla `Activar recargo de equivalencia`.
Para Verifactu. Clasifica el impuesto según su naturaleza:
* IVA
* IPSI
* IGIC
* Otros
Para Verifactu. Motivo legal por el que se aplica, no aplica o está exento. Ejemplos:
* E1: Exenta por el artículo 20 de la Ley de IVA
* E2: Exenta por el artículo 21 de la Ley de IVA
* E3: Exenta por artículo 22
* E4: Exenta por artículo 24
* E5: Exenta por artículo 25
* E6: Otros
Para Verifactu.
* 01: Operación de régimen general.
* 02: Exportación.
* 03: Operaciones a las que se aplique el régimen especial de bienes usados, objetos de arte, antigüedades y objetos de colección.
* 04: Régimen especial del oro de inversión.
* 05: Régimen especial de las agencias de viajes.
* 06: Régimen especial grupo de entidades en IVA/IGIC (Nivel Avanzado).
* 07: Régimen especial del criterio de caja.
* 08: L8A: Operaciones sujetas al IPSI / IGIC. L8B: Operaciones sujetas al IPSI / IVA.
* 09: Facturación de servicios de agencias de viaje como mediadoras en nombre y por cuenta ajena.
* 10: Cobros por cuenta de terceros de honorarios profesionales o derechos derivados.
* 11: Operaciones de arrendamiento de local de negocio.
* 14: L8A: Factura con IVA pendiente de devengo en certificaciones de obra a Administraciones Públicas. L8B: Factura con IGIC pendiente de devengo.
* 15: L8A: Factura con IVA pendiente de devengo en operaciones de tracto sucesivo. L8B: Factura con IGIC pendiente de devengo.
* 17: L8A: OSS e IOSS IVA. L8B: Régimen especial de comerciante minorista.
* 18: L8A: Recargo de equivalencia. L8B: Régimen especial del pequeño empresario o profesional.
* 19: L8A: Operaciones de actividades incluidas en el Régimen Especial de Agricultura, Ganadería y Pesca (REAGYP). L8B: Operaciones interiores exentas por aplicación artículo 25 Ley 19/1994.
* 20: Régimen simplificado sólo para IVA.
Para Verifactu.
* S1: Operación Sujeta y No exenta - Sin inversión del sujeto pasivo.
* S2: Operación Sujeta y No exenta - Con Inversión del sujeto pasivo.
* N1: Operación No Sujeta artículo 7, 14, otros.
* N2: Operación No Sujeta por Reglas de localización.
Puedes asociar subcuentas para la contabilidad automática ( [Contabilidad Automática](/docs/rtg/pymes/procesos/contabilidad-automatica) ).
Determina el país del impuesto. Las ventanas de generación de Presupuestos, Ventas, Pedidos... lo tienen en cuenta al seleccionar los impuestos.
Cuatro campos te permiten restringir la aplicación de un impuesto a determinados [Tipos de Ventas e Ingresos](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos).
En ocasiones el filtro por país no basta. Por ejemplo, el impuesto [Impuesto: VIES](/docs/rtg/pymes/configuracion/impuestos/impuesto-vies) se aplica en varios estados, por lo que resulta especialmente útil filtrarlo por tipo de venta [Tipo de Venta: Intracomunitaria (VIES)](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-intracomunitaria-vies).
De igual modo, si trabajas con el impuesto [Impuesto: REBU (Régimen especial de los bienes usados...)](/docs/rtg/pymes/configuracion/impuestos/impuesto-rebu-regimen-especial-de-los-bienes-usados...) , puedes asignarlo únicamente al tipo de venta [Tipo de Venta: REB](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-reb).
***
## Ejemplos [#ejemplos]
IVA general del 21% con recargo de equivalencia, para la mayoría de operaciones nacionales.
Régimen especial de bienes usados, objetos de arte, antigüedades y colección.
Ventas intracomunitarias al 0% a empresas con VAT validado en VIES.
Envíos a Canarias, Ceuta y Melilla, exentos por el artículo 21 de la Ley del IVA.
Ventas a clientes fuera de la UE, exentas por el artículo 21 de la Ley del IVA.
Operaciones no sujetas al IVA por reglas de localización.
# Tipos de Ventas e Ingresos (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos)
Un **Tipo de Venta** define cómo debe comportarse una factura dentro del sistema. Sirve para adaptar la lógica de facturación según el contexto:
* Factura simplificada
* Venta online
* Operaciones intracomunitarias
* Régimen OSS\
...y cualquier otra necesidad específica.
## Tipos de ventas Pymes y TPV [#tipos-de-ventas-pymes-y-tpv]
Puedes usar los tipos de venta en la aplicación de [TPV](/docs/rtg/tpv) y en [Pymes](/docs/rtg/pymes). En la ficha del **tipo de venta** hay una casilla `Disponible en TPV`.
### Pymes [#pymes]
En Pymes aparecen todos los tipos de venta, ya que esta aplicación está pensada para usuarios avanzados.
### TPV [#tpv]
En `TPV` únicamente aparecen los marcados como `Disponible en TPV`, ya que está pensado para ventas sencillas (generalmente facturas simplificadas en puntos de venta: supermercados, hostelería...).
## Campos [#campos]
Cada Tipo de Venta permite ajustar múltiples opciones para adaptarse a cada situación:
Limita el valor total permitido en la venta (por ejemplo, para cumplir con el tope legal de las facturas simplificadas).
Si el movimiento no es una venta (una subvención, una devolución de impuestos), marca esta opción para que el sistema lo trate como un ingreso contable sin factura asociada.
Determina si este tipo de venta está disponible en la generación automática de asientos contables.
Puedes forzar un impuesto específico que sobrescribe el configurado en productos.
> Ejemplo: aunque los productos estén al 21% de IVA, puedes definir un tipo de venta intracomunitario con un impuesto del 0% si el cliente está dado de alta en el VIES.
Aplica una retención automática a las ventas de este tipo (por ejemplo, IRPF en servicios profesionales).
Clasifica las ventas bajo una categoría específica, que sustituye a la definida en los productos o servicios.
Determina si la factura se confecciona con o sin impuestos incluidos.
Permite configurar si el cliente debe rellenarse o no.
Permite configurar si los datos fiscales del cliente deben rellenarse o no.
Determina si el cliente debe estar dado de alta o no en AEAT.\
Puedes elegir entre:
* **Sin restricción**
* **Debe estar dado de alta en AEAT**
* **No debe estar en AEAT**
Determina si el cliente debe estar dado de alta o no en VIES.\
Opciones disponibles:
* **Sin restricción**
* **Debe estar dado de alta en VIES**
* **No debe estar en VIES**
Puedes definir una **lista de países** usando el formato **ISO 3166-1 alfa-2** (códigos de dos letras), separados por comas.
**Ejemplo 1: Países incluidos**
* **Política de países:** Incluir
* **Lista:**
```
ES,FR,IT
```
→ Solo España, Francia e Italia quedan permitidos.
***
**Ejemplo 2: Países excluidos**
* **Política de países:** Excluir
* **Lista:**
```
ES,FR,IT
```
→ Bloquea España, Francia e Italia; el resto de países quedan permitidos.
***
**Ejemplo 3: Provincias incluidas**
* **Política de países:** Incluir
* **Lista:**
```
ES[Ceuta],ES[Melilla]
```
→ Solo Ceuta y Melilla quedan permitidas.
***
**Ejemplo 4: Provincias excluidas**
* **Política de países:** Incluir
* **Lista:**
```
ES,ES[!Ceuta],ES[!Melilla],ES[!Canarias]
```
→ Toda España queda permitida salvo Ceuta, Melilla y Canarias.
Define cómo debe interpretarse la **lista de países permitidos**.\
Opciones disponibles:
* **Incluir**: solo se permite la venta a los países (o provincias) indicados.
* **Excluir**: se permite la venta a todos los destinos **excepto** los indicados.
Así controlas en qué territorios aplica el tipo de venta, combinando la lista ISO con provincias (`ES[Ceuta]`, `FR[Martinique]`, etc.).
Determina si este tipo de ventas aparece en envíos pendientes (Picking o Sendcloud, Genei...)\
Para determinados usos, puede requerir integraciones y/o personalizaciones.
El sistema no permite seleccionar dirección de envío, lo que además simplifica la interfaz.
Activa esta opción si quieres **impedir que se añadan conceptos de texto libre** a la venta.\
De este modo, el sistema **obliga a seleccionar elementos estructurados**, como productos, recursos o servicios previamente definidos.
> Útil para evitar errores, asegurar trazabilidad o controlar el uso de tarifas preconfiguradas.
Impide que se añadan productos a la venta. Útil si el tipo de venta solo debe usar recursos u otros elementos.
Bloquea la posibilidad de añadir recursos a la venta. Solo se pueden usar productos o conceptos válidos según el tipo de venta.
Determina si este tipo de ventas aparece en el área de clientes. Para determinados usos, puede requerir integraciones y/o personalizaciones.
Permite definir si este tipo de venta **puede ser utilizado desde la aplicación de TPV**.\
Cuando está activado, aparece como opción en el terminal de punto de venta, pensado para ventas rápidas y simplificadas (como hostelería, retail o mostrador).
> Si no se marca, este tipo de venta solo está disponible en la aplicación de PYMES o en otras integraciones del sistema.
Indica si este tipo de venta está **activo y disponible para ser utilizado en el sistema**.\
Si no está marcado como disponible, no puede seleccionarse ni desde TPV, ni desde PYMES, ni desde ninguna otra parte de la plataforma.
> Útil para desactivar un tipo de venta sin tener que eliminarlo.
Permite **asociar este tipo de venta a un libro registro concreto**.
Permite indicar si este tipo de venta **funciona en modo táctil**, pensado para pantallas sin teclado ni ratón (hostelería, kioscos, etc.).
Activa esta opción si el tipo de venta representa **una factura ya emitida externamente**, desde otro programa o sistema de facturación. En ese caso, el sistema no genera numeración, entre otras funcionalidades. Ejemplo: `Facturas Stripe`
## Sugerencias inteligentes [#sugerencias-inteligentes]
Dinaup analiza el nombre de cada tipo de venta y, si encuentra términos como “OSS”, “Ingresos” o “Exportación”, ofrece sugerencias adaptadas al contexto.
#### Palabras clave y sus sugerencias [#palabras-clave-y-sus-sugerencias]
| Palabra clave | Contexto |
| -------------------------- | --------------------------------------------------------------- |
| **Simplificada** | Facturas simplificadas / tickets |
| **Nacional** | Ventas dentro de España |
| **Ceuta/Melilla/Canarias** | Ventas a territorios donde no se aplica el IVA. |
| **OSS** | Ventas a través del One-Stop-Shop (UE) |
| **Exportaciones** | Ventas fuera de la UE |
| **VIES** | Operaciones entre países UE registradas en VIES. |
| **Ingresos** | Entradas sin factura (subvenciones, devoluciones de impuestos…) |
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: Exportación (Canarias, Ceuta y Melilla) (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion-canarias-ceuta-y-melilla)
Usa este tipo para operaciones desde la península a Canarias, Ceuta y Melilla, territorios donde no se aplica el IVA peninsular.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: Exportación (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-exportacion)
Usa este tipo para operaciones con clientes en países terceros: ventas fuera de la Unión Europea a las que no se aplica el IVA español.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: Intracomunitaria (VIES) (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-intracomunitaria-vies)
Tipo de venta para operaciones intracomunitarias a empresas o profesionales con NIF-VAT europeo válido: clientes de la UE (excepto España) dados de alta en el sistema VIES.
### Campos recomendados [#campos-recomendados]
| Parámetro | Valor sugerido | Notas |
| ---------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Nombre** | `VIES` | |
| **Países permitidos** | `AT, BE, BG, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IE, IT, LV, LT, LU, MT, NL, PL, PT, RO, SK, SI, SE` | Francia, Alemania, Italia, etc. Excepto España, que sería [Tipo de Venta: Nacional](/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-nacional). |
| **Política de países** | `Incluir` | |
| **Validar NIFs VIES** | `Sí` | Solo admite VAT-UE válido |
| **Impuesto** | [Impuesto: VIES](/docs/rtg/pymes/configuracion/impuestos/impuesto-vies) | |
| **Libro** | `Intracomunitarias` | Agrupa las operaciones VIES |
| **Notas a Incluir** | “*`Reverse charge. VAT to be accounted for by the recipient under Article 196 of the EU VAT Directive`*” | |
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: Nacional (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-nacional)
Tipo de venta para cualquier operación a clientes dentro de España peninsular o Baleares, tanto empresas como particulares. Es el tipo más común para ventas nacionales.
### Campos recomendados [#campos-recomendados]
| Parámetro | Valor sugerido | Notas |
| ---------------------- | ------------------------------------------ | ------------------------------------------------------------------------- |
| **Nombre** | `Nacional` | |
| **Países permitidos** | `ES,ES[!Ceuta],ES[!Melilla],ES[!Canarias]` | Aplicable a todo el territorio español excepto Canarias, Ceuta y Melilla. |
| **Política de países** | `Incluir` | |
| **Libro** | `Nacionales` | |
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: OSS (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-oss)
Pensado para ventas a consumidores finales en la UE bajo el régimen de ventanilla única (OSS). Permite gestionar IVA extranjero para ventas online o servicios digitales.
### General [#general]
* Nombre: `OSS`
* Descripción: `Venta a consumidor final UE bajo régimen OSS`
* Nota a Incluir: `Factura emitida bajo el régimen especial de ventanilla única (OSS). El IVA aplicado corresponde al país de consumo.`
### Países permitidos [#países-permitidos]
* Lista de Países: Incluye solo los países de la Unión Europea, excluyendo España (ES).
```
AT, BE, BG, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IE, IT, LV, LT, LU, MT, NL, PL, PT, RO, SK, SI, SE
```
* Política: `Incluir`
### Validaciones de NIF [#validaciones-de-nif]
Para minimizar errores, se recomienda aplicar la siguiente configuración:
* Permisión NIF en AEAT: `No`.
* Permisión NIF en VIES: `No`.
Dinaup valida el NIF del cliente para determinar si se debe aplicar esta configuración. Esto asegura que el sistema lo interprete como una venta a consumidor final y no como una operación intracomunitaria o nacional.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: REB (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-reb)
Tipo específico para ventas de bienes usados, antigüedades o arte bajo el régimen especial. No desglosa IVA en la factura, solo aplica a margen de beneficio.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: Simplificada (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-simplificada)
Tipo orientado a ventas de mostrador o tickets, donde no se recogen datos del cliente. Para operaciones rápidas, anónimas y de bajo importe.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*
# Tipo de Venta: TPV Hostelería (/docs/rtg/pymes/facturacion/ventas/tipos-de-ventas-e-ingresos/tipo-de-venta-tpv-hosteleria)
Tipo de venta pensado para operaciones rápidas en bares, cafeterías o restaurantes. Similar a simplificada, pero permite gestionar tickets, mesas, cuentas y otras funciones específicas de hostelería.
***
*⚠️ Esta información tiene carácter orientativo. Te recomendamos consultar con tu asesor fiscal antes de aplicarla a tu caso concreto.*