# Metabase Actions — Alta de Piezas e Intercambios

## Requisitos
- Metabase v0.44+ (Open Source o Pro)
- Actions habilitadas en Admin → Settings
- Database con "Model actions" activado

---

## 1. Configuración Inicial

### 1.1 Habilitar Actions
1. Ir a **Admin** → **Settings**
2. Buscar **"Enable Actions"** → Activar
3. Ir a **Admin** → **Databases** → Click en `nexus_autoparts`
4. Activar **"Model actions"**

### 1.2 Crear Modelos Base

En Metabase, un **Modelo** es una pregunta (query) guardada como tabla virtual.
Los Actions se vinculan a Modelos.

**Modelo 1: Piezas OEM** → New → SQL Query:
```sql
SELECT
    p.id_part,
    p.oem_part_number,
    p.name_part,
    p.name_es,
    pg.name_part_group AS grupo,
    pc.name_part_category AS categoria,
    p.description,
    p.description_es,
    p.weight_kg,
    mat.name_material AS material
FROM parts p
JOIN part_groups pg ON p.group_id = pg.id_part_group
JOIN part_categories pc ON pg.category_id = pc.id_part_category
LEFT JOIN materials mat ON p.id_material = mat.id_material
ORDER BY p.oem_part_number
```
Guardar → Click ⋯ → **Turn into a model** → Nombrar: `Piezas OEM`

**Modelo 2: Fitments** → New → SQL Query:
```sql
SELECT
    vp.id_vehicle_part,
    b.name_brand AS marca,
    m.name_model AS modelo,
    y.year_car AS año,
    e.name_engine AS motor,
    p.oem_part_number,
    p.name_part AS pieza,
    vp.quantity_required AS cantidad,
    pp.name_position_part AS posicion,
    vp.fitment_notes AS notas
FROM vehicle_parts vp
JOIN model_year_engine mye ON vp.model_year_engine_id = mye.id_mye
JOIN models m ON mye.model_id = m.id_model
JOIN brands b ON m.brand_id = b.id_brand
JOIN years y ON mye.year_id = y.id_year
JOIN engines e ON mye.engine_id = e.id_engine
JOIN parts p ON vp.part_id = p.id_part
LEFT JOIN position_part pp ON vp.id_position_part = pp.id_position_part
ORDER BY b.name_brand, m.name_model, y.year_car
```
Guardar → **Turn into a model** → Nombrar: `Fitments`

**Modelo 3: Aftermarket** → New → SQL Query:
```sql
SELECT
    ap.id_aftermarket_parts,
    p.oem_part_number AS oem_ref,
    p.name_part AS pieza_oem,
    mfr.name_manufacture AS fabricante,
    ap.part_number AS numero_aftermarket,
    ap.name_aftermarket_parts AS nombre,
    ap.name_es AS nombre_es,
    qt.name_quality AS calidad,
    ap.price_usd AS precio_usd,
    ap.warranty_months AS garantia_meses
FROM aftermarket_parts ap
JOIN parts p ON ap.oem_part_id = p.id_part
JOIN manufacturers mfr ON ap.manufacturer_id = mfr.id_manufacture
LEFT JOIN quality_tier qt ON ap.id_quality_tier = qt.id_quality_tier
ORDER BY p.oem_part_number, mfr.name_manufacture
```
Guardar → **Turn into a model** → Nombrar: `Aftermarket`

**Modelo 4: Cross-References** → New → SQL Query:
```sql
SELECT
    pcr.id_part_cross_ref,
    p.oem_part_number AS oem_ref,
    p.name_part AS pieza,
    pcr.cross_reference_number AS numero_cruzado,
    rt.name_ref_type AS tipo_referencia,
    pcr.source_ref AS fuente,
    pcr.notes AS notas
FROM part_cross_references pcr
JOIN parts p ON pcr.part_id = p.id_part
LEFT JOIN reference_type rt ON pcr.id_ref_type = rt.id_ref_type
ORDER BY p.oem_part_number, rt.name_ref_type
```
Guardar → **Turn into a model** → Nombrar: `Cross-References`

---

## 2. Crear Actions (Formularios de Alta)

Para cada Modelo, crear Actions que permiten insertar datos.

### Action 1: Nueva Pieza OEM

1. Abrir el modelo **Piezas OEM**
2. Click **⋯** → **Info** → **Actions** → **New action**
3. Nombrar: `Alta de Pieza OEM`
4. Pegar este SQL:

```sql
INSERT INTO parts (
    oem_part_number,
    name_part,
    name_es,
    group_id,
    description,
    description_es,
    weight_kg,
    id_material
) VALUES (
    {{oem_part_number}},
    {{name_part}},
    {{name_es}},
    {{group_id}},
    {{description}},
    {{description_es}},
    {{weight_kg}},
    {{id_material}}
)
```

5. Configurar campos del formulario:

| Variable | Label | Tipo | Requerido |
|----------|-------|------|-----------|
| `oem_part_number` | Número OEM | string | Si |
| `name_part` | Nombre (EN) | string | Si |
| `name_es` | Nombre (ES) | string | No |
| `group_id` | ID Grupo | number | Si |
| `description` | Descripción (EN) | string (long) | No |
| `description_es` | Descripción (ES) | string (long) | No |
| `weight_kg` | Peso (kg) | number | No |
| `id_material` | ID Material | number | No |

6. Click **Save**

> **Tip:** Para que el usuario no tenga que memorizar `group_id`, crea una pregunta
> auxiliar con los grupos disponibles:
> ```sql
> SELECT pg.id_part_group AS id, pg.name_part_group AS grupo,
>        pc.name_part_category AS categoria
> FROM part_groups pg
> JOIN part_categories pc ON pg.category_id = pc.id_part_category
> ORDER BY pc.display_order, pg.display_order
> ```

---

### Action 2: Nuevo Fitment (vincular pieza a vehículo)

1. Abrir el modelo **Fitments**
2. **New action** → Nombrar: `Alta de Fitment`
3. SQL:

```sql
INSERT INTO vehicle_parts (
    model_year_engine_id,
    part_id,
    quantity_required,
    id_position_part,
    fitment_notes
) VALUES (
    {{model_year_engine_id}},
    {{part_id}},
    {{quantity_required}},
    {{id_position_part}},
    {{fitment_notes}}
)
```

| Variable | Label | Tipo | Requerido | Default |
|----------|-------|------|-----------|---------|
| `model_year_engine_id` | ID Vehículo (MYE) | number | Si | — |
| `part_id` | ID Pieza | number | Si | — |
| `quantity_required` | Cantidad | number | No | 1 |
| `id_position_part` | Posición (1=front, 2=rear) | number | No | — |
| `fitment_notes` | Notas | string | No | — |

> **Tip:** Para encontrar el `model_year_engine_id`, crea esta pregunta auxiliar:
> ```sql
> SELECT mye.id_mye AS id, b.name_brand AS marca,
>        m.name_model AS modelo, y.year_car AS año, e.name_engine AS motor
> FROM model_year_engine mye
> JOIN models m ON mye.model_id = m.id_model
> JOIN brands b ON m.brand_id = b.id_brand
> JOIN years y ON mye.year_id = y.id_year
> JOIN engines e ON mye.engine_id = e.id_engine
> WHERE b.name_brand ILIKE {{'%' || marca || '%'}}
>   AND m.name_model ILIKE {{'%' || modelo || '%'}}
> ORDER BY b.name_brand, m.name_model, y.year_car
> ```

---

### Action 3: Fitment Masivo (una pieza → varios vehículos)

1. En el modelo **Fitments** → **New action**
2. Nombrar: `Fitment Masivo por Marca/Modelo/Años`
3. SQL:

```sql
INSERT INTO vehicle_parts (model_year_engine_id, part_id, quantity_required, id_position_part)
SELECT mye.id_mye, {{part_id}}, {{quantity_required}}, {{id_position_part}}
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id_model
JOIN brands b ON m.brand_id = b.id_brand
JOIN years y ON mye.year_id = y.id_year
WHERE b.name_brand ILIKE {{marca}}
  AND m.name_model ILIKE {{modelo}}
  AND y.year_car BETWEEN {{year_from}} AND {{year_to}}
ON CONFLICT DO NOTHING
```

| Variable | Label | Tipo | Requerido |
|----------|-------|------|-----------|
| `part_id` | ID Pieza | number | Si |
| `marca` | Marca (ej: TOYOTA) | string | Si |
| `modelo` | Modelo (ej: Camry) | string | Si |
| `year_from` | Año desde | number | Si |
| `year_to` | Año hasta | number | Si |
| `quantity_required` | Cantidad | number | Si |
| `id_position_part` | Posición (1=front, 2=rear, vacío=N/A) | number | No |

---

### Action 4: Nueva Pieza Aftermarket

1. En el modelo **Aftermarket** → **New action**
2. Nombrar: `Alta de Pieza Aftermarket`
3. SQL:

```sql
INSERT INTO aftermarket_parts (
    oem_part_id,
    manufacturer_id,
    part_number,
    name_aftermarket_parts,
    name_es,
    id_quality_tier,
    price_usd,
    warranty_months
) VALUES (
    {{oem_part_id}},
    {{manufacturer_id}},
    {{part_number}},
    {{name_aftermarket_parts}},
    {{name_es}},
    {{id_quality_tier}},
    {{price_usd}},
    {{warranty_months}}
)
```

| Variable | Label | Tipo | Requerido |
|----------|-------|------|-----------|
| `oem_part_id` | ID Pieza OEM | number | Si |
| `manufacturer_id` | ID Fabricante | number | Si |
| `part_number` | Número Aftermarket | string | Si |
| `name_aftermarket_parts` | Nombre (EN) | string | No |
| `name_es` | Nombre (ES) | string | No |
| `id_quality_tier` | Calidad (1=economy, 2=oem, 3=premium, 4=standard) | number | No |
| `price_usd` | Precio USD | number | No |
| `warranty_months` | Garantía (meses) | number | No |

> **Tip:** Pregunta auxiliar para fabricantes:
> ```sql
> SELECT id_manufacture AS id, name_manufacture AS fabricante
> FROM manufacturers ORDER BY name_manufacture
> ```

---

### Action 5: Nueva Cross-Reference

1. En el modelo **Cross-References** → **New action**
2. Nombrar: `Alta de Cross-Reference`
3. SQL:

```sql
INSERT INTO part_cross_references (
    part_id,
    cross_reference_number,
    id_ref_type,
    source_ref,
    notes
) VALUES (
    {{part_id}},
    {{cross_reference_number}},
    {{id_ref_type}},
    {{source_ref}},
    {{notes}}
)
```

| Variable | Label | Tipo | Requerido |
|----------|-------|------|-----------|
| `part_id` | ID Pieza OEM | number | Si |
| `cross_reference_number` | Número de Referencia | string | Si |
| `id_ref_type` | Tipo (1=competitor, 2=interchange, 3=oem_alternate, 4=supersession) | number | No |
| `source_ref` | Fuente | string | No |
| `notes` | Notas | string | No |

---

## 3. Dashboard de Carga de Datos

Crear un **Dashboard** que agrupe todo el flujo de carga:

1. **New** → **Dashboard** → Nombrar: `Panel de Carga de Datos`
2. Agregar estas tarjetas:

### Fila 1: Consulta rápida
- **Buscar Pieza** (pregunta con filtro `{{oem_number}}`)
- **Buscar Vehículo** (pregunta con filtros `{{marca}}`, `{{modelo}}`)

### Fila 2: Botones de Actions
- **+ Nueva Pieza OEM** → Action 1
- **+ Nuevo Fitment** → Action 2
- **+ Fitment Masivo** → Action 3
- **+ Aftermarket** → Action 4
- **+ Cross-Reference** → Action 5

### Fila 3: Referencias
- **Tabla de Grupos** (grupos con IDs para referencia)
- **Tabla de Fabricantes** (fabricantes con IDs)
- **Estadísticas** (conteos actuales)

### Fila 4: Últimos registros
- **Últimas piezas cargadas**:
  ```sql
  SELECT oem_part_number, name_part, name_es, created_at
  FROM parts ORDER BY created_at DESC LIMIT 10
  ```
- **Últimos fitments**:
  ```sql
  SELECT b.name_brand, m.name_model, y.year_car, p.oem_part_number, vp.created_at
  FROM vehicle_parts vp
  JOIN model_year_engine mye ON vp.model_year_engine_id = mye.id_mye
  JOIN models m ON mye.model_id = m.id_model
  JOIN brands b ON m.brand_id = b.id_brand
  JOIN years y ON mye.year_id = y.id_year
  JOIN parts p ON vp.part_id = p.id_part
  ORDER BY vp.created_at DESC LIMIT 10
  ```

---

## 4. Flujo de Trabajo Recomendado

### Para cargar una pieza nueva con todo su contexto:

```
1. Abrir "Panel de Carga de Datos"

2. Click [+ Nueva Pieza OEM]
   → Llenar: OEM#, Nombre, Grupo, Descripción
   → Submit → Anotar el ID generado

3. Click [+ Fitment Masivo]
   → Ingresar: ID pieza, Marca, Modelo, Rango de años
   → Submit → La pieza queda vinculada a todos los vehículos

4. Click [+ Aftermarket] (repetir por cada fabricante)
   → Ingresar: ID pieza OEM, ID fabricante, # aftermarket, precio
   → Submit

5. Click [+ Cross-Reference] (repetir por cada referencia)
   → Ingresar: ID pieza, # referencia, tipo
   → Submit

6. Verificar en "Últimos registros" que todo se cargó
```

---

## 5. Preguntas Auxiliares Importantes

Guardar estas como preguntas para tener a mano durante la carga:

### Buscar pieza por número
```sql
SELECT id_part, oem_part_number, name_part, name_es
FROM parts
WHERE oem_part_number ILIKE {{'%' || numero || '%'}}
   OR name_part ILIKE {{'%' || numero || '%'}}
ORDER BY oem_part_number
LIMIT 50
```

### Buscar vehículo por marca/modelo
```sql
SELECT mye.id_mye, b.name_brand, m.name_model, y.year_car, e.name_engine
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id_model
JOIN brands b ON m.brand_id = b.id_brand
JOIN years y ON mye.year_id = y.id_year
JOIN engines e ON mye.engine_id = e.id_engine
WHERE b.name_brand ILIKE {{'%' || marca || '%'}}
  AND m.name_model ILIKE {{'%' || modelo || '%'}}
ORDER BY y.year_car DESC
LIMIT 100
```

### Catálogo de grupos (referencia para group_id)
```sql
SELECT pg.id_part_group AS id, pg.name_part_group AS grupo,
       pc.name_part_category AS categoria
FROM part_groups pg
JOIN part_categories pc ON pg.category_id = pc.id_part_category
ORDER BY pc.display_order, pg.display_order
```

### Catálogo de fabricantes (referencia para manufacturer_id)
```sql
SELECT m.id_manufacture AS id, m.name_manufacture AS fabricante,
       mt.name_type_manu AS tipo, qt.name_quality AS calidad
FROM manufacturers m
LEFT JOIN manufacture_type mt ON m.id_type_manu = mt.id_type_manu
LEFT JOIN quality_tier qt ON m.id_quality_tier = qt.id_quality_tier
ORDER BY m.name_manufacture
```

---

## 6. IDs de Referencia Rápida

### Calidad (`id_quality_tier`)
| ID | Valor |
|----|-------|
| 1 | economy |
| 2 | oem |
| 3 | premium |
| 4 | standard |

### Tipo de referencia (`id_ref_type`)
| ID | Valor | Uso |
|----|-------|-----|
| 1 | competitor | Número de competidor equivalente |
| 2 | interchange | Intercambio directo compatible |
| 3 | oem_alternate | Número OEM alterno |
| 4 | supersession | Pieza que esta reemplaza |

### Posición (`id_position_part`)
| ID | Valor |
|----|-------|
| 1 | front |
| 2 | rear |

### Tipo de fabricante (`id_type_manu`)
| ID | Valor |
|----|-------|
| 1 | aftermarket |
| 2 | oem |
