chore: sync from fn-registry agent
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "07306d98",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 01 — Exploración: quotes ↔ call_center ↔ factura\n",
|
||||
"\n",
|
||||
"Mapa de tablas y joins en `psql_dcpublic` (BigQuery `autingo-159109`).\n",
|
||||
"\n",
|
||||
"## Cadena de joins\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"tpv_authorization_tpvuser_centers (dccenter_id ∈ {159 CALL_CENTER_AURGI, 162 CALL_CENTER})\n",
|
||||
" │ tpvuser_id\n",
|
||||
" ▼\n",
|
||||
"tpv_orders_quote.created_by_id ──► quote por agente call_center\n",
|
||||
" │ order_id\n",
|
||||
" ▼\n",
|
||||
"tpv_orders_order ─► terminal_id ─► tpv_terminals.center_id ─► centers (centro real de facturación)\n",
|
||||
" │ │ customer_id │ vehicle_id\n",
|
||||
" ▼ ▼ ▼\n",
|
||||
"tpv_orders_invoice (status convertido) tpv_customers (tlf) tpv_vehicles_vehicle (matrícula)\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Identidad cliente = `(customer_id, vehicle_id)` o (tlf, matrícula) según necesite normalización."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d2b6d545",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os, sys\n",
|
||||
"from google.cloud import bigquery\n",
|
||||
"import pandas as pd\n",
|
||||
"\n",
|
||||
"PROJECT = \"autingo-159109\"\n",
|
||||
"DATASET = \"psql_dcpublic\"\n",
|
||||
"bq = bigquery.Client(project=PROJECT)\n",
|
||||
"\n",
|
||||
"def q(sql):\n",
|
||||
" return bq.query(sql).to_dataframe()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3238b92e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Usuarios call_center"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "34d656ad",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"cc_users = q(f\"\"\"\n",
|
||||
"SELECT u.id, u.name, u.email, u.is_active, u.role_id,\n",
|
||||
" STRING_AGG(CAST(uc.dccenter_id AS STRING)) AS centers\n",
|
||||
"FROM `{PROJECT}.{DATASET}.tpv_authorization_tpvuser` u\n",
|
||||
"JOIN `{PROJECT}.{DATASET}.tpv_authorization_tpvuser_centers` uc\n",
|
||||
" ON u.id = uc.tpvuser_id\n",
|
||||
"WHERE uc.dccenter_id IN (159, 162)\n",
|
||||
"GROUP BY 1,2,3,4,5\n",
|
||||
"ORDER BY u.is_active DESC, u.id\n",
|
||||
"\"\"\")\n",
|
||||
"print(f\"Total usuarios call_center: {len(cc_users)} (activos: {cc_users.is_active.sum()})\")\n",
|
||||
"cc_users.head(20)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9ec102fb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. Schema quote — campos clave"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e5f94b52",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"q(f\"\"\"\n",
|
||||
"SELECT column_name, data_type\n",
|
||||
"FROM `{PROJECT}.{DATASET}.INFORMATION_SCHEMA.COLUMNS`\n",
|
||||
"WHERE table_name='tpv_orders_quote'\n",
|
||||
"ORDER BY ordinal_position\n",
|
||||
"\"\"\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "32ffc1d2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 3. Distribución `status` y `accepted` (últimos 90d)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "609022a9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"q(f\"\"\"\n",
|
||||
"SELECT status, accepted, COUNT(*) n\n",
|
||||
"FROM `{PROJECT}.{DATASET}.tpv_orders_quote`\n",
|
||||
"WHERE created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)\n",
|
||||
" AND deleted_at IS NULL\n",
|
||||
"GROUP BY status, accepted\n",
|
||||
"ORDER BY n DESC\n",
|
||||
"\"\"\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "73c85198",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 4. Conversion quote → invoice (mismo order_id)\n",
|
||||
"\n",
|
||||
"Una quote convierte cuando existe `tpv_orders_invoice` con el mismo `order_id`. Ese invoice fija la facturación real (NAV-sync via `nav_id`)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "46378f84",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"q(f\"\"\"\n",
|
||||
"SELECT\n",
|
||||
" COUNT(*) AS quotes,\n",
|
||||
" COUNT(DISTINCT q.order_id) AS distinct_orders,\n",
|
||||
" SUM(CASE WHEN i.id IS NOT NULL THEN 1 ELSE 0 END) AS quotes_con_invoice,\n",
|
||||
" SAFE_DIVIDE(SUM(CASE WHEN i.id IS NOT NULL THEN 1 ELSE 0 END), COUNT(*)) AS conversion_rate\n",
|
||||
"FROM `{PROJECT}.{DATASET}.tpv_orders_quote` q\n",
|
||||
"LEFT JOIN `{PROJECT}.{DATASET}.tpv_orders_invoice` i\n",
|
||||
" ON q.order_id = i.order_id\n",
|
||||
"WHERE q.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)\n",
|
||||
" AND q.deleted_at IS NULL\n",
|
||||
"\"\"\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "df8b402c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 5. Sanity: quote por call_center vs otro\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "506744d3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"q(f\"\"\"\n",
|
||||
"WITH cc_users AS (\n",
|
||||
" SELECT DISTINCT tpvuser_id AS user_id\n",
|
||||
" FROM `{PROJECT}.{DATASET}.tpv_authorization_tpvuser_centers`\n",
|
||||
" WHERE dccenter_id IN (159, 162)\n",
|
||||
")\n",
|
||||
"SELECT\n",
|
||||
" CASE WHEN cc.user_id IS NOT NULL THEN 'call_center' ELSE 'otro' END AS origen_user,\n",
|
||||
" COUNT(*) AS quotes,\n",
|
||||
" SUM(CASE WHEN i.id IS NOT NULL THEN 1 ELSE 0 END) AS convertidos,\n",
|
||||
" ROUND(SAFE_DIVIDE(SUM(CASE WHEN i.id IS NOT NULL THEN 1 ELSE 0 END), COUNT(*)), 3) AS conv_rate\n",
|
||||
"FROM `{PROJECT}.{DATASET}.tpv_orders_quote` q\n",
|
||||
"LEFT JOIN cc_users cc ON q.created_by_id = cc.user_id\n",
|
||||
"LEFT JOIN `{PROJECT}.{DATASET}.tpv_orders_invoice` i ON q.order_id = i.order_id\n",
|
||||
"WHERE q.created_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)\n",
|
||||
" AND q.deleted_at IS NULL\n",
|
||||
"GROUP BY 1\n",
|
||||
"\"\"\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user