A diferencia de otros módulos, acá **no hay un componente por tipo de socio**: `BusinessPartnerForm.tsx` es un único formulario genérico parametrizado por props, y `Customers.tsx` / `Suppliers.tsx` son wrappers finos que solo le pasan configuración distinta:
| `extraFields` | `[]` (sin campos extra hoy) | `U_EXX_TIPODOCU` (Tipo de Documento SUNAT, select) |
La diferenciación entre "es cliente" o "es proveedor" para el propio dato de SAP la hace el campo `CardType` (`cCustomer` / `cSupplier`), que viaja fijo en el `body` del POST/PATCH según qué wrapper se use — el formulario en sí no lo deja editar.
El mecanismo `extraFields` (tipo `ExtraFieldConfig[]`, definido en `BusinessPartnerForm.tsx`) permite agregar campos exclusivos de un tipo de socio sin tocar el formulario base: cada entrada define `name`, `label`, `type` (`text` | `email` | `select`), y opcionalmente `loadOptions` (una función async que trae las opciones del backend). Hoy el único caso real es el campo `U_EXX_TIPODOCU` en Proveedores, que carga sus opciones desde `GET /api/Sunat/BusinessPartners/DocumentType` (catálogo SUNAT expuesto vía SAP).
## Flujo Vista de Lista → Editar Socio (caso Clientes)
```mermaid
sequenceDiagram
actor User as Usuario
participant Router as App.tsx
participant ListView as CustomersList
participant LVT as ListViewTemplate
participant DTable as DenseTable
participant DetailView as Customers.tsx
participant Form as BusinessPartnerForm
participant API as api.ts
participant Backend as backend business_partners.py
Form->>Form: setFormData(data) — sin mapeo de nombres, usa los campos SAP tal cual
Form-->>User: formulario con pestañas "General" / "Direcciones"
User->>Form: edita campos y clic "Actualizar Cliente"
Form->>API: PATCH /api/BusinessPartners/C00001
Note over Form,API: body: {CardName, FederalTaxID, Phone1, EmailAddress, BPAddresses[], ...extraFields}
API->>Backend: fetch PATCH
Backend->>SAP: PATCH BusinessPartners('C00001')
SAP-->>Backend: 204 No Content
Backend-->>API: 204
API-->>Form: ok
Form-->>User: "Cliente actualizado correctamente"
```
El flujo de Proveedores es idéntico, cambiando el `baseFilter` a `CardType eq 'cSupplier'` en `SuppliersList.tsx` y usando `Suppliers.tsx` como vista de detalle.
Para un socio **nuevo** (`isEditMode = false`), el submit hace `POST /api/BusinessPartners` en vez de `PATCH`, y tras la respuesta exitosa navega de vuelta al listado (`listPath`) después de 1.5s.
A diferencia del módulo de Lotes, acá **no hay mapeo de nombres SAP → amigable**: el formulario usa los nombres de campo de SAP directamente como `name` de cada input (`CardCode`, `CardName`, `FederalTaxID`, `Phone1`, `EmailAddress`). El label visible sí es un texto amigable en español; el nombre técnico SAP se muestra en un tooltip (ícono ⓘ, componente `FieldTooltip.tsx`) en vez de ir concatenado al label.