# Proveedores

El módulo `Proveedores`, dentro de `Gestión interna`, es el maestro único para
las empresas y profesionales a los que AnimalCharlie compra productos o
servicios. La ficha reúne identidad fiscal, contacto, clasificación,
condiciones de pago, documentación privada, compras y artículos suministrados.

## Flujo De Uso

1. Abrir `Gestión interna / Proveedores` y buscar por nombre, NIF/CIF,
   categoría o contacto.
2. Crear o abrir una ficha. `Nuevo proveedor` muestra una ficha vacía y
   `Guardar` conserva el registro sin mezclarlo con Clientes.
3. Usar `Documentos` para contratos, acuerdos, presupuestos, facturas,
   certificados, seguros, datos fiscales o bancarios.
4. Usar `Compras` para revisar facturas, tickets, mercancía, servicios, activos
   y gastos generales vinculados, o crear una compra nueva en Facturación con
   el proveedor ya seleccionado.
5. Usar `Inventario` para ver la referencia propia del proveedor, el artículo
   canónico, stock actual, último coste y unidades recibidas. Al pulsar una fila
   se abre el mismo artículo en `Facturación / Catálogo / Productos`.

El buscador del directorio permanece visible y filtra al instante por nombre,
NIF/CIF, categoría o contacto. `Filtros` abre el popover común con estado
—activos, pendientes de revisión, bloqueados o inactivos— y categoría; su
contador muestra cuántos criterios están activos y `Limpiar` restablece ambos
filtros sin borrar la búsqueda. Estos controles solo cambian el índice y no
activan el estado de cambios sin guardar de la ficha.

La carcasa es `master-detail`: empieza en el directorio y abre la ficha a todo
el ancho cuando se selecciona una fila. En PC puede usarse `Lista y ficha`; en
iPad Air vertical se alterna entre `Proveedores` y `Ficha`. No existe una vista
de teléfono soportada.

La ficha mantiene un estado real de cambios sin guardar. Si se intenta crear
otro proveedor, abrir otra fila o actualizar el directorio, se pide confirmación
antes de sustituir los campos actuales. Cancelar conserva íntegramente la ficha,
sus campos y la selección; aceptar descarta el borrador y continúa. La marca se
limpia después de una carga o un guardado confirmado. Archivar conserva su única
confirmación destructiva y no abre una segunda confirmación por el borrador.

## Datos Y Reglas

La tabla `suppliers` guarda razón social, nombre comercial, NIF/CIF
normalizado, tipo, estado, categoría, referencia, contacto, dirección, forma y
plazo de pago, cuenta bancaria, IVA por defecto, etiquetas y notas internas.

- La razón social es obligatoria.
- Un NIF/CIF normalizado no puede repetirse.
- Archivar conserva documentos, compras y movimientos históricos.
- Un proveedor archivado, bloqueado o inactivo no puede asociarse a una compra nueva.
- Los datos bancarios, fiscales, contractuales y las notas son información
  interna sensible.

## Expediente Documental

`supplier_documents` relaciona cada documento con una entrada privada de
`evidence` usando `entity_type='supplier'`. El archivo nunca se publica como
URL estática: descarga y borrado pasan por endpoints autenticados y permisos de
Proveedores. Se conservan título, tipo, referencia, vigencia, notas, autor y
metadatos del archivo.

Cada fila ofrece `Vista previa` cuando el formato puede abrirse de forma segura,
además de la descarga explícita. PDF e imágenes raster conservan su
representación visual; TXT, CSV, Markdown, JSON, DOCX y XLSX usan el extractor
existente y abren una vista de texto identificada como tal. DOC, XLS, SVG, HTML
y formatos sin extractor mantienen únicamente `Descargar`: nunca se entrega
contenido activo declarado por el fichero como una página del ERP.

Endpoints:

- `POST /api/suppliers/{id}/documents`
- `GET /api/suppliers/{id}/documents/{documentId}`
- `GET /api/suppliers/{id}/documents/{documentId}/preview`
- `DELETE /api/suppliers/{id}/documents/{documentId}`

## Relación Con Facturación

`billing_expenses.supplier_id` enlaza cada compra con la ficha maestra y es
obligatorio para cualquier alta o edición nueva. El campo de texto `supplier`
se mantiene como instantánea del nombre para poder seguir leyendo registros
históricos anteriores al maestro, pero ya no autoriza guardar proveedor libre.

En `Facturación / Gastos`, el selector permite:

- elegir una sugerencia existente, conservar su ID y aplicar categoría, forma
  de pago, IVA y vencimiento por defecto al alta;
- usar `Alta proveedor` cuando el nombre aún no existe: abre la ficha de
  Proveedores con la razón social escrita para terminar un alta manual;
- después de `Leer factura o ticket`, mostrar en azul el proveedor que Charlie
  ha identificado pero no existe exactamente en el maestro y ofrecer `Aceptar
  alta automática` sin abandonar el gasto.

El botón cambia a `Abrir ficha` cuando el texto coincide con un proveedor real.
Al cambiar manualmente el nombre se elimina el ID anterior para evitar
relaciones incorrectas; el backend también rechaza una compra sin `supplier_id`.

## Alta Asistida Desde Factura

`Aceptar alta automática` abre un único popup de revisión, sin pasos. A la
izquierda presenta una ficha editable con razón social, nombre comercial,
NIF/CIF, tipo, categoría, contacto, email, teléfono, web, dirección, localidad,
provincia, código postal, país, pago, plazo, IVA, IBAN y notas. Cada dato indica
si procede de la `Factura`, de `VIES` o de una corrección `Revisada` por el
usuario. Charlie y Hermes solo proponen: el proveedor nunca se crea de forma
silenciosa.

A la derecha se separan dos comprobaciones:

- `VIES · Comisión Europea`: el backend envía únicamente país y NIF-IVA al
  registro oficial. La factura, su texto y sus imágenes no salen a internet.
  Un resultado negativo significa que no consta como operador intracomunitario;
  no afirma que la empresa nacional no exista. Si VIES no responde, el alta
  sigue disponible y la UI muestra la degradación.
- `Existentes y similares`: se comparan NIF/CIF, razón social, nombre
  comercial, web, correo, teléfono, dirección y localidad. Una coincidencia
  puede seleccionarse con `Usar existente`; las fichas archivadas, bloqueadas o
  inactivas se abren para revisión, pero no se vinculan a una compra nueva.

El servidor repite la comparación al confirmar. Un NIF/CIF exacto reutiliza la
ficha existente incluso si se pulsó crear. Cuando solo hay nombres o datos muy
similares, la primera petición devuelve `review`; crear una ficha separada
requiere la confirmación explícita `Crear de todas formas`. La resolución queda
guardada en `source_extraction_json` junto al análisis de la factura.

Endpoints internos:

- `POST /api/suppliers/assisted-preview`: normaliza la propuesta, consulta VIES
  y devuelve coincidencias sin guardar nada.
- `POST /api/suppliers/assisted-create`: repite la detección de duplicados y
  crea, reutiliza o pide confirmación según el resultado.

Configuración opcional: `SUPPLIER_PUBLIC_LOOKUP_ENABLED=0` desactiva VIES y
`SUPPLIER_PUBLIC_LOOKUP_TIMEOUT` limita su espera en segundos. La URL del
registro oficial es fija en backend para evitar consultas arbitrarias o SSRF.

## Líneas De Compra E Inventario

El catálogo único sigue siendo `billing_products`: Proveedores no mantiene una
copia paralela. Las compras se desglosan en `billing_purchase_lines` con tipo
`goods`, `service`, `asset` o `general`, descripción, referencia del proveedor,
código de barras, cantidad, unidad, coste, IVA, descuento y tratamiento de
inventario.

`billing_product_supplier_refs` conserva los nombres y referencias que usa cada
proveedor para un artículo. Antes de proponer un alta, el servidor contrasta en
este orden:

1. referencia exacta del proveedor;
2. código de barras;
3. SKU;
4. nombre normalizado exacto o alias anterior del proveedor;
5. similitud alta y no ambigua con el catálogo existente.

Hermes/GPT solo prepara la propuesta. Al guardar, el backend repite el
contraste y puede sustituir un ID incorrecto por la coincidencia acreditada. Si
no existe una coincidencia fiable y la línea requiere inventario, el guardado
confirma el alta en `billing_products` y crea la referencia del proveedor.
Servicios y gastos generales nunca incrementan stock.

Las entradas se registran en `billing_inventory_movements`. Editar una compra
retira primero sus movimientos anteriores y aplica las líneas revisadas dentro
de la misma transacción, por lo que no acumula stock dos veces. Anular la compra
genera contramovimientos, revierte sus unidades y deja
`inventory_status='reversed'`; las líneas y la pareja entrada/reversión se
conservan como trazabilidad.

## Charlie Y Hermes

El especialista estable es `hermes-module-suppliers` y su MCP es
`animal-charlie.suppliers`. Recibe el proveedor activo como entidad
`supplier`, puede resumir datos, documentos, compras, artículos suministrados,
stock y pendiente. Para documentos de compra, `hermes-module-billing` usa el
Hermes local con el modelo GPT configurado, extrae líneas y propone
coincidencias sin guardar nada. Ambos agentes deben tratar datos fiscales,
bancarios y contractuales como sensibles; las escrituras continúan requiriendo
revisión y confirmación visible.

## Permisos

- Lectura: `suppliers.read` o `suppliers.write`.
- Escritura, archivo y documentos: `suppliers.write`.
- Los perfiles técnicos incluyen ambos permisos por defecto.
- Los gastos siguen requiriendo `billing.write`.

## Verificación

El cambio se valida con `tools/verify_suppliers_workflow.py`,
`tools/verify_purchase_inventory_workflow.py` y
`tools/verify_suppliers_controller.js`, además del contrato de navegación
común, la matriz de acceso por rol y la matriz Charlie V2. Las pruebas visuales
cubren PC, Galaxy Tab A9+, iPad Air apaisado e iPad Air vertical y guardan su
evidencia fuera del repositorio.
