# dffreegift: oferta acima de um limiar de carrinho, guia completo

> Guia completo do módulo dffreegift para PrestaShop 8 e 9: instalação, configuração, funcionamento interno (CartRule nativa), personalização, resolução de problemas e desinstalação. Todos os passos vêm acompanhados dos parâmetros exatos…

- Página: <https://www.datafirefly.com/pt/documentation/dffreegift/>
- Idioma: pt
- Atualizado em: 2026-09-02
- Outros idiomas: [fr](https://www.datafirefly.com/documentation/dffreegift/index.md), [en](https://www.datafirefly.com/en/documentation/dffreegift/index.md), [es](https://www.datafirefly.com/es/documentation/dffreegift/index.md), [de](https://www.datafirefly.com/de/documentation/dffreegift/index.md), [pl](https://www.datafirefly.com/pl/documentation/dffreegift/index.md), [it](https://www.datafirefly.com/it/documentation/dffreegift/index.md), [nl](https://www.datafirefly.com/nl/documentation/dffreegift/index.md)
- Índice: <https://www.datafirefly.com/pt/documentation/llms.txt>

Guia completo do módulo **dffreegift** para PrestaShop 8 e 9: instalação, configuração, funcionamento interno (CartRule nativa), personalização, resolução de problemas e desinstalação. Todos os passos vêm acompanhados dos parâmetros exatos a usar em produção.

## Visão geral

O dffreegift adiciona automaticamente um produto de oferta ao carrinho assim que um limiar configurado é atingido, e retira-o se o carrinho voltar a descer abaixo. A mecânica assenta integralmente no sistema nativo `CartRule` do PrestaShop (campo `gift_product`): o módulo nunca manipula diretamente os preços dos produtos, não cria nenhum `SpecificPrice` temporário e não injeta nada nos hooks de cálculo de preço. Resultado: compatibilidade completa com as suas outras promoções, códigos promocionais, impostos e multimoeda.

O módulo mostra também um **bloco de progresso** na página do carrinho com a mensagem « Adicione X € para receber a sua oferta », uma barra colorida que se enche à medida que o limiar se aproxima, e uma animação ao ultrapassá-lo.

**Loja em português.** As cadeias do front-office (« Adicione %amount% para receber a sua oferta », « Oferta adicionada ao seu carrinho! ») são fornecidas em francês e inglês. Traduza-as para português em Internacional → Traduções → Traduções dos módulos instalados (ver « Personalizar os textos »), caso contrário o cliente vê o inglês.

## Pré-requisitos

- PrestaShop 8.0 a 9.x (testado em 8.0, 8.1, 8.2, 9.0)
- PHP 8.1 no mínimo (8.2 e 8.3 suportados)
- Um produto ativo no seu catálogo que servirá de oferta (produto simples ou com declinações)
- Acesso de administrador ao back-office PrestaShop

## Instalação

1. No back-office, vá a **Módulos → Gestor de módulos → Carregar um módulo**.
2. Carregue o ficheiro `dffreegift-1.0.0.zip`.
3. Clique em **Instalar** e depois em **Configurar**.

Na instalação, o módulo efetua as seguintes operações em segundo plano:

- Registo de 5 hooks: `actionCartSave`, `actionObjectCartRuleDeleteBefore`, `displayShoppingCart`, `displayCartExtraProductActions`, `displayHeader`.
- Escrita dos valores de configuração por defeito (limiar 50 €, cálculo com IVA, sem portes, verificação de stock ativada).
- Criação de uma `CartRule` « fantasma » com um código único do tipo `DFFREEGIFT_A7B3F2D9`, visível em **Catálogo → Descontos → Regras de carrinho**.

**Nota.** A CartRule criada na instalação ainda não tem produto de oferta atribuído (`gift_product = 0`) e por isso não está funcionalmente ativa. Será sincronizada assim que guardar um ID de produto de oferta no ecrã de configuração.

## Configuração

O ecrã de configuração encontra-se em **Módulos → DataFirefly Free Gift → Configurar**. Todos os parâmetros estão agrupados num único formulário.

### Ativar o módulo

O interruptor **Ativar o módulo** funciona como interruptor principal. Na posição _Não_, o módulo continua instalado mas não faz nada: sem adição automática, sem bloco no front-office, sem cálculo de limiar. Útil para desativar temporariamente a oferta (fim de uma operação sazonal, por exemplo) sem perder a configuração.

### Produto de oferta e declinação

Dois campos a preencher por ordem:

1. **ID do produto de oferta**: introduza o ID PrestaShop do produto a oferecer. O ID encontra-se em **Catálogo → Produtos** (coluna ID). Depois de guardar uma primeira vez, o nome do produto aparece como ajuda sob o campo para confirmação.
2. **Declinação**: lista pendente das combinações disponíveis para o produto. Preenche-se automaticamente _depois_ de guardar o ID do produto. Escolha uma declinação específica (por exemplo « Tamanho M, cor preta ») ou deixe em _— Sem declinação —_ para um produto simples.

**Dica.** Se mudar de produto de oferta mais tarde, a CartRule é automaticamente ressincronizada na gravação. Não precisa de tocar manualmente na regra na secção Descontos.

### Limiar de ativação

O campo **Limiar de ativação** define o montante do carrinho a partir do qual a oferta é adicionada. Dois parâmetros associados determinam a base de cálculo:

- **Cálculo com IVA**: se ativado, o total inclui todos os impostos aplicados ao carrinho. Se desativado, o limiar é comparado com o total sem IVA. A maioria das lojas B2C funciona com IVA; as lojas B2B raciocinam muitas vezes sem IVA.
- **Incluir os portes**: se ativado, os portes estimados são acrescentados ao total antes da comparação. Na prática, raramente se ativa, já que os portes nem sempre estão calculados no momento em que o cliente consulta o carrinho (nenhuma transportadora escolhida = 0 €).

Concretamente, o total avaliado corresponde a uma chamada nativa do PrestaShop:

```
Cart::getOrderTotal(
    $with_taxes = (bool) CFG_TAX_INCL,
    $type = CFG_INCLUDE_SHIPPING ? Cart::BOTH : Cart::ONLY_PRODUCTS
);
```

Isto garante que o valor usado na comparação é estritamente idêntico ao apresentado no resumo do carrinho do PrestaShop.

### Verificação do stock

O interruptor **Verificar o stock da oferta** (ativado por defeito) suspende a adição automática se o produto de oferta estiver indisponível. O controlo respeita a estratégia _out of stock_ configurada globalmente no PrestaShop:

- Se o produto estiver marcado « autorizar a encomenda sem stock », a adição automática mantém-se ativa mesmo com quantidade 0.
- Se o produto recusar encomendas sem stock, a adição automática é suspensa quando a quantidade chega a 0.

**Recomendação.** Deixe esta verificação ativada. Desativar o controlo pode levar a encomendas bloqueadas no checkout por rutura de stock da oferta: experiência de cliente degradada e intervenção manual necessária.

### Restrição por grupos de clientes

A grelha **Grupos de clientes elegíveis** lista todos os grupos da loja com uma caixa de seleção por grupo. Dois comportamentos:

- **Nenhuma caixa marcada**: todos os clientes são elegíveis, incluindo os visitantes não identificados (desde que o grupo por defeito `PS_UNIDENTIFIED_GROUP` não esteja excluído, que é o comportamento por defeito).
- **Uma ou várias caixas marcadas**: só os clientes membros de pelo menos um grupo marcado veem o bloco de progresso e beneficiam da adição automática.

Casos de utilização típicos:

- Oferta reservada ao grupo « Profissionais » para uma clientela B2B.
- Oferta reservada ao grupo « VIP » para um programa de fidelização.
- Oferta proposta a todos _exceto_ aos revendedores (marcar todos os grupos exceto o grupo revendedor).

### Opções de apresentação

Dois interruptores independentes controlam a aparência do bloco no front-office:

- **Mostrar a mensagem de progresso**: ativa ou desativa completamente o bloco na página do carrinho. Na posição _Não_, a adição automática continua a funcionar mas nenhuma mensagem aparece do lado do cliente (útil se quiser controlar a apresentação através do seu próprio tema).
- **Mostrar a barra de progresso**: ativa ou desativa a barra colorida sob a mensagem. A mensagem de texto continua visível.

## Como funciona tecnicamente

### A CartRule fantasma

Em vez de manipular os preços dos produtos, o dffreegift explora o mecanismo nativo de oferta do PrestaShop através de `CartRule`. Na instalação, é criada uma regra com as seguintes propriedades:

- `code` = `DFFREEGIFT_A7B3F2D9` (sufixo gerado aleatoriamente na instalação)
- `gift_product` = 0 (atualizado a cada gravação da configuração)
- `gift_product_attribute` = 0 (atualizado a cada gravação da configuração)
- `quantity` = 999 999 e `quantity_per_user` = 999 999 (praticamente ilimitado)
- `date_from` = agora, `date_to` = +50 anos
- `active` = 1, sem código, sem desconto, sem restrição de produto nem de categoria

Quando o limiar é atingido, o módulo associa esta regra ao carrinho através de `Cart::addCartRule($id)`. O PrestaShop encarrega-se depois do resto:

- Inserção de uma linha de carrinho com `gift = 1` e `price = 0`.
- Apresentação no resumo do carrinho com um badge « Oferta ».
- Consideração no momento da conversão em encomenda.
- Snapshot no histórico da encomenda (a oferta continua visível mesmo que mude de produto de oferta mais tarde).

Quando o carrinho volta a descer abaixo do limiar, o módulo desassocia a regra através de `Cart::removeCartRule($id)`. A linha de oferta é retirada no mesmo pedido.

### Os hooks utilizados

- **actionCartSave**: hook principal. Chamado a cada gravação do carrinho (adição, alteração, remoção, início de sessão do cliente com fusão de carrinho). O módulo calcula o total e decide associar ou desassociar a regra. Uma flag estática `self::$syncing` impede a recursão se a associação da regra desencadear por sua vez um save.
- **actionObjectCartRuleDeleteBefore**: autorreparação. Se um administrador eliminar manualmente a regra fantasma a partir de **Catálogo → Descontos**, este hook deteta a eliminação e repõe o ID a zero na configuração. A próxima sincronização recriará uma regra limpa.
- **displayHeader**: regista o CSS e o JS do front-office (`views/css/dffreegift.css` e `views/js/dffreegift.js`).
- **displayShoppingCart**: renderiza o bloco de progresso na página do carrinho.
- **displayCartExtraProductActions**: reservado para evoluções futuras (badge na linha de oferta).

### O cálculo do limiar

A cada chamada de `syncCartGift()`, o módulo verifica por ordem:

1. O módulo está ativado? (senão sai)
2. O cliente é elegível segundo os grupos configurados? (senão desassocia, se associada)
3. O produto de oferta é válido (existe, ativo, em stock se a verificação estiver ativada)? (senão desassocia)
4. Cálculo do total segundo com/sem IVA e portes incluídos/excluídos.
5. Comparação com o limiar com tolerância de arredondamento de 0,001 €.
6. Associar a regra se o limiar for atingido e ainda não estiver associada. Desassociar se estiver abaixo do limiar e associada.

## Bloco de progresso no front-office

O bloco aparece automaticamente na página do carrinho, entre o resumo dos produtos e o total. Dois estados visuais:

- **Em espera** (limiar não atingido): fundo cinzento-claro, mensagem « Adicione X,XX € para receber a sua oferta », barra laranja que se enche à medida que o limiar se aproxima.
- **Objetivo atingido** (limiar ultrapassado): fundo verde-claro, mensagem « Oferta adicionada ao seu carrinho! », barra cheia a verde. Uma animação `pulse` é desencadeada na transição do estado _em espera_ para _atingido_.

### Personalizar as cores

As cores são definidas em `views/css/dffreegift.css`. Para personalizar sem modificar o módulo (o que apagaria as suas alterações nas atualizações), sobreponha as classes no CSS do seu tema:

```
.dffreegift-progress {
    border-color: #a-sua-cor;
    background: #o-seu-fundo;
}
.dffreegift-progress--reached {
    background: #o-seu-verde-claro;
    border-color: #o-seu-verde;
}
.dffreegift-progress__bar-fill {
    background: linear-gradient(90deg, #cor1, #cor2);
}
```

### Personalizar os textos

Os textos apresentados do lado do cliente são traduzíveis através do mecanismo padrão do PrestaShop. Vá a **Internacional → Traduções**, selecione « Traduções dos módulos », escolha _dffreegift_ e o idioma, e procure o domínio `Modules.Dffreegift.Shop`. As cadeias disponíveis:

- _« Adicione %amount% para receber a sua oferta »_: mensagem em espera (`%amount%` é substituído automaticamente pelo montante restante formatado segundo a moeda e a localização).
- _« Oferta adicionada ao seu carrinho! »_: mensagem de objetivo atingido.
- _« Progresso até à oferta »_: etiqueta ARIA da barra (lida pelos leitores de ecrã).

## Coabitação com outras promoções

Sendo a oferta adicionada através de uma `CartRule` nativa, coabita normalmente com qualquer outra `CartRule`. Comportamentos esperados:

- **Outros códigos promocionais do cliente** (desconto em percentagem, montante fixo, portes grátis): aplicam-se normalmente em paralelo com a oferta. A oferta não consome o desconto, e vice-versa.
- **Outra regra com gift_product** configurado noutro lado: o PrestaShop trata as duas como regras independentes e adiciona as duas ofertas. Atenção se acumular vários módulos de ofertas.
- **Regra com product_restriction** que exclui o produto de oferta: a regra que restringe prevalece. A oferta não é adicionada se outra regra ativa a excluir explicitamente.
- **Regra com cart_rule_restriction**: se outra regra proibir o uso da nossa por restrição cruzada, a adição automática é bloqueada (comportamento nativo do PrestaShop).

**Nota.** O limiar do dffreegift é avaliado no total _sem a oferta_. Se tiver outra regra de carrinho que desconte o total antes de o dffreegift o avaliar, a comparação é feita no total _depois_ do desconto. Um carrinho de 60 € com desconto de 15 € cai para 45 € e não ativará um limiar de 50 €.

## Multiloja

O módulo funciona com a configuração multiloja do PrestaShop no **contexto da loja por defeito**. As configurações (limiar, produto de oferta, opções) são guardadas através de `Configuration::updateValue`, que respeita o contexto de loja atual. A `CartRule` criada na instalação é associada à loja ativa no momento da instalação.

Para uma implementação multiloja com _ofertas diferentes por loja_, é atualmente necessário instalar e configurar o módulo em cada contexto de loja separadamente. Contacte o suporte para uma variante com delimitação explícita por `id_shop`.

## Resolução de problemas

### A oferta não é adicionada ao carrinho

Verifique por ordem:

1. O módulo está ativado? (Módulos → Configurar → interruptor _Ativar o módulo_).
2. O produto de oferta é válido? (ID correto, produto ativo, em stock se a verificação de stock estiver ativada).
3. O cliente está num grupo autorizado? (se restringiu a grupos, um visitante não identificado que não esteja em nenhum grupo autorizado não verá nada).
4. O limiar foi realmente atingido? Recalcule manualmente o total segundo os seus parâmetros (com/sem IVA, com/sem portes).
5. A `CartRule` fantasma existe e está ativa? Vá a **Catálogo → Descontos → Regras de carrinho** e procure `DFFREEGIFT_`.

### O bloco de progresso não aparece na página do carrinho

Causas comuns:

- O interruptor _Mostrar a mensagem de progresso_ está na posição _Não_.
- O cliente não é elegível segundo os grupos de clientes configurados.
- O produto de oferta é inválido (não existe, inativo, ou esgotado com verificação de stock ativada).
- O seu tema personalizado não chama o hook `displayShoppingCart`. Verifique com o comando `grep -r "displayShoppingCart" themes/o-seu-tema/` ou em **Módulos → Posições**.

### A CartRule desapareceu do back-office

Se alguém eliminou a regra a partir de **Catálogo → Descontos**, o hook `actionObjectCartRuleDeleteBefore` detetou a eliminação e repôs a configuração a zero. Na próxima sincronização do carrinho (ou seja, na próxima adição de produto por um cliente), é criada automaticamente uma nova regra com um novo código `DFFREEGIFT_xxxxxxxx`.

Para forçar a regeneração imediatamente sem esperar por um cliente:

1. Vá a **Módulos → DataFirefly Free Gift → Desativar**.
2. Depois **Ativar** de novo. Isto recria uma regra limpa.

### Erros nos registos do PrestaShop

O módulo regista as exceções em **Parâmetros avançados → Registos** com o prefixo `[dffreegift]`. Uma mensagem típica em caso de problema:

```
[dffreegift] actionCartSave error: <descrição do erro>
```

Estes erros nunca interrompem o funcionamento do carrinho: são apenas informativos. Em caso de registo recorrente, transmita a mensagem completa ao suporte.

### O limiar parece mal calculado

O cálculo depende estritamente dos seus parâmetros _Cálculo com IVA_ e _Incluir os portes_. Para verificar o que o PrestaShop devolve:

- Com IVA + sem portes: corresponde ao _Subtotal de produtos com IVA_ apresentado no resumo do carrinho.
- Com IVA + com portes: corresponde ao _Total com IVA_ (produtos + portes se uma transportadora estiver selecionada).
- Sem IVA + sem portes: corresponde ao _Subtotal de produtos sem IVA_.
- Sem IVA + com portes: corresponde ao _Total sem IVA_ (produtos + portes sem IVA).

Se constatar uma diferença, compare com a linha exata do resumo do carrinho: há fortes probabilidades de a diferença vir dos portes ainda não calculados (o cliente ainda não escolheu transportadora, logo os portes estão a 0 €).

## Desinstalação

Vá a **Módulos → Gestor de módulos → DataFirefly Free Gift → Desinstalar**. A desinstalação elimina:

- A `CartRule` fantasma e todas as suas associações aos carrinhos (os carrinhos em curso perderão automaticamente a sua oferta).
- Todas as chaves de configuração com o prefixo `DFFREEGIFT_`.

**Atenção.** A desinstalação não altera as ofertas nas encomendas passadas: estas conservam o seu snapshot de origem com a oferta devidamente registada. Só os carrinhos em curso são afetados.

## FAQ rápida

- **A oferta aparece no mini-carrinho do cabeçalho?** Não, apenas na página do carrinho (hook `displayShoppingCart`). O mini-carrinho é gerido de forma diferente por cada tema e seria necessária uma integração específica tema a tema. A pedido ao suporte.
- **Posso oferecer várias ofertas com vários limiares (ex. oferta A aos 50 €, oferta B aos 100 €)?** Não, a versão 1.0.0 gere uma única oferta com um único limiar. Para vários escalões, contacte o suporte.
- **A oferta está incluída nos reembolsos?** Como qualquer produto de oferta nativo do PrestaShop, a oferta aparece na encomenda a preço 0. Em caso de reembolso parcial, a oferta fica na encomenda sem impacto financeiro.
- **Posso modificar o ficheiro dffreegift.php diretamente?** Tecnicamente sim (código não cifrado), mas as atualizações oficiais apagarão as suas alterações. Crie um módulo de override para qualquer personalização profunda.

## Suporte e atualizações

O módulo inclui **12 meses de atualizações e de suporte** a partir da data de compra. Suporte por e-mail em francês ou em inglês, resposta em 24 horas úteis.

Para qualquer questão ou anomalia, contacte [o suporte DataFirefly](https://www.datafirefly.com/pt/contacto/) indicando:

- Versão do PrestaShop (visível em **Parâmetros avançados → Informação**)
- Versão do PHP
- Versão do módulo dffreegift instalado
- Descrição do comportamento observado vs. comportamento esperado
- Excerto dos registos do PrestaShop se aplicável (`[dffreegift]`)
