# DfProforma Shopware — Presupuestos pro forma con aceptación del cliente y auto-conversión

> Qué hace DfProforma Shopware 6.7 sabe emitir facturas, albaranes y notas de crédito — pero no presupuestos pro forma. Y sin embargo, en prácticamente todos los contextos B2B (equipamiento industrial,…

- Página: <https://www.datafirefly.com/es/documentation/dfproforma-shopware-presupuesto-proforma/>
- Idioma: es
- Actualizado el: 2026-07-01
- Otros idiomas: [fr](https://www.datafirefly.com/documentation/dfproforma-devis-shopware/index.md), [en](https://www.datafirefly.com/en/documentation/dfproforma-shopware-pro-forma-quote/index.md), [de](https://www.datafirefly.com/de/documentation/dfproforma-shopware-proforma-angebot/index.md), [it](https://www.datafirefly.com/it/documentation/dfproforma-shopware-preventivo-proforma/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfproforma-devis-shopware/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfproforma-devis-shopware/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfproforma-devis-shopware/index.md)
- Índice: <https://www.datafirefly.com/es/documentation/llms.txt>

## Qué hace DfProforma

Shopware 6.7 sabe emitir facturas, albaranes y notas de crédito — pero no presupuestos pro forma. Y sin embargo, en prácticamente todos los contextos B2B (equipamiento industrial, servicios a empresas, compras públicas, ventas por licitación), el cliente debe recibir un documento formal que acepta _antes_ de que el pedido se vuelva firme.

DfProforma cubre esta carencia sin trucos: un verdadero tipo de documento Shopware nativo `df_proforma`, su propio rango de numeración `PF{n}`, una plantilla PDF Twig con marca, un flujo de aceptación del cliente autónomo con URL pública firmada HMAC-SHA256, y una conversión automática a pedido firme en cuanto la transacción subyacente pasa al estado pagado.

**En resumen:** el comercial genera un presupuesto desde la ficha del pedido en el admin, lo envía por email, el cliente hace clic en el enlace, acepta en línea sin cuenta Shopware, paga, y el presupuesto pasa automáticamente al estado _Convertido_. Sin clic manual tras el pago.

## Requisitos

- **Shopware** 6.7.0 o superior (el plugin no es retrocompatible con 6.6 debido a la refactorización del sistema de documentos)
- **PHP** 8.2 mínimo
- **MySQL** 8.0+ o **MariaDB** 10.6+
- Workers de mensajes Shopware activos (recomendado para la gestión automática de vencimientos)
- Mail Service Shopware configurado (SMTP funcional para envíos transaccionales)

## Instalación

### 1. Subir el plugin

Desde la administración de Shopware, vaya a _Extensiones → Mis extensiones → Subir extensión_, y seleccione el archivo `DfProforma-1.0.6.zip`.

### 2. Instalar y activar

En la lista de extensiones, haga clic en _Instalar_ y luego en _Activar_. Las migraciones de Shopware se ejecutan automáticamente y crean:

- La tabla SQL `df_proforma` con sus índices en `order_id`, `status`, `public_token`
- El tipo de documento `df_proforma` en `document_type`
- El rango de numeración `document_df_proforma` en formato `PF{n}` configurable
- La plantilla de email transaccional base para generación, envío y aceptación

### 3. Recompilar la administración

El plugin incluye un módulo Vite admin que extiende la ficha del pedido (`sw-order-detail-base`). Debe recompilar el bundle de administración global para que aparezca la pestaña _Pro forma_:

```
bin/build-administration.sh
bin/console cache:clear
```

**Omitir este paso** es la principal causa de "la pestaña Pro forma no aparece en la ficha del pedido" — recuerde recompilar tras cada actualización del plugin.

## Configuración

### Ajustes globales

Desde _Extensiones → Mis extensiones → DfProforma → Configurar_, accede a los siguientes ajustes:

- **Validez por defecto** — Número de días durante los cuales el enlace de aceptación sigue siendo válido (30 por defecto). Cada presupuesto puede sobrescribir este valor individualmente.
- **Auto-conversión al pago** — Activada por defecto. Desactívela si desea conservar el control manual de la transición _Aceptado → Convertido_.
- **Nombre del remitente** — Nombre mostrado como remitente de los emails transaccionales (por defecto: el nombre del sales-channel).
- **Acento de marca del PDF** — Color de acento utilizado en la plantilla PDF incluida (banda de cabecera, línea separadora, badge de estado).

### Configuración por sales-channel

Los ajustes anteriores pueden sobrescribirse por sales-channel en _Ajustes → Sales channels → [su canal] → Configuración del plugin_. Útil si gestiona varias tiendas con políticas de validez diferentes (por ejemplo 30 días para B2C, 60 días para B2B).

## Generar un presupuesto pro forma

### Desde la ficha del pedido (admin)

1. Abra un pedido en _Pedidos → Vista general_
2. Haga clic en la pestaña _Pro forma_ (junto a _Documentos_)
3. Haga clic en _Generar presupuesto pro forma_
4. Se crea el PDF, el presupuesto aparece en la lista con un número `PF-…` y el estado _Borrador_

### Desde el API admin

Se exponen tres endpoints para integrar la generación en sus flujos externos:

```
POST /api/_action/df-proforma/generate
Body: { "orderId": "…" }

POST /api/_action/df-proforma/mark-sent
Body: { "proformaId": "…" }

GET  /api/_action/df-proforma/by-order/{orderId}
```

Autenticación OAuth2 admin estándar de Shopware. Útil para conectar DfProforma con un CRM externo o un pipeline de automatización.

## Enviar un presupuesto al cliente

### Email transaccional

Desde la lista de presupuestos (pestaña Pro forma de la ficha del pedido), haga clic en el icono del sobre junto al presupuesto. El módulo:

1. Pasa el presupuesto al estado _Enviado_ (con marca de tiempo)
2. Envía un email al cliente vía el Mail Service Shopware, usando la plantilla `df_proforma_sent`, en el idioma del sales-channel
3. Adjunta el PDF del presupuesto e incluye la URL pública de aceptación
4. Emite el evento `ProformaGeneratedEvent` (disparador Flow Builder)

### URL pública de aceptación

Cada presupuesto enviado lleva una URL de la forma:

```
https://su-tienda.com/proforma/accept/{token}
```

El token está cifrado y firmado con HMAC-SHA256 usando la clave secreta de Shopware (`APP_SECRET` / `kernel.secret`). Imposible de falsificar o adivinar. La URL caduca tras la validez del presupuesto (30 días por defecto).

## Página pública de aceptación del cliente

El cliente abre la URL — **sin cuenta Shopware necesaria** (la página omite la autenticación estándar de cuenta de cliente). Ve:

- Un resumen limpio del pedido: líneas, precios, IVA, totales, condiciones
- Un botón principal _Aceptar este presupuesto_
- Un botón secundario _Rechazar con motivo_
- La validez mostrada ("Válido hasta el 20/06/2026")

En la aceptación:

- Firma con marca de tiempo al milisegundo y persistida en base de datos
- Dirección IP del cliente persistida como prueba
- Estado pasa a _Aceptado_ con historial de transición marcado
- Evento `ProformaAcceptedEvent` despachado a Flow Builder

En caso de rechazo, el campo _Motivo_ es obligatorio — útil para sus comerciales que pueden recontactar al cliente con una contrapropuesta.

**Personalización:** la página de aceptación usa los bloques Twig estándar del Storefront y hereda su tema. Puede sobreescribir `@DfProforma/storefront/page/account/proforma/quote.html.twig` desde su tema.

## Flujo de estados

Seis estados cubren todo el ciclo de vida de un presupuesto:

- **Borrador** — Presupuesto creado pero aún no enviado al cliente
- **Enviado** — Email enviado, esperando respuesta del cliente
- **Aceptado** — El cliente hizo clic en _Aceptar_ en la página pública
- **Rechazado** — El cliente hizo clic en _Rechazar_ con motivo
- **Caducado** — Validez superada sin respuesta (transición automática vía scheduled task)
- **Convertido** — Pedido subyacente pagado, conversión automática

Cada transición se persiste con marca de tiempo al segundo, identificador del actor, tipo de disparador (_comercial_, _cliente_, _sistema_, _pago_) y payload JSON para metadatos libres. Puede reconstruir el historial exacto de cualquier presupuesto en cualquier momento.

## Auto-conversión al pago

El módulo registra un Subscriber en el evento `order_transaction.state.paid` de la máquina de estados de Shopware. Cuando una transacción pasa a _pagada_ (Stripe, transferencia bancaria, PayPal, etc.), el Subscriber:

1. Busca todos los presupuestos pro forma en estado _Aceptado_ vinculados al pedido
2. Los pasa al estado _Convertido_
3. Marca el historial de transición con tipo de disparador _pago_

Sin intervención humana, sin cron, sin retraso. Sus informes comerciales se mantienen consistentes sin esfuerzo.

Para desactivar la auto-conversión (si su equipo prefiere control manual), desmarque la opción en _Configuración del plugin → Auto-conversión al pago_.

## Flow Builder — eventos Business Event

El módulo emite dos eventos estándar Shopware Business Event:

- `ProformaGeneratedEvent` — Al generar un presupuesto (implementa `BusinessEventInterface`)
- `ProformaAcceptedEvent` — A la aceptación del cliente (implementa `BusinessEventInterface`)

Ambos aparecen automáticamente en la lista de disparadores del Flow Builder Shopware nativo. Puede conectar cualquier acción Flow:

- Notificación Slack al equipo de ventas al aceptar
- Email resumen interno al comercial responsable
- Webhook a su CRM (HubSpot, Salesforce, Pipedrive…)
- Actualización de campo personalizado en el cliente (por ejemplo, etiqueta `quote-accepted`)
- Notificación push móvil vía un servicio de terceros

Sin intervención en el código del módulo — todo se configura desde _Ajustes → Shop → Flow Builder_.

## Personalización de la plantilla PDF

El PDF del presupuesto se renderiza vía `DocumentFileRendererRegistry` (el nuevo sistema de renderizado de archivos de Shopware 6.7), a partir de la plantilla Twig `@DfProforma/documents/proforma.html.twig` incluida en el módulo.

Para personalizarla, cree un plugin personalizado o sobreescríbala desde su tema respetando la jerarquía estándar de plantillas Twig de Shopware:

```
custom/plugins/YourTheme/src/Resources/views/documents/proforma.html.twig
```

La plantilla incluida expone estos bloques Twig identificados:

- Cabecera con logo y datos de la empresa
- Bloque de cliente
- Resumen de líneas del pedido
- Totales HT/TTC con desglose de IVA
- Banda de resumen al pie (número PF, fechas de emisión y caducidad)
- Marca de agua _PRO FORMA_
- Acento de marca configurable vía `config.accentColor`

Variables disponibles en la plantilla: `order` (OrderEntity cargada con todas sus asociaciones), `config` (configuración del documento incluyendo `documentNumber`, `documentDate`, `validUntil`, `validityDays`), `context`.

## Multiidioma

FR, EN, DE y ES se incluyen por defecto, snippets de storefront y admin. Para añadir más idiomas, cree un archivo de snippets por locale en `src/Resources/snippet/` siguiendo la convención estándar de Shopware.

Las plantillas de email transaccionales también son multiidioma: la plantilla correcta se selecciona automáticamente según el idioma del sales-channel del cliente en el momento del envío. Puede personalizar las plantillas por idioma desde _Ajustes → Shop → Plantillas de email_.

## API — endpoints admin disponibles

```
POST   /api/_action/df-proforma/generate         # Genera un presupuesto para un pedido
POST   /api/_action/df-proforma/mark-sent        # Marca como enviado (transición manual)
GET    /api/_action/df-proforma/by-order/{id}    # Lista los presupuestos de un pedido
```

Las entidades `df_proforma` también son accesibles vía el API DAL estándar de Shopware (`/api/df-proforma`) para búsquedas, exportaciones o integraciones avanzadas.

## Desinstalación

Por defecto, los datos de negocio se conservan al desinstalar (opción _Keep User Data_ activada). Así preserva el historial de auditoría de los presupuestos emitidos, útil para conformidad y trazabilidad comercial.

Para forzar la eliminación completa (tabla `df_proforma`, tipo de documento, rango de numeración, plantilla de email), desactive la opción _Keep User Data_ en el prompt de desinstalación.

**Recomendación:** mantenga los datos por defecto. Solo fuerce la eliminación si está seguro de no necesitar nunca más acceder al historial de presupuestos por razones comerciales, contables o legales.

## Solución de problemas

### La pestaña Pro forma no aparece en la ficha del pedido

El bundle de administración no se recompiló tras la instalación. Ejecute `bin/build-administration.sh` y luego `bin/console cache:clear`.

### Error "Unable to find a document generator with type df_proforma"

El tag de servicio del renderer no es correcto — este bug se corrigió desde la 1.0.2. Asegúrese de usar una versión del plugin ≥ 1.0.2.

### Error "Call to undefined method Context::getSalesChannelId()"

Causa histórica: firma antigua del constructor `RenderedDocument`. Corregido en 1.0.4. Actualice a 1.0.6.

### Error Twig "Cannot rewind a generator that was already run"

Corregido en 1.0.6 — la plantilla se adaptó para no consumir dos veces un generador procedente de `|filter()`.

### El cliente recibe el email pero la URL de aceptación devuelve un 404

Verifique que el sales-channel Storefront esté correctamente registrado como dominio del canal de ventas utilizado para el pedido. La ruta pública `/proforma/accept/{token}` está registrada en el Storefront — no funciona si accede a la URL vía el dominio admin.

### La caducidad automática no funciona

Verifique que los _message workers_ de Shopware estén en ejecución en segundo plano (`bin/console messenger:consume` o vía un supervisor tipo systemd/supervisord). La caducidad pasa por la cola de mensajes estándar de Shopware.

## Soporte y actualizaciones

12 meses de actualizaciones incluidas (compatibilidad Shopware, correcciones de errores, adiciones funcionales menores). Soporte por email en francés e inglés en 24 horas laborables. Código fuente PHP entregado en texto plano, conforme PSR-4, auditable y modificable.

Para cualquier pregunta o incidencia: [contact@datafirefly.com](https://www.datafirefly.com/contact/).
