# DfProforma Shopware: faturas pro forma com aceitação do cliente e conversão automática

> O que faz o DfProforma O Shopware 6.7 sabe emitir faturas, guias de remessa e notas de crédito, mas não faturas pro forma. Ora, na quase totalidade dos contextos B2B…

- Página: <https://www.datafirefly.com/pt/documentation/dfproforma-devis-shopware/>
- Idioma: pt
- Atualizado em: 2026-09-02
- Outros 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), [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), [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)
- Índice: <https://www.datafirefly.com/pt/documentation/llms.txt>

## O que faz o DfProforma

O Shopware 6.7 sabe emitir faturas, guias de remessa e notas de crédito, mas não faturas pro forma. Ora, na quase totalidade dos contextos B2B (equipamento industrial, serviços a empresas, compras públicas, vendas por concurso), o cliente tem de receber um documento formal que aceita _antes_ de a encomenda se tornar firme.

O DfProforma preenche essa lacuna sem improvisos: um verdadeiro tipo de documento nativo do Shopware `df_proforma`, o seu próprio intervalo de numeração `PF{n}`, o seu template de PDF em Twig com a sua marca, um fluxo de aceitação pelo cliente autónomo com URL público assinado com HMAC-SHA256, e uma conversão automática em encomenda assim que a transação subjacente passa ao estado pago.

**Em resumo:** o comercial gera uma pro forma a partir da ficha da encomenda na administração, envia-a por email, o cliente clica na ligação, aceita online sem conta Shopware, paga, e a pro forma passa automaticamente ao estado _Convertida_. Sem cliques manuais depois do pagamento.

## Pré-requisitos

- **Shopware** 6.7.0 ou superior (a extensão não é retrocompatível com a 6.6 devido às refundições do sistema de documentos)
- **PHP** 8.2 no mínimo
- **MySQL** 8.0+ ou **MariaDB** 10.6+
- Workers de mensagens do Shopware ativos (recomendado para a gestão automática das expirações)
- Serviço de email do Shopware configurado (SMTP funcional para os envios transacionais)

## Instalação

### 1. Carregar a extensão

Na administração do Shopware, vá a _Extensões → As minhas extensões → Carregar uma extensão_ e selecione o ficheiro `DfProforma-1.0.6.zip`.

### 2. Instalar e ativar

Na lista de extensões, clique em _Instalar_ e depois em _Ativar_. As migrações do Shopware executam-se automaticamente e criam:

- A tabela SQL `df_proforma` e os seus índices em `order_id`, `status`, `public_token`
- O tipo de documento `df_proforma` em `document_type`
- O intervalo de numeração `document_df_proforma` no formato `PF{n}`, configurável
- O template de email transacional de base para a geração, o envio e a aceitação

### 3. Recompilar a administração

A extensão fornece um módulo Vite de administração que estende a ficha da encomenda (`sw-order-detail-base`). É preciso recompilar o bundle global de administração para que o separador _Pro forma_ apareça:

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

**Esquecer este passo** é a primeira causa de «o separador Pro forma não aparece na ficha da encomenda»; lembre-se de recompilar depois de cada atualização da extensão.

## Configuração

### Definições globais

A partir de _Extensões → As minhas extensões → DfProforma → Configurar_, acede às seguintes definições:

- **Validade predefinida**: número de dias durante os quais a ligação de aceitação se mantém válida (30 por predefinição). Cada pro forma pode substituir este valor individualmente.
- **Conversão automática no recebimento**: ativa por predefinição. Desative-a se preferir manter o controlo manual da passagem _Aceite → Convertida_.
- **Nome do remetente**: nome apresentado como remetente dos emails transacionais (por predefinição: o nome do sales channel).
- **Cor de marca do PDF**: cor de destaque usada no template de PDF entregue (faixa de cabeçalho, linha de separação, selo de estado).

### Configuração por sales channel

As definições acima podem ser substituídas por sales channel em _Definições → Sales channels → [o seu canal] → Configuração da extensão_. Útil se gerir várias lojas com políticas de validade diferentes (por exemplo 30 dias para o B2C, 60 dias para o B2B).

## Gerar uma pro forma

### A partir da ficha da encomenda (administração)

1. Abra uma encomenda em _Encomendas → Visão geral_
2. Clique no separador _Pro forma_ (ao lado de _Documentos_)
3. Clique em _Gerar uma pro forma_
4. O PDF é criado, a pro forma aparece na lista com um número `PF-…` e o estado _Rascunho_

### A partir da Admin API

São expostos três endpoints para integrar a geração nos seus fluxos 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}
```

Autenticação OAuth2 normal da administração do Shopware. Útil para ligar o DfProforma a um CRM externo ou a um pipeline de automatização.

## Enviar uma pro forma ao cliente

### Email transacional

A partir da lista de pro formas (separador Pro forma da ficha da encomenda), clique no ícone de envelope ao lado da pro forma. O módulo:

1. Passa a pro forma ao estado _Enviada_ (com data e hora)
2. Envia um email ao cliente através do Mail Service do Shopware, usando o template `df_proforma_sent`, no idioma do sales channel
3. Anexa o PDF da pro forma e inclui o URL público de aceitação
4. Emite o evento `ProformaGeneratedEvent` (acionador do Flow Builder)

### URL público de aceitação

Cada pro forma enviada tem um URL do tipo:

```
https://a-sua-loja.com/proforma/accept/{token}
```

O token é cifrado e assinado com HMAC-SHA256 usando a chave secreta do Shopware (`APP_SECRET` / `kernel.secret`). Impossível de forjar ou de adivinhar. O URL expira ao fim da validade da pro forma (30 dias por predefinição).

## Página pública de aceitação pelo cliente

O cliente abre o URL, **sem necessidade de conta Shopware** (a página contorna a autenticação normal da conta de cliente). Vê:

- Um resumo limpo da encomenda: linhas, preços, IVA, totais, condições
- Um botão principal _Aceitar esta pro forma_
- Um botão secundário _Recusar com motivo_
- A validade apresentada («Válida até 20/06/2026»)

Na aceitação:

- Assinatura com data e hora ao milissegundo e guardada na base de dados
- Endereço IP do cliente guardado como prova
- O estado passa a _Aceite_ com o histórico de transição marcado
- Evento `ProformaAcceptedEvent` enviado ao Flow Builder

Em caso de recusa, o campo _Motivo_ é obrigatório, útil para os seus comerciais poderem voltar a contactar o cliente com uma contraproposta.

**Personalização:** a página de aceitação usa os blocos Twig normais do Storefront e herda o seu tema. Pode sobrepor `@DfProforma/storefront/page/account/proforma/quote.html.twig` a partir do seu tema.

## Fluxo de estados

Seis estados cobrem a totalidade do ciclo de vida de uma pro forma:

- **Rascunho**: pro forma criada mas ainda não enviada ao cliente
- **Enviada**: email enviado, à espera da resposta do cliente
- **Aceite**: o cliente clicou em _Aceitar_ na página pública
- **Recusada**: o cliente clicou em _Recusar_ com motivo
- **Expirada**: validade ultrapassada sem resposta (transição automática por scheduled task)
- **Convertida**: encomenda subjacente paga, conversão automática

Cada transição é guardada com data ao segundo, identificador do ator, tipo de acionamento (_comercial_, _cliente_, _sistema_, _pagamento_) e payload JSON para metadados livres. Pode reconstituir o histórico exato de uma pro forma a qualquer momento.

## Conversão automática no recebimento

O módulo regista um Subscriber no evento `order_transaction.state.paid` da máquina de estados do Shopware. Quando uma transação passa a _paga_ (Stripe, transferência, PayPal e outros), o Subscriber:

1. Procura todas as pro formas em estado _Aceite_ associadas à encomenda
2. Passa-as ao estado _Convertida_
3. Marca o histórico de transição com o tipo de acionamento _pagamento_

Sem intervenção humana, sem cron, sem atraso. Os seus relatórios comerciais mantêm-se coerentes sem esforço.

Para desativar a conversão automática (se a sua equipa preferir um controlo manual), desmarque a opção em _Configuração da extensão → Conversão automática no recebimento_.

## Flow Builder: eventos de negócio

O módulo emite dois eventos normais do Shopware:

- `ProformaGeneratedEvent`: na geração de uma pro forma (implementa a `BusinessEventInterface`)
- `ProformaAcceptedEvent`: na aceitação pelo cliente (implementa a `BusinessEventInterface`)

Ambos aparecem automaticamente na lista de acionadores do Flow Builder nativo do Shopware. Pode ligar-lhes qualquer ação do Flow:

- Notificação no Slack para a equipa de vendas na aceitação
- Email de resumo interno para o comercial responsável
- Webhook para o seu CRM (HubSpot, Salesforce, Pipedrive e outros)
- Atualização de um campo personalizado no cliente (por exemplo, etiqueta `quote-accepted`)
- Notificação push móvel através de um serviço de terceiros

Sem qualquer intervenção no código do módulo, tudo se configura a partir de _Definições → Loja → Flow Builder_.

## Personalização do template de PDF

O PDF da pro forma é renderizado através do `DocumentFileRendererRegistry` (o novo sistema de renderização de ficheiros do Shopware 6.7), a partir do template Twig `@DfProforma/documents/proforma.html.twig` entregue com o módulo.

Para o personalizar, crie uma extensão própria ou sobreponha-o a partir do seu tema respeitando a hierarquia normal de templates Twig do Shopware:

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

O template entregue expõe estes blocos Twig identificados:

- Cabeçalho com logotipo e dados da empresa
- Bloco do cliente
- Resumo das linhas de encomenda
- Totais com e sem IVA com repartição do IVA
- Faixa de resumo no rodapé (número PF, datas de emissão e de expiração)
- Marca de água _PRO FORMA_
- Cor de marca configurável através de `config.accentColor`

Variáveis disponíveis no template: `order` (OrderEntity carregada com todas as suas associações), `config` (configuração do documento, incluindo `documentNumber`, `documentDate`, `validUntil`, `validityDays`), `context`.

## Multilingue

FR, EN, DE e ES vêm por predefinição, com snippets de Storefront e de administração. Para acrescentar outros idiomas, crie um ficheiro de snippets por locale em `src/Resources/snippet/` seguindo a convenção normal do Shopware.

Os templates de email transacionais também são multilingues: o template certo é selecionado automaticamente segundo o idioma do sales channel do cliente no momento do envio. Pode personalizar os templates por idioma em _Definições → Loja → Modelos de email_.

## API: endpoints de administração disponíveis

```
POST   /api/_action/df-proforma/generate         # Gera uma pro forma para uma encomenda
POST   /api/_action/df-proforma/mark-sent        # Marca como enviada (transição manual)
GET    /api/_action/df-proforma/by-order/{id}    # Lista as pro formas de uma encomenda
```

As entidades `df_proforma` também estão acessíveis através da API DAL normal do Shopware (`/api/df-proforma`) para pesquisas, exportações ou integrações avançadas.

## Desinstalação

Por predefinição, os dados de negócio são conservados na desinstalação (opção _Keep User Data_ ativa). Preserva assim o histórico de auditoria das pro formas emitidas, útil para a conformidade e a rastreabilidade comercial.

Para forçar a eliminação completa (tabela `df_proforma`, tipo de documento, intervalo de numeração, template de email), desative a opção _Keep User Data_ no pedido de confirmação da desinstalação.

**Recomendação:** mantenha os dados por predefinição. Só force a eliminação se tiver a certeza de que nunca mais vai precisar do histórico das pro formas por razões comerciais, contabilísticas ou legais.

## Resolução de problemas

### O separador Pro forma não aparece na ficha da encomenda

O bundle de administração não foi recompilado depois da instalação. Execute `bin/build-administration.sh` e depois `bin/console cache:clear`.

### Erro «Unable to find a document generator with type df_proforma»

A tag de serviço do renderer não está correta; este erro está corrigido desde a 1.0.2. Confirme que usa uma versão ≥ 1.0.2 da extensão.

### Erro «Call to undefined method Context::getSalesChannelId()»

Causa histórica: antiga assinatura do construtor `RenderedDocument`. Corrigido na 1.0.4. Atualize para a 1.0.6.

### Erro Twig «Cannot rewind a generator that was already run»

Corrigido na 1.0.6: o template foi adaptado para não consumir duas vezes um gerador proveniente de `|filter()`.

### O cliente recebe o email mas o URL de aceitação devolve um erro 404

Verifique que o sales channel Storefront está mesmo registado como domínio do canal de venda usado para a encomenda. A rota pública `/proforma/accept/{token}` está registada no Storefront; não funciona se aceder ao URL pelo domínio de administração.

### A expiração automática não funciona

Verifique que os _message workers_ do Shopware estão a correr em segundo plano (`bin/console messenger:consume` ou através de um supervisor do tipo systemd/supervisord). A expiração passa pela fila de mensagens normal do Shopware.

## Suporte e atualizações

12 meses de atualizações incluídas (compatibilidade com o Shopware, correções de erros, pequenas adições funcionais). Suporte por email em francês e inglês em 24 horas úteis. Código-fonte PHP entregue em claro, conforme à PSR-4, auditável e modificável.

Para qualquer questão ou comunicação: [contact@datafirefly.com](https://www.datafirefly.com/pt/contacto/).
