# DfProforma Shopware — Preventivi pro forma con accettazione cliente e auto-conversione

> Cosa fa DfProforma Shopware 6.7 sa emettere fatture, DDT e note di credito — ma non preventivi pro forma. Eppure, in quasi tutti i contesti B2B (attrezzature industriali, servizi alle…

- Pagina: <https://www.datafirefly.com/it/documentation/dfproforma-shopware-preventivo-proforma/>
- Lingua: it
- Aggiornato il: 2026-07-01
- Altre lingue: [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), [es](https://www.datafirefly.com/es/documentation/dfproforma-shopware-presupuesto-proforma/index.md), [de](https://www.datafirefly.com/de/documentation/dfproforma-shopware-proforma-angebot/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)
- Indice: <https://www.datafirefly.com/it/documentation/llms.txt>

## Cosa fa DfProforma

Shopware 6.7 sa emettere fatture, DDT e note di credito — ma non preventivi pro forma. Eppure, in quasi tutti i contesti B2B (attrezzature industriali, servizi alle aziende, appalti pubblici, vendite per gara d'appalto), il cliente deve ricevere un documento formale che accetta _prima_ che l'ordine diventi vincolante.

DfProforma colma questa lacuna senza espedienti: un vero tipo di documento Shopware nativo `df_proforma`, un proprio range di numerazione `PF{n}`, un template PDF Twig brandizzato, un workflow di accettazione cliente autonomo con URL pubblica firmata HMAC-SHA256, e una conversione automatica in ordine vincolante non appena la transazione sottostante passa allo stato pagato.

**In sintesi:** il commerciale genera un preventivo dalla scheda ordine nell'admin, lo invia via email, il cliente clicca sul link, accetta online senza account Shopware, paga, e il preventivo passa automaticamente allo stato _Convertito_. Nessun clic manuale post-pagamento.

## Requisiti

- **Shopware** 6.7.0 o superiore (il plugin non è retrocompatibile con 6.6 a causa del refactoring del sistema di documenti)
- **PHP** 8.2 minimo
- **MySQL** 8.0+ o **MariaDB** 10.6+
- Message worker Shopware attivi (raccomandato per la gestione automatica delle scadenze)
- Mail Service Shopware configurato (SMTP funzionante per gli invii transazionali)

## Installazione

### 1. Caricare il plugin

Dall'amministrazione Shopware, andate in _Estensioni → Le mie estensioni → Carica estensione_, e selezionate il file `DfProforma-1.0.6.zip`.

### 2. Installare e attivare

Nell'elenco delle estensioni, cliccate _Installa_ e poi _Attiva_. Le migrazioni Shopware si eseguono automaticamente e creano:

- La tabella SQL `df_proforma` con i suoi indici su `order_id`, `status`, `public_token`
- Il tipo di documento `df_proforma` in `document_type`
- Il range di numerazione `document_df_proforma` nel formato `PF{n}` configurabile
- Il template email transazionale base per generazione, invio e accettazione

### 3. Ricompilare l'amministrazione

Il plugin fornisce un modulo Vite admin che estende la scheda ordine (`sw-order-detail-base`). Bisogna ricompilare il bundle di amministrazione globale affinché il tab _Pro forma_ appaia:

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

**Saltare questo passo** è la causa principale di "il tab Pro forma non appare sulla scheda ordine" — ricordate di ricompilare dopo ogni aggiornamento del plugin.

## Configurazione

### Impostazioni globali

Da _Estensioni → Le mie estensioni → DfProforma → Configura_, accedete alle seguenti impostazioni:

- **Validità di default** — Numero di giorni durante i quali il link di accettazione rimane valido (30 di default). Ogni preventivo può sovrascrivere questo valore individualmente.
- **Auto-conversione al pagamento** — Attivata di default. Disattivatela se volete conservare il controllo manuale della transizione _Accettato → Convertito_.
- **Nome del mittente** — Nome mostrato come mittente delle email transazionali (di default: il nome del sales-channel).
- **Colore brand del PDF** — Colore accento utilizzato nel template PDF fornito (banda di intestazione, linea di separazione, badge di stato).

### Configurazione per sales-channel

Le impostazioni sopra possono essere sovrascritte per sales-channel in _Impostazioni → Sales channels → [vostro canale] → Configurazione plugin_. Utile se gestite più shop con politiche di validità diverse (per esempio 30 giorni per B2C, 60 giorni per B2B).

## Generare un preventivo pro forma

### Dalla scheda ordine (admin)

1. Aprite un ordine in _Ordini → Panoramica_
2. Cliccate sul tab _Pro forma_ (accanto a _Documenti_)
3. Cliccate _Genera preventivo pro forma_
4. Il PDF viene creato, il preventivo appare nell'elenco con un numero `PF-…` e lo stato _Bozza_

### Dall'API admin

Vengono esposti tre endpoint per integrare la generazione nei vostri flussi esterni:

```
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}
```

Autenticazione OAuth2 admin standard di Shopware. Utile per collegare DfProforma a un CRM esterno o a una pipeline di automazione.

## Inviare un preventivo al cliente

### Email transazionale

Dall'elenco dei preventivi (tab Pro forma della scheda ordine), cliccate sull'icona busta accanto al preventivo. Il modulo:

1. Passa il preventivo allo stato _Inviato_ (con timestamp)
2. Invia un'email al cliente via il Mail Service Shopware, usando il template `df_proforma_sent`, nella lingua del sales-channel
3. Allega il PDF del preventivo e include l'URL pubblica di accettazione
4. Emette l'evento `ProformaGeneratedEvent` (trigger Flow Builder)

### URL pubblica di accettazione

Ogni preventivo inviato porta un URL della forma:

```
https://vostro-shop.com/proforma/accept/{token}
```

Il token è cifrato e firmato con HMAC-SHA256 usando la chiave segreta di Shopware (`APP_SECRET` / `kernel.secret`). Impossibile da falsificare o indovinare. L'URL scade dopo la validità del preventivo (30 giorni di default).

## Pagina pubblica di accettazione cliente

Il cliente apre l'URL — **nessun account Shopware richiesto** (la pagina bypassa l'autenticazione standard dell'account cliente). Vede:

- Un riepilogo pulito dell'ordine: righe, prezzi, IVA, totali, condizioni
- Un pulsante principale _Accetta questo preventivo_
- Un pulsante secondario _Rifiuta con motivo_
- La validità mostrata ("Valido fino al 20/06/2026")

All'accettazione:

- Firma con timestamp al millisecondo e persistita in database
- Indirizzo IP del cliente persistito come prova
- Stato passa a _Accettato_ con la cronologia di transizione marcata
- Evento `ProformaAcceptedEvent` dispatchato a Flow Builder

In caso di rifiuto, il campo _Motivo_ è obbligatorio — utile per i vostri commerciali che possono ricontattare il cliente con una contro-proposta.

**Personalizzazione:** la pagina di accettazione usa i blocchi Twig standard dello Storefront ed eredita il vostro tema. Potete sovrascrivere `@DfProforma/storefront/page/account/proforma/quote.html.twig` dal vostro tema.

## Workflow di stati

Sei stati coprono l'intero ciclo di vita di un preventivo:

- **Bozza** — Preventivo creato ma non ancora inviato al cliente
- **Inviato** — Email inviata, in attesa di risposta cliente
- **Accettato** — Il cliente ha cliccato _Accetta_ sulla pagina pubblica
- **Rifiutato** — Il cliente ha cliccato _Rifiuta_ con motivo
- **Scaduto** — Validità superata senza risposta (transizione automatica via scheduled task)
- **Convertito** — Ordine sottostante pagato, conversione automatica

Ogni transizione viene persistita con timestamp al secondo, identificatore dell'attore, tipo di trigger (_commerciale_, _cliente_, _sistema_, _pagamento_) e payload JSON per metadati liberi. Potete ricostruire in qualsiasi momento la cronologia esatta di un preventivo.

## Auto-conversione al pagamento

Il modulo registra un Subscriber sull'evento `order_transaction.state.paid` della macchina a stati di Shopware. Quando una transazione passa a _pagata_ (Stripe, bonifico, PayPal ecc.), il Subscriber:

1. Cerca tutti i preventivi pro forma in stato _Accettato_ collegati all'ordine
2. Li passa allo stato _Convertito_
3. Marca la cronologia di transizione con tipo di trigger _pagamento_

Nessun intervento umano, nessun cron, nessun ritardo. I vostri report commerciali rimangono coerenti senza sforzo.

Per disattivare l'auto-conversione (se il vostro team preferisce il controllo manuale), deselezionate l'opzione in _Configurazione plugin → Auto-conversione al pagamento_.

## Flow Builder — eventi Business Event

Il modulo emette due eventi standard Shopware Business Event:

- `ProformaGeneratedEvent` — Alla generazione di un preventivo (implementa `BusinessEventInterface`)
- `ProformaAcceptedEvent` — All'accettazione del cliente (implementa `BusinessEventInterface`)

Entrambi appaiono automaticamente nell'elenco dei trigger del Flow Builder Shopware nativo. Potete collegare qualsiasi azione Flow:

- Notifica Slack al team vendite all'accettazione
- Email riepilogo interno al commerciale responsabile
- Webhook al vostro CRM (HubSpot, Salesforce, Pipedrive…)
- Aggiornamento di campo personalizzato sul cliente (per esempio, tag `quote-accepted`)
- Notifica push mobile via un servizio di terze parti

Nessun intervento nel codice del modulo necessario — tutto passa per l'admin Shopware.

## Personalizzazione del template PDF

Il PDF del preventivo viene renderizzato tramite `DocumentFileRendererRegistry` (il nuovo sistema di rendering di file di Shopware 6.7), a partire dal template Twig `@DfProforma/documents/proforma.html.twig` fornito nel modulo.

Per personalizzarlo, create un plugin personalizzato o sovrascrivetelo dal vostro tema rispettando la gerarchia standard dei template Twig di Shopware:

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

Il template fornito espone questi blocchi Twig identificati:

- Intestazione con logo e dati aziendali
- Blocco cliente
- Riepilogo delle righe ordine
- Totali HT/TTC con scomposizione IVA
- Banda di riepilogo in fondo (numero PF, date di emissione e scadenza)
- Filigrana _PRO FORMA_
- Colore brand configurabile via `config.accentColor`

Variabili disponibili nel template: `order` (OrderEntity caricata con tutte le sue associazioni), `config` (configurazione del documento incluso `documentNumber`, `documentDate`, `validUntil`, `validityDays`), `context`.

## Multilingua

FR, EN, DE ed ES sono forniti di default, snippet storefront e admin. Per aggiungere altre lingue, create un file di snippet per locale in `src/Resources/snippet/` seguendo la convenzione standard di Shopware.

I template email transazionali sono anch'essi multilingua: il template corretto viene selezionato automaticamente in base alla lingua del sales-channel del cliente al momento dell'invio. Potete personalizzare i template per lingua da _Impostazioni → Shop → Template email_.

## API — endpoint admin disponibili

```
POST   /api/_action/df-proforma/generate         # Genera un preventivo per un ordine
POST   /api/_action/df-proforma/mark-sent        # Marca come inviato (transizione manuale)
GET    /api/_action/df-proforma/by-order/{id}    # Elenca i preventivi di un ordine
```

Le entità `df_proforma` sono anche accessibili tramite l'API DAL standard Shopware (`/api/df-proforma`) per ricerche, esportazioni o integrazioni avanzate.

## Disinstallazione

Di default, i dati di business vengono conservati alla disinstallazione (opzione _Keep User Data_ attivata). Preservate così la cronologia di audit dei preventivi emessi, utile per conformità e tracciabilità commerciale.

Per forzare la rimozione completa (tabella `df_proforma`, tipo di documento, range di numerazione, template email), disattivate l'opzione _Keep User Data_ nel prompt di disinstallazione.

**Raccomandazione:** mantenete i dati di default. Forzate la rimozione solo se siete certi di non avere mai più bisogno di accedere alla cronologia dei preventivi per ragioni commerciali, contabili o legali.

## Risoluzione dei problemi

### Il tab Pro forma non appare sulla scheda ordine

Il bundle di amministrazione non è stato ricompilato dopo l'installazione. Eseguite `bin/build-administration.sh` e poi `bin/console cache:clear`.

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

Il tag di servizio del renderer non è corretto — questo bug è stato corretto dalla 1.0.2. Assicuratevi di usare una versione del plugin ≥ 1.0.2.

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

Causa storica: vecchia firma del costruttore `RenderedDocument`. Corretto in 1.0.4. Aggiornate alla 1.0.6.

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

Corretto in 1.0.6 — il template è stato adattato per non consumare due volte un generatore proveniente da `|filter()`.

### Il cliente riceve l'email ma l'URL di accettazione restituisce un 404

Verificate che il sales-channel Storefront sia correttamente registrato come dominio del canale di vendita utilizzato per l'ordine. La rotta pubblica `/proforma/accept/{token}` è registrata sullo Storefront — non funziona se accedete all'URL tramite il dominio admin.

### La scadenza automatica non funziona

Verificate che i _message worker_ di Shopware siano in esecuzione in background (`bin/console messenger:consume` o tramite un supervisore tipo systemd/supervisord). La scadenza passa dalla coda di messaggi Shopware standard.

## Supporto e aggiornamenti

12 mesi di aggiornamenti inclusi (compatibilità Shopware, correzioni di bug, aggiunte funzionali minori). Supporto via email in francese e inglese entro 24 ore lavorative. Codice sorgente PHP consegnato in chiaro, conforme PSR-4, verificabile e modificabile.

Per qualsiasi domanda o segnalazione: [contact@datafirefly.com](https://www.datafirefly.com/contact/).
