{
  "name": "reportes",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "GET",
        "path": "reportes/:tipo",
        "responseMode": "responseNode"
      },
      "id": "wh",
      "name": "GET reportes",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const tipo = items[0].json.params.tipo;\nconst desde = items[0].json.query.desde || '1900-01-01';\nconst hasta = items[0].json.query.hasta || '2999-12-31';\nconst formato = items[0].json.query.formato || 'csv'; // csv|xlsx|pdf\nconst queries = {\n  ventas:   `SELECT numero, fecha, cliente, vendedor, total, adeudado, estado FROM v_ov_resumen WHERE fecha BETWEEN '${desde}' AND '${hasta}' ORDER BY fecha DESC`,\n  stock:    `SELECT producto, sku, stock, reservado, disponible FROM v_stock_disponible ORDER BY producto`,\n  faltantes:`SELECT ov, producto, sku, cantidad FROM v_faltantes`,\n  cobranzas:`SELECT o.numero, o.fecha, c.nombre AS cliente, o.total, o.reserva, o.adeudado, o.estado\n             FROM ordenes_venta o LEFT JOIN clientes c ON c.id = o.cliente_id\n             WHERE o.fecha BETWEEN '${desde}' AND '${hasta}' AND o.adeudado > 0 ORDER BY o.fecha`\n};\nif (!queries[tipo]) throw new Error('Tipo desconocido: ' + tipo);\nreturn [{ json: { sql: queries[tipo], tipo, formato } }];"
      },
      "id": "sql",
      "name": "Armar SQL",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "={{ $json.sql }}"
      },
      "id": "run",
      "name": "Ejecutar",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        680,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const formato = $node['Armar SQL'].json.formato;\nconst rows = items.map(i => i.json);\nif (!rows.length) return [{ json: { ct: 'text/plain', body: 'Sin datos' } }];\nif (formato === 'csv') {\n  const cols = Object.keys(rows[0]);\n  const csv = [cols.join(','), ...rows.map(r => cols.map(c => JSON.stringify(r[c] ?? '')).join(','))].join('\\n');\n  return [{ json: { ct: 'text/csv', body: csv } }];\n}\nreturn [{ json: { ct: 'application/json', body: JSON.stringify(rows, null, 2) } }];"
      },
      "id": "fmt",
      "name": "Formatear",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{$json.body}}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "={{$json.ct}}"
              },
              {
                "name": "Content-Disposition",
                "value": "=attachment; filename=reporte-{{ $node['Armar SQL'].json.tipo }}.csv"
              }
            ]
          }
        }
      },
      "id": "resp",
      "name": "Responder",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1120,
        300
      ]
    }
  ],
  "connections": {
    "GET reportes": {
      "main": [
        [
          {
            "node": "Armar SQL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Armar SQL": {
      "main": [
        [
          {
            "node": "Ejecutar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ejecutar": {
      "main": [
        [
          {
            "node": "Formatear",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Formatear": {
      "main": [
        [
          {
            "node": "Responder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}