{
  "name": "Cierre de caja: alerta de descuadres",
  "nodes": [
    {
      "parameters": {
        "content": "## Alerta de descuadres de caja\nCada noche lee los cierres del día en una hoja de Google y te envía **un solo correo** con los que superan el umbral. Si ningún cierre lo supera, no llega nada.\n\nEs una plantilla: adáptala y pruébala con datos de prueba antes de fiarte de ella.\n\nExplicación completa en el artículo «Cierre de caja: cómo automatizar el control de descuadres» de fernandorivera.es.",
        "height": 300,
        "width": 400,
        "color": 4
      },
      "id": "eeae42f5-2393-54ca-aeb8-1400dde49b76",
      "name": "Nota: qué hace",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -440,
        -360
      ]
    },
    {
      "parameters": {
        "content": "## 1. Prepara la hoja\nPestaña **Cierres**, una fila por caja y medio de pago, con estas columnas en la fila 1:\n\n`Fecha` · `Tienda` · `Caja` · `Medio de pago` · `Venta TPV` · `Contado` · `Descuadre` · `Usuario` · `Comentario`\n\n- **Fecha** como texto AAAA-MM-DD (por ejemplo 2026-11-03).\n- **Descuadre** = Contado − Venta TPV (negativo si falta dinero). Puede venir del TPV o ser una fórmula.\n\nLa hoja la rellena tu TPV (API, integración o informe por correo) o la persona que cierra. Si tu TPV se conecta directamente con n8n, puedes cambiar el nodo de Google Sheets por el suyo.",
        "height": 360,
        "width": 460,
        "color": 5
      },
      "id": "79fad5e8-750b-5942-87ae-24718981a89e",
      "name": "Nota: la hoja",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -20,
        -420
      ]
    },
    {
      "parameters": {
        "content": "## 2. Configura\n- **Configuración**: pon tu umbral en euros y el correo que recibe el aviso.\n- **Leer cierres**: cambia `TU_ID_DE_HOJA` por el ID de tu hoja (está en la URL, entre `/d/` y `/edit`) y crea la credencial de Google.\n- **Enviar aviso**: crea la credencial de Gmail.\n- **Cada noche**: ajusta la hora a cuando ya estén todos los cierres.\n\nLa zona horaria del flujo está en Europe/Madrid (Ajustes del flujo).",
        "height": 360,
        "width": 420,
        "color": 6
      },
      "id": "24fe741c-d8b9-56bb-87e2-5853f803cbac",
      "name": "Nota: configura",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        460,
        -420
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "days",
              "daysInterval": 1,
              "triggerAtHour": 23,
              "triggerAtMinute": 30
            }
          ]
        }
      },
      "id": "9ff1145e-bf57-5256-a45d-f6edc6b04137",
      "name": "Cada noche 23:30",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -400,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "90f6a7a9-7f68-5928-95a2-abbe2d2227c2",
              "name": "umbral_euros",
              "value": 5,
              "type": "number"
            },
            {
              "id": "2a8a13cf-c071-502e-b731-fea5eac5a28f",
              "name": "email_aviso",
              "value": "TU_CORREO",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "10d3e8e5-b5cc-5817-a9ac-e99479718940",
      "name": "Configuración",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -180,
        0
      ]
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "TU_ID_DE_HOJA",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Cierres",
          "mode": "name"
        },
        "options": {}
      },
      "id": "c607403d-4367-55c4-8676-356187ba01db",
      "name": "Leer cierres",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        40,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "efbfa78a-18cb-5501-9903-df49ff468568",
              "leftValue": "={{ String($json['Fecha']).trim() }}",
              "rightValue": "={{ $now.toFormat('yyyy-MM-dd') }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "fe1ad63b-9cd8-5249-a0e0-a4f60dee8efd",
              "leftValue": "={{ Math.abs(parseFloat(String($json['Descuadre'] ?? '').replace(',', '.'))) }}",
              "rightValue": "={{ $('Configuración').first().json.umbral_euros }}",
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "id": "f5d0993d-5ec6-5f51-9051-8d981e7bc9bc",
      "name": "¿Hoy y supera el umbral?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        260,
        0
      ]
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "descuadres",
        "options": {}
      },
      "id": "bfca3111-13d4-5614-9d45-8840a5b87f2b",
      "name": "Juntar descuadres",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        480,
        -100
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $('Configuración').first().json.email_aviso }}",
        "subject": "=Descuadres de caja {{ $now.toFormat('dd/MM') }}: {{ $json.descuadres.length }} cierre(s) por revisar",
        "emailType": "text",
        "message": "=Hola:\n\nEstos cierres de hoy ({{ $now.toFormat('dd/MM/yyyy') }}) superan el umbral de {{ $('Configuración').first().json.umbral_euros }} €:\n\n{{ $json.descuadres.map(d => '- ' + d['Tienda'] + ' · caja ' + d['Caja'] + ' · ' + d['Medio de pago'] + ': ' + d['Descuadre'] + ' € (cerró ' + d['Usuario'] + ')' + (d['Comentario'] ? ' · Comentario: ' + d['Comentario'] : ' · SIN COMENTARIO')).join('\\n') }}\n\nAntes de dar nada por perdido: recuento, salidas sin anotar, cobros con tarjeta marcados como efectivo, anulaciones y fondo de caja.\n\nAviso automático del flujo de cierres de caja.",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "f3853770-74c0-5548-9621-851a7cf9b63b",
      "name": "Enviar aviso",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        700,
        -100
      ],
      "webhookId": "a38bf6aa-3874-5cd3-963b-2d8f8e0f4124"
    },
    {
      "parameters": {},
      "id": "d13e46b3-1828-5eda-8ddf-5000d2476567",
      "name": "Sin descuadres: no se envía nada",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        480,
        120
      ]
    },
    {
      "parameters": {
        "content": "### Por qué un umbral\nUn descuadre aislado de pocos euros suele ser un error humano. El aviso es para lo que se sale de lo normal. Los patrones (mismo turno, siempre falta) se ven en el historial de la hoja.",
        "height": 200,
        "width": 300,
        "color": 7
      },
      "id": "0b960465-42cb-5a68-80ff-b1def6a2b190",
      "name": "Nota: umbral",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        180,
        200
      ]
    }
  ],
  "connections": {
    "Cada noche 23:30": {
      "main": [
        [
          {
            "node": "Configuración",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configuración": {
      "main": [
        [
          {
            "node": "Leer cierres",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leer cierres": {
      "main": [
        [
          {
            "node": "¿Hoy y supera el umbral?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Juntar descuadres": {
      "main": [
        [
          {
            "node": "Enviar aviso",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Hoy y supera el umbral?": {
      "main": [
        [
          {
            "node": "Juntar descuadres",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sin descuadres: no se envía nada",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "timezone": "Europe/Madrid"
  },
  "tags": []
}
