Ir al contenido principal

V3 - DASHBOARDS 🚧⚠️👷🏻‍♀️

Actualizado hace más de una semana

Introducción

En este documento encontrarás la recopilación de todos los dashboards disponibles en Golfmanager, organizados y explicados con detalle para facilitar su consulta y uso.


Dashboard de Reservas - ID 700.

Introducción

El Dashboard de Reservas es una herramienta interactiva diseñada para analizar en tiempo real la evolución de las reservas. Permite a los usuarios visualizar tendencias, comparar periodos, prever futuras reservas y conocer los clientes más activos, así como otros indicadores relevantes del negocio.

Indicadores de rendimiento

Total de Reservas vs Periodo Anterior

Muestra:

  • Total de reservas del periodo actual.

  • Total de reservas del periodo anterior.

  • Variación porcentual de reservas con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • booking.

  • bookingResource: recursos reservables.

  • bookingResourceType: tipo del recurso.

Tiene en cuenta lo siguiente:

  • Solo incluye reservas que no cruzan varios días.

  • Excluye reservas que se hagan por días completos.

  • Incluye solo reservas con estados activos o válidos.

  • Asegura que las reservas no estén expiradas.

Previsión

Muestra

  • Valor estimado de reservas. Predice el número de reservas del año actual combinando datos reales y del año pasado:

    • Meses pasados: se usa el número real de reservas de este año.

    • Mes actual:

      • Hasta hoy: datos reales.

      • Desde mañana: datos del mismo mes del año pasado.

    • Meses futuros: se usa directamente el número de reservas del año pasado como predicción.

  • Comparativa de reservas con periodo anterior.

  • Variación porcentual de reservas con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas

  • booking.

  • bookingResource: recursos reservables.

  • bookingResourceType: tipo del recurso.

Tiene en cuenta lo siguiente:

  • Solo considera reservas dentro de dos rangos de fechas

  • Filtra para incluir solo reservas válidas, no canceladas ni cruzadas, que no estén expiradas.

Tablas Resumen

Top clientes

Muestra:

Tabla con los clientes con mayor número de reservas ordenada de mayor a menor.

  • Saber cuántos clientes únicos hicieron reservas dentro de un rango de fechas.

  • Lista esos clientes con el número total de reservas que hicieron, ordenados por los que más reservaron.

Tablas consultadas:

  • booking.

  • bookingResource: recursos reservables.

  • bookingResourceType: tipo del recurso.

  • customer.

Tiene en cuanta lo siguiente

  • Filtra solo las reservas válidas en el rango de fechas indicado.

  • Excluye reservas canceladas, cruzadas o expiradas.

  • Si se aplica un filtro por tipo de recurso, también lo limita por esos tipos.

Canal de Reserva (Online / Offline)

Muestra:

Distribución de reservas según canal Online u Offline, con cambio porcentual respecto al periodo anterior.

  • Crea una columna llamada Canal que indica si la reserva fue Online u Offline.

  • Columna con el % de Offline y Online.

  • Cuenta cuántas reservas hay en cada grupo.

Tablas consultadas:

  • booking.

  • bookingResource: recursos reservables.

  • bookingResourceType: tipo del recurso.

Tiene en cuenta lo siguientes:

  • Solo incluye reservas en el rango de fechas.

  • Excluye reservas caducadas, cruzadas, por días completos o con estado inválido.

  • Asegura que solo entren reservas activas (por ejemplo: confirmadas, pendientes, etc.).


Etiquetas

Muestra:

  • Cuántas reservas se hicieron para cada “etiqueta de cliente” (customerTag) asociada a un tipo de reserva, dentro de un rango de fechas. Es útil, por ejemplo, para ver cuántas reservas se hicieron por tipo de socio: “Socio”, “Visitante”, “Invitado”, etc.

Tablas consultadas:

  • customerTag.

  • bookingType.

  • booking.

  • bookingResource.

  • bookingResourceType.

Tiene en cuenta lo siguiente:

  • Une las reservas (booking) con:

    • Las etiquetas de cliente (customerTag)

    • La relación entre tipo de reserva y etiqueta (bookingTypeToCustomerTag)

    • El recurso reservado (bookingResource)

    • El tipo de recurso (bookingResourceType)

  • Limita a reservas dentro del rango de fechas.

  • Excluye reservas cruzadas, por días completos, caducadas o con estado inválido.

  • Solo incluye reservas activas y válidas.

  • Agrupa los resultados por etiqueta de cliente.

  • Solo muestra etiquetas con al menos una reserva.

  • Ordena de mayor a menor cantidad de reservas.​

Agencias

Muestra:

  • Muestra un ranking de agencias que más reservas han hecho en un rango de fechas determinado.

Tablas consultadas:

  • booking.

  • bookingResource.

  • bookingResourceType.

  • customer.

Tiene en cuenta lo siguiente:

  • Fechas: Filtra las reservas entre el periodo seleccionado.

  • No cruzadas.

  • Activas (no expiradas).

  • Clientes válidos: que no estén eliminados y sean agencias.

  • Reservas no por días completos.

  • Reservas válidas con estado 1, 2 o 3.

Reservas por Mes (Gráfico de Barras)

Muestra:

  • Genera una comparativa mensual entre las reservas del año pasado y el año actual, y también calcula una proyección (forecast) para el resto del año.

Tablas consultadas:

  • booking.

  • bookingResource.

  • bookingResourceType.

Tiene en cuenta lo siguiente:

  • Reservas no cruzadas.

  • Reservas no por días completos.

  • Reservas activas (status 1, 2 o 3).

  • Reservas no expiradas.

Reservas por Nacionalidad (Mapa Mundial Interactivo)

Muestra:

Muestra el top 10 de nacionalidades (países) de los clientes que han hecho reservas durante un rango de fechas específico, incluyendo el código de país, nombre del país, y cantidad de reservas.

  • Mapa con países destacados

  • Lista top 10 nacionalidades

  • Indicadores de cambio por país

Para que se muestren las banderas y se pinten en el mapa hay que tener en cuenta lo siguiente

  • Configuración > Países > Crear el país

    • Nombre: España

      • España es para que se pinte en el mapa.

    • Código ISO: ES

      • ES es para que salga la bandera.

Tablas consultadas:

  • booking.

  • country.

  • bookingResource.

  • bookingResourceType.

Tiene en cuenta lo siguiente:

  • Estén dentro del rango de fechas.

  • No sean cruzadas.

  • No sean por días enteros.

  • Tengan estado válido.

  • No hayan expirado.

Dashboard de Tienda - ID 701.

Introducción

Se ha incorporado un nuevo dashboard operativo llamado Tienda, diseñado para ofrecer una visión global del rendimiento de la tienda en un año determinado. Este informe permite analizar las ventas, márgenes, inventario y movimientos de stock, con comparativas entre periodos. Su objetivo es facilitar decisiones estratégicas y operativas basadas en datos.

Indicadores de rendimiento


Ventas, Coste y Margen

Este widget muestra un resumen de ventas totales por producto. Utiliza los parámetros recibidos para aplicar filtros por fechas, subfamilias, almacenes y paginación.

Muestra

  • Total vendido, coste total y margen total del periodo actual.

  • Total vendido, coste total y margen total del periodo anterior.

  • Variación porcentual del total vendido, coste total y margen total con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • sale: Para obtener las ventas realizadas.

  • product: Para relacionar la venta con el producto.

  • subfamily: Para agrupar los productos por subfamilia.

  • warehouse: Para filtrar por almacenes (si se implementa en la función interna).

Tiene en cuenta lo siguiente:

  • Fechas:

    • startDate y endDate (si no se especifican, usa el día actual).

    • Esto limita las ventas incluidas al período solicitado.

  • Paginación:

    • page y pageSize determinan qué parte del resultado se devuelve.

  • Filtros adicionales (opcional):

    • Aunque el objeto filter incluye resourceType, este no se define ni se extrae correctamente en el web.parseValues, por lo que probablemente no funcione como está.

  • Subfamilias (subfamilyId) y almacenes (warehouseId):

    • Se declaran en la interfaz Filter, lo que indica que podrían usarse en gettotalSalePerProductData para filtrar los productos vendidos por subfamilia o por almacén.

    • Pero en esta función no se están pasando al filtro, por lo que o están incompletos o se ignoran en esta parte del código.

Valor de stock

Este widget muestra el valor total del stock (cantidad × coste medio unitario) para dos periodos diferentes:

  • currentYear: Total de stock creado entre las fechas actuales indicadas (filter.start y filter.end).

  • lastYear: Total de stock creado en el mismo periodo del año anterior.

Es decir, multiplica el coste medio del producto por la cantidad registrada en cada movimiento de stock.

Tablas consultadas

  • stock (s)

    • Contiene los movimientos de stock, con datos como: created, amount, averageUnitCost, warehouse, etc.

  • product (p)

    • Información sobre los productos involucrados en los movimientos.

  • subfamily (sf)

    • Clasificación secundaria del producto (opcional).

Es decir, multiplica el coste medio del producto por la cantidad registrada en cada movimiento de stock.

Relaciones clave:

  • s.product = p.id → Une cada movimiento de stock con su producto.

  • p.subfamily = sf.id → Asocia el producto con su subfamilia (si tiene).

Tiene en cuenta lo siguiente

  • Fechas:

    • Dos periodos:

      • Actual (filter.start → filter.end)

      • Año anterior (start - 1 año → end - 1 año)

    • Solo incluye movimientos de stock creados en cualquiera de esos dos periodos.

  • Condiciones adicionales (opcional):

    • inDeposit: si es true, solo incluye productos en depósito (p.inDeposit = 1).

    • warehouseId: si se proporciona, filtra por almacenes específicos (s.warehouse IN ?).

    • subfamilyId: si se proporciona, filtra por subfamilias (sf.id IN ?).

Regularizaciones

Este fragmento crea un objeto regularizeData con tres datos:

  • currentYear: total de regularizaciones de stock realizadas en el periodo actual.

  • lastYear: total de regularizaciones del mismo periodo pero del año anterior.

  • percent: variación porcentual entre ambos periodos.

    • Si el total del año anterior es 0, devuelve 100.

    • Si no, calcula el % de variación con la fórmula: (actual - anterior)/anterior x 100

Tablas consultadas:

Usa la función getStockData, que consulta estas tablas:

  • stockTransaction (st): contiene los movimientos de stock.

  • product (p): se une para conocer el producto del movimiento.

  • subfamily (sf): permite filtrar por subfamilia del producto.

Tiene en cuenta lo siguiente:

  • Tipo de movimiento: Se filtra por st.type IN (1, 4), que representan tipos de regularización de stock, definidos así:

    • 1: ajuste de stock positivo

    • 4: ajuste de stock negativo

  • Rangos de fechas:

    • Año actual: entre filter.start y filter.end.

    • Año anterior: entre filter.start - 1 año y filter.end - 1 año.

  • Filtros adicionales (si se incluyen en filter):

    • warehouseId: filtra movimientos por almacén.

    • subfamilyId: filtra productos por subfamilia.

    • numberOfDecimals: redondea el resultado porcentual con esa precisión.

Transferencias

Este bloque crea un objeto transfersData con tres métricas relacionadas con transferencias de stock:

  • currentYear: total de stock transferido en el periodo actual (usando el filtro).

  • lastYear: total de stock transferido en el mismo periodo pero del año anterior.

  • percent: la variación porcentual entre el periodo actual y el anterior.

    • Si el total del año anterior es 0, se devuelve 100.

    • Si no, se calcula con la fórmula: (actual - anterior)/anterior x 100.

Tablas consultadas:

Este bloque utiliza la función getStockData, que a su vez consulta las siguientes tablas

  • stockTransaction (st): contiene todos los movimientos de inventario (entradas, salidas, ajustes, transferencias, etc.).

  • product (p): se une para obtener detalles del producto.

  • subfamily (sf) (opcional): permite aplicar filtros por subfamilia de producto.

Tiene en cuenta lo siguiente:

  • Tipo de movimiento:

    • Se filtra por st.type IN (2), lo que indica que solo se tienen en cuenta las transferencias de stock.

  • Fechas:

    • Periodo actual: desde filter.start hasta filter.end.

    • Mismo periodo del año anterior: se calcula automáticamente restando un año a ambas fechas.

  • Filtros adicionales que pueden aplicarse (según el contenido del objeto filter):

    • warehouseId: para limitar los datos a uno o varios almacenes.

    • subfamilyId: para limitar por subfamilias de productos.

    • numberOfDecimals: controla la precisión del redondeo del porcentaje.

Valor de stock en Deposito

Este widget muestra el valor económico total de los movimientos de stock de un tipo específico (por ejemplo, compras, ventas, ajustes…), comparando dos periodos:

  • currentTotal: Valor total de movimientos de stock del tipo indicado en el periodo actual (start a end).

  • lastYearTotal: Valor total de movimientos de stock del mismo tipo en el mismo periodo del año anterior.

Tablas consultadas:

  • stockTransaction (st)

    • Contiene los movimientos de stock: fecha, tipo, cantidad (amount), coste bruto por unidad (grossUnitCost), almacén, etc.

  • product (p)

    • Información de cada producto relacionado con el movimiento.

  • subfamily (sf)

    • Subcategoría del producto, usada para filtrar.

Tiene en cuenta lo siguiente:

  • Periodo:

    • Actual: Entre filter.start y filter.end.

    • Anterior: Mismo periodo, pero del año anterior (usando .addYears(-1)).

  • Tipo de movimiento:

    • Solo incluye movimientos cuyo type esté incluido en el array type. (Por ejemplo, type = [1, 3] para incluir ventas y ajustes).

  • Filtros opcionales:

    • warehouseId: si se indica, filtra por almacenes específicos.

    • subfamilyId: si se indica, filtra por subfamilias de productos.

    • numberOfDecimals: se usa para redondear los resultados.

Carritos

Esta función devuelve el número total de carritos de venta únicos (POS carts) que han generado movimientos de stock en dos periodos:

  • currentTotal: número de carritos únicos del periodo actual.

  • lastYearTotal: número de carritos únicos en el mismo periodo del año anterior.

Solo se cuentan los carritos que han generado movimientos de stock (stockTransaction), no todos los carritos creados.

Tablas consultadas:

  • stockTransaction (st)

    • Tabla principal donde se registran los movimientos de stock.

  • sale (s)

    • Relaciona cada movimiento con una venta (st.fkId = s.id).

  • posCartSale (pcs)

    • Permite obtener el carrito (pcs.cart) al que pertenece la venta.

  • product (p)

    • Relacionado con el producto afectado en el movimiento.

  • subfamily (sf)

    • Para filtrar por subcategorías de productos si es necesario.

Tiene en cuenta lo siguiente:

  • Periodos de comparación:

    • Actual: entre filter.start y filter.end

    • Año anterior: mismo rango pero hace un año (filter.start.addYears(-1) a filter.end.addYears(-1))

  • Lógica del conteo:

    • Solo se cuentan carritos únicos (COUNT(DISTINCT pcs.cart)) por periodo.

    • Se filtran por la fecha del movimiento (st.created).

  • Filtros opcionales:

    • warehouseId: Si se indica, filtra por uno o más almacenes.

    • subfamilyId: Si se indica, filtra por subfamilias de productos.

Precio y Unidades medio por carrito

Este widget muestra el número total de unidades vendidas (en realidad, unidades extraídas del stock) para dos periodos comparativos:

  • currentYearTotal: Total de unidades vendidas en el periodo actual.

  • lastYearTotal: Total de unidades vendidas en el mismo periodo del año anterior.

Las unidades se multiplican por -1 porque los movimientos de tipo 3 (ventas) se registran como salidas negativas en la tabla de stock.

Tablas consultadas

  • stockTransaction (st)

    • Tabla principal donde se registran los movimientos de stock (entradas y salidas de productos).

  • product (p)

    • Se une a stockTransaction para identificar el producto al que pertenece cada movimiento.

  • subfamily (sf)

    • Se une opcionalmente para permitir filtrar por subfamilias de productos.

Tiene en cuenta lo siguiente:

  • Periodos:

    • Actual: desde filter.start hasta filter.end

    • Año anterior: mismo rango de fechas, pero hace un año (start.addYears(-1))

  • Tipo de movimiento:

    • Solo se consideran los movimientos de tipo 3, que representan ventas (salidas de stock).

  • Lógica del cálculo:

    • Se suman todas las unidades vendidas en cada periodo.

    • Se multiplica por -1 porque las salidas del stock están registradas como valores negativos en st.amount.

  • Filtros opcionales:

    • warehouseId: si está definido, filtra los movimientos por almacenes específicos.

    • subfamilyId: si está definido, filtra los productos por sus subfamilias.

Tablas resumen

Top Ventas por Producto

Este widget muestra dos cosas:

  • data: un listado paginado de los productos que más unidades han salido del almacén (ventas) en un periodo de tiempo concreto.

    • Cada entrada contiene:

      • name: nombre del producto.

      • total: número de transacciones de stock de tipo salida (type = 3) asociadas a ese producto.

  • totalCount: número total de productos únicos (DISTINCT p.id) que tienen al menos una transacción de salida (stockTransaction.type = 3) dentro del periodo especificado. Esto se usa para paginar correctamente.

Las tablas principales que usa son:

  • stockTransaction (st) → almacena todos los movimientos de stock (entradas, salidas, ajustes…).

  • product (p) → contiene la información del producto al que pertenece cada movimiento de stock.

Relación:

  • Se hace un JOIN entre stockTransaction y product mediante p.id = st.product.

Tiene en cuenta lo siguiente

  • Fechas de creación del movimiento:

    • Solo considera los movimientos creados entre filters.start y filters.end.

    • st.created BETWEEN ? AND ?

  • Tipo de movimiento:

    • Solo se tienen en cuenta los movimientos de tipo salida → st.type IN (3).

  • Filtros opcionales si se proporcionan:

    • subfamilyId: solo productos cuya subfamilia (p.subfamily) esté en esa lista.

    • warehouseId: solo movimientos hechos desde los almacenes especificados (st.warehouse).

  • Paginación:

    • Devuelve los resultados en bloques definidos por page y pageSize.

    • Usa LIMIT ?, ? para controlar qué registros se devuelven en cada página.

Top ventas por subfamilia

Devuelve una lista de subfamilias de productos con el número total de transacciones de stock asociadas a productos de esa subfamilia durante un periodo de tiempo.

Cada fila contiene:

  • name: nombre de la subfamilia.

  • total: cantidad total de registros en stockTransaction vinculados a productos de esa subfamilia.

Tablas consultadas:

  • stockTransaction (st)

    • Fuente principal de datos (cada movimiento de stock).

  • product (p)

    • Para enlazar la transacción con el producto y su subfamilia.

  • subfamily (s)

    • Para obtener el nombre de la subfamilia relacionada con cada producto.

Tiene en cuenta lo siguiente:

  • Rango de fechas obligatorio:

    • Se filtra por la fecha de creación de la transacción:

  • Filtro por subfamilias específicas (opcional):

    • Si se indica filters.subfamilyId, solo se incluyen productos que pertenezcan a esas subfamilias.

  • Filtro por almacenes (opcional):

    • Si se indica filters.warehouseId, solo se incluyen transacciones realizadas en esos almacenes.

Top Proveedores

Esta función devuelve una lista de proveedores junto con el número de transacciones de stock en las que están involucrados. Para cada proveedor, muestra:

  • name: el nombre del proveedor.

  • total: el número total de transacciones de stock relacionadas con productos suministrados por ese proveedor.

Tablas consultadas:

  • stockTransaction (st)

    • Tabla principal donde se registran todas las entradas y salidas de stock.

    • Se usa st.created para filtrar por fecha.

  • product (p)

    • Relaciona cada transacción con el producto asociado.

  • supplier (s)

    • Relaciona cada producto con el proveedor que lo suministra.

Tiene en cuenta lo siguiente:

  • Rango de fechas:

    • Usa st.created BETWEEN filters.start AND filters.end para limitar los datos a un período específico.

  • Filtro por subfamilia (opcional):

    • Si subfamilyId está presente y tiene valores, solo se consideran productos que pertenecen a esas subfamilias.

  • Filtro por almacén (opcional):

    • Si warehouseId está presente y tiene valores, solo se consideran transacciones que ocurrieron en esos almacenes.

Dashboard de Facturación - ID 702

Introducción

Este dashboard ofrece un resumen del rendimiento financiero para el periodo seleccionado, incluyendo facturación, cobros, importes pendientes y desgloses de impuestos. Resume la distribución por método de pago, tipo impositivo y familias de productos.

En la parte superior del dashboard puedes aplicar los siguientes filtros:

  • Fecha → Selector de periodo (por defecto: “Este mes”).

  • Familia → Multiselector para que selecciones una o varias familias.

  • Empresa → Multiselector para que selecciones una o varias empresas.

  • Usuario → Multiselector para que selecciones una o varios usuarios.

  • TPV → Multiselector para que selecciones una o varios TPVs.

  • Tipo de factura → Multiselector para que selecciones una o varios tipos de facturas.

Indicadores de rendimiento

Total facturado (sin impuestos)

Esta función es útil para comparar la facturación del periodo actual vs el mismo periodo del año anterior, aplicando los filtros seleccionados. Ideal para informes de evolución anual en dashboards.

Muestra:

  • Total facturado (sin impuestos) del periodo actual.

  • Total facturado (sin impuestos) del periodo anterior.

  • Variación porcentual del total facturado (sin impuestos) con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • invoiceLine → tabla principal con los datos de línea de factura.

  • invoice → para obtener los datos de la factura a la que pertenece la línea.

  • invoiceType → para saber si la factura es interna o no.

  • product, subfamily, pos → para aplicar los filtros deseados por producto, familia o terminal de venta.

Tiene en cuenta lo siguiente:

  • Facturas activas (status != 0)

  • Facturas no internas (isInternal = 0)

  • Facturas del periodo actual o del mismo periodo hace un año

Total cobrado

Este widget muestra el total cobrado (pagos) en el periodo actual y el mismo periodo del año anterior, aplicando filtros personalizados.

Muestra:

  • currentYear: suma el importe de pagos (sp.amount) realizados entre las fechas indicadas en los filtros.

  • lastYear: suma el importe de pagos en el mismo rango de fechas pero del año anterior.

  • Se usa COALESCE para asegurar que si no hay resultados, se devuelva 0.

  • Variación porcentual de facturación con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • salePayment (sp) → tabla de relación de pagos.

  • payment (p) → detalles del pago (fecha, método, usuario…).

  • sale (s) → venta asociada al pago.

  • product, subfamily, paymentMethod, invoice, invoiceType, pos → se conectan para enriquecer la información (producto, categoría, TPV, factura…).

Tiene en cuenta lo siguiente:

  • Se filtran solo facturas activas (status != 0)

  • Y se excluyen facturas internas (isInternal = 0)

Pagos a crédito pendientes

Esta función calcula el importe total pendiente de cobro a crédito (sin domiciliación bancaria) para el periodo actual y para el mismo periodo del año anterior. Devuelve dos valores:

  • currentYear: total pendiente entre start y end

  • lastYear: total pendiente del mismo periodo, pero del año anterior

Muestra:

  • currentYear: suma de ventas pendientes (no facturadas, no domiciliadas) del periodo actual.

  • lastYear: la misma suma pero desplazada un año hacia atrás.

Se usa COALESCE(…, 0) para asegurar que si no hay resultados se devuelva 0.

  • Variación porcentual de facturación con indicador visual (⬆️ verde / ⬇️ rojo)

Tablas consultadas:

  • sale (s): tabla principal de ventas

  • product (prod): para asociar el producto

  • subfamily (sf): subfamilia del producto

  • pos (po): punto de venta (TPV)

Tiene en cuenta lo siguiente:

  • Solo se incluyen ventas en estado confirmado (status = 2)

  • Que fueron a crédito (onCredit = true)

  • Pero no domiciliadas (directDebit = false)

  • Que no son bonos (voucherType IS NULL)

Y que hayan sido usadas dentro del periodo actual o el mismo del año anterior.

Ventas no pagadas

Esta función calcula el importe total de ventas no cobradas (que no son a crédito) en dos periodos:

  • El intervalo de fechas actual (filters.start a filters.end)

  • El mismo intervalo del año anterior

Muestra:

  • currentYear: total de ventas no pagadas en el periodo actual

  • lastYear: total de ventas no pagadas en ese mismo periodo del año anterior (ambas devueltas como 0 si no hay resultados, gracias al uso de COALESCE)

  • Variación porcentual de facturación con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • sale (s): tabla principal de ventas

  • product (prod): producto de la venta

  • subfamily (sf): subfamilia del producto

  • pos (po): punto de venta o TPV

Tiene en cuenta lo siguiente:

  • Solo ventas confirmadas (status = 2)

  • Que no fueron pagadas a crédito (onCredit = false)

  • Que fueron usadas (useDate) en el intervalo actual o el mismo del año anterior

Ventas no facturadas

Este widget muestra el importe total de ventas no facturadas durante el rango de fechas actual y del año anterior.

Muestra:

  • currentYear: suma el importe de ventas (s.total) que no han sido facturadas y cuya fecha de uso (useDate) está en el rango actual.

  • lastYear: suma lo mismo pero para el mismo rango de fechas, un año antes.

  • COALESCE(…, 0) asegura que, si no hay resultados, devuelve 0.

  • Variación porcentual de facturación con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • sale (s) → ventas.

  • invoice (i) → unión para verificar si están facturadas o no.

  • invoiceType (it) → tipo de factura, aunque en este caso se une pero no se filtra.

  • product, subfamily, pos → para poder aplicar filtros por familia y TPV.

Tiene en cuenta lo siguiente:

  • Ventas no facturadas (s.invoice IS NULL)

  • En estado confirmado/activo (status = 2)

  • Sin bono o tipo de vale (voucherType IS NULL)

  • Y que:

    • Tengan una fecha de uso dentro del rango actual o del año anterior (esto se repite en los CASE y en el WHERE para acotar los datos).

Tablas resumen

Resumen por formas de pago

Este widget muestra el resumen por formas de pago, dentro de un rango de fechas y aplicando los filtros que se indiquen. Muestra cada forma de pago con su total correspondiente ordenado de mayor a menor.

Muestra:

  • Muestra un listado de formas de pago, la primera columna es el método de pago y la segunda columna muestra la suma de los importes pagados. Ordenado de mayor a menor.

Tablas consultadas:

  • salePayment → tabla de pagos individuales.

  • payment → información del pago.

  • sale → la venta relacionada.

  • product → producto de la venta.

  • subfamily → subfamilia del producto (puede ser null, por eso es LEFT JOIN)

  • paymentMethod → método de pago (efectivo, tarjeta)

  • invoice → factura relacionada.

  • invoiceType → tipo de factura.

  • pos → terminal de punto de venta.

Tiene en cuenta lo siguiente:

  • Solo pagos entre dos fechas.

  • Solo facturas válidas.

  • No internas.

Resumen facturado por impuesto

Esta función obtiene el total de impuestos facturados, agrupados por tipo de impuesto (taxRate), dentro de un rango de fechas y aplicando los filtros que se indiquen.

Muestra:

  • Este widget muestra el resumen por tipo de impuesto, dentro de un rango de fechas y aplicando los filtros que se indiquen. Muestra cada tipo de impuesto con su total correspondiente ordenado de mayor a menor.

Tablas consultadas:

  • Se seleccionan:

    • il.taxRate: tipo de impuesto aplicado.

    • il.total - il.totalBeforeTaxes: total de impuestos en esa línea (diferencia entre total con impuestos y sin impuestos).

  • Se hace JOIN con:

    • invoice → para obtener la factura a la que pertenece la línea.

    • invoiceType → para comprobar si es una factura interna o no.

    • product, subfamily, family → para poder aplicar filtros por familia de productos.

    • pos → para filtrar por terminal de venta.

Tiene en cuenta lo siguiente:

  • Solo facturas con estado distinto de 0 (i.status != ?) → normalmente 0 = anulada.

  • Solo facturas que no sean internas (it.isInternal = ?)

  • Filtrado por fecha entre filters.start y filters.end.

Resumen por facturación por familias

Este widget muestra un resumen de la facturación agrupado por familia de producto, mostrando: - total sin impuestos, - total de impuestos, - y total con impuestos - para el rango de fechas seleccionado (y filtros adicionales).

Muestra:

  • name: nombre de la familia del producto.

  • totalBFTaxes: suma de totales sin impuestos.

  • totalTaxes: suma de los impuestos aplicados (total - totalBeforeTaxes).

  • total: suma total con impuestos.

Tablas consultadas:

  • invoiceLine (il): líneas de facturas (cada producto facturado).

  • invoice (i): factura correspondiente.

  • invoiceType (it): tipo de factura (se usa para filtrar internas).

  • product (p): producto facturado.

  • subfamily (sf), family (f): jerarquía de producto.

  • pos (po): punto de venta.

Tiene en cuenta lo siguiente:

  • Solo se consideren facturas activas (status != 0)

  • No se incluyan facturas internas (isInternal = 0)

  • Se limiten los datos al rango de fechas indicado

Resumen por facturación por subfamilias

Esta función obtiene un resumen de la facturación agrupado por subfamilia de productos, mostrando:

  • total sin impuestos,

  • total de impuestos,

  • total con impuestos.

  • para el período de tiempo definido por el filtro, más otros filtros opcionales (usuario, empresa, familia, TPV).

Muestra:

  • name: nombre de la subfamilia

  • totalBFTaxes: suma del total antes de impuestos

  • totalTaxes: suma de los impuestos aplicados

  • total: suma total con impuestos.

Tablas consultadas:

  • invoiceLine (il): líneas de factura

  • invoice (i): factura

  • invoiceType (it): tipo de factura

  • product (p): producto

  • subfamily (sf): subfamilia del producto

  • family (f): familia padre (por si se necesita más adelante)

  • pos (po): punto de venta

Tiene en cuenta lo siguiente:

  • Solo facturas activas (status != 0)

  • No internas (isInternal = 0)

  • Dentro del rango de fechas (filters.start, filters.end)

Dashboard de Mapa de calor - ID 703

En la parte superior del dashboard puedes aplicar los siguientes filtros:

  • Fecha → Selector de periodo (por defecto: “Este mes”).

  • Area → Multiselector para que selecciones una o varias areas.

  • Tipo de Mapa de Calor → Semana, Día y Hora o Día y Ocupación.

  • Canal → Online u Offline.

  • Tipo de recurso → Multiselector para que selecciones uno o varios tipos de recurso.

Mapa de calor semana

Este widget muestra los datos necesarios para un heatmap (mapa de calor) semanal que muestra cuántas reservas se han hecho por hora y por día de la semana dentro de un rango de fechas determinado.

Muestra:

  • hour: la hora del día (0 a 23).

  • day: el día de la semana (1 = Lunes, 7 = Domingo).

  • total: número de reservas realizadas para esa combinación hora/día.

En la parte de getHeatMapByWeek, se transforman esos datos en un formato estructurado para renderizar el heatmap, añadiendo totales por fila y columna, y calculando el valor máximo (maxValue) para calibrar los colores del mapa.

Tablas consultadas:

  • booking (b): tabla principal, contiene las reservas.

  • bookingResource ®: enlaza la reserva con un recurso (ej. pista, carrito, green fee…).

  • bookingResourceType (rt): da el tipo del recurso (ej. buggy, tee time, pista de pádel…).

Tiene en cuenta lo siguiente:

  • b.crossing = false: solo reservas normales (no cruzadas).

  • b.timeout IS NULL OR b.timeout > now(): solo reservas que siguen activas o vigentes.

  • b.area = ?: se filtra por la zona (área) seleccionada.

  • b.start BETWEEN ? AND ?: solo se tienen en cuenta las reservas dentro del rango de fechas indicado.

  • b.byDays = 0: excluye reservas que ocupan días completos (probablemente solo quiere por horas).

  • b.status IN (1, 2, 3): solo reservas con estado válido (pendiente, confirmada o similar).

  • b.online (opcional): si está presente, filtra por si la reserva fue online o no.

  • rt.id IN ? (opcional): filtra por tipos de recurso específicos.

Mapa de calor día y hora

Este widget muestra un mapa de calor por día y hora. Es decir, te dice cuántas reservas se han realizado en cada hora de cada día dentro de un rango de fechas determinado.

Muestra:

  • hour: hora de la reserva (de 0 a 23).

  • day: día del mes.

  • month: mes.

  • year: año.

  • total: número de reservas para esa combinación de hora, día, mes y año.

Esta información se transforma en una matriz lista para mostrar gráficamente el heatmap, con:

  • Filas = días (por fecha, incluyendo día de la semana).

  • Columnas = horas.

  • Celdas = número de reservas (o “-” si no hubo ninguna).

  • Totales por fila y columna.

  • Valor máximo (maxValue) para escalar el color del mapa.

Utiliza las siguientes tablas:

  • booking (b): la tabla principal de reservas.

  • bookingResource ®: enlaza la reserva con un recurso (ej. pista, tee time).

  • bookingResourceType (rt): indica el tipo de recurso.

  • bookingArea (usada en getTimeSpan): se consulta para obtener la hora mínima y máxima de actividad de la zona seleccionada, útil para definir el eje de horas del heatmap.

Tiene en cuenta lo siguiente:

  • b.crossing = false: excluye reservas cruzadas.

  • (b.timeout IS NULL OR b.timeout > now()): solo se incluyen reservas activas o futuras.

  • b.area = ?: filtra por la zona seleccionada.

  • b.start BETWEEN ? AND ?: solo incluye reservas dentro del rango de fechas indicado.

  • b.byDays = 0: descarta reservas que son por días completos (solo horas).

  • b.status no se filtra en este caso (a diferencia de getHeatMapByWeekData).

  • b.online = ? (opcional): filtra si es reserva online.

  • rt.id IN ? (opcional): filtra por tipos de recurso.

Mapa de calor - Día y Ocupación

Este widget muestra un mapa de ocupación diaria, es decir:

  • Cuántas reservas se han hecho cada día en un rango de fechas.

  • Qué porcentaje de ocupación representa cada día respecto a la capacidad teórica del mes.

  • Un total de reservas y ocupación global.

Los datos que devuelve son:

  • bookingData: total de reservas por día.

  • occupationData: porcentaje de ocupación por día, en función de la capacidad definida para ese mes.

  • maxBookingValue: máximo de reservas en un solo día.

  • maxOccupationValue: máxima ocupación porcentual en un día.

  • weekDay: lista de días del rango, con su nombre y fecha.

  • hours: cabecera que contiene los títulos de cada serie: “Ocupación %” y “Reservas”.

Consulta las siguientes tablas:

  • booking (b): tabla principal de reservas.

  • bookingResource ®: une la reserva con el recurso.

  • bookingResourceType (rt): indica el tipo de recurso reservado.

Tiene en cuenta lo siguiente:

  • b.crossing = false: descarta reservas cruzadas.

  • (b.timeout IS NULL OR b.timeout > now()): solo incluye reservas activas o futuras.

  • b.area = ?: filtra por área.

  • b.start BETWEEN ? AND ?: rango de fechas indicado.

  • b.byDays = 0: solo reservas por hora, no por días completos.

  • b.status IN (1,2,3): solo reservas con estado válido (por ejemplo: confirmadas, en curso).

Filtros opcionales:

  • b.online = ?: si se quieren ver solo reservas online.

  • rt.id IN ?: por tipos de recurso.

En el cálculo posterior (getHeatMapOccupation):

  • Define un array de días desde la fecha final hasta la inicial.

  • Busca las capacidades mensuales configuradas (por ejemplo: settings_januaryCapacity, settings_februaryCapacity, etc.).

  • Divide la capacidad del mes entre los días de ese mes → capacidad diaria estimada.

  • Calcula el porcentaje de ocupación diaria: (reservas del día * 100) / capacidad diaria.

También calcula totales:

  • Suma total de reservas (bookingTotal).

  • Suma total de capacidad (totalCapacity).

  • Ocupación total del rango: (bookingTotal * 100) / totalCapacity.

Dashboard de Management - ID 706


Reservas por meses

Muestra:

  • Genera una comparativa mensual entre las reservas del año pasado y el año actual, y también calcula una proyección (forecast) para el resto del año.

Tablas consultadas:

  • booking.

  • bookingResource.

  • bookingResourceType.

Tiene en cuenta lo siguiente:

  • Reservas no cruzadas.

  • Reservas no por días completos.

  • Reservas activas (status 1, 2 o 3).

  • Reservas no expiradas.

Situación de negocio

Previsión

Muestra:

  • Valor estimado de reservas. Predice el número de reservas del año actual combinando datos reales y del año pasado:

    • Meses pasados: se usa el número real de reservas de este año.

    • Mes actual:

      • Hasta hoy: datos reales.

      • Desde mañana: datos del mismo mes del año pasado.

    • Meses futuros: se usa directamente el número de reservas del año pasado como predicción.

  • Comparativa de reservas con periodo anterior.

  • Variación porcentual de reservas con indicador visual (⬆️ verde / ⬇️ rojo).

Tablas consultadas:

  • booking.

  • bookingResource: recursos reservables.

  • bookingResourceType: tipo del recurso.

Tiene en cuenta lo siguiente:

  • Solo considera reservas dentro de dos rangos de fechas

  • Filtra para incluir solo reservas válidas, no canceladas ni cruzadas, que no estén expiradas.

Resumen de facturación por familias

Este widget muestra un resumen de la facturación agrupado por familia de producto, mostrando: - total sin impuestos, - total de impuestos, - y total con impuestos - para el rango de fechas seleccionado (y filtros adicionales).

Muestra:

  • name: nombre de la familia del producto.

  • totalBFTaxes: suma de totales sin impuestos.

  • totalTaxes: suma de los impuestos aplicados (total - totalBeforeTaxes).

  • total: suma total con impuestos.

Tablas consultadas:

  • invoiceLine (il): líneas de facturas (cada producto facturado).

  • invoice (i): factura correspondiente.

  • invoiceType (it): tipo de factura (se usa para filtrar internas).

  • product (p): producto facturado.

  • subfamily (sf), family (f): jerarquía de producto.

  • pos (po): punto de venta.

Tiene en cuenta lo siguiente:

  • Solo se consideren facturas activas (status != 0)

  • No se incluyan facturas internas (isInternal = 0)

  • Se limiten los datos al rango de fechas indicado

Canal: Online/Offline

Muestra:

Distribución de reservas según canal Online u Offline, con cambio porcentual respecto al periodo anterior.

  • Crea una columna llamada name que indica si la reserva fue Online u Offline.

  • Cuenta cuántas reservas hay en cada grupo.

Tablas consultadas:

  • booking.

  • bookingResource: recursos reservables.

  • bookingResourceType: tipo del recurso.

Tiene en cuenta lo siguiente:

  • Solo incluye reservas en el rango de fechas.

  • Excluye reservas caducadas, cruzadas, por días completos o con estado inválido.

  • Asegura que solo entren reservas activas (por ejemplo: confirmadas, pendientes, etc.).

¿Ha quedado contestada tu pregunta?