THELIA Forum

Welcome to the THELIA support and discusssion forum

Announcement

Rejoignez la communauté sur le Discord Thelia : https://discord.gg/YgwpYEE3y3

Offline


Bonjour,
Dans le formulaire pour ajouter un produit au panier, je souhaite ajouter une contrainte pour qu'un client ayant déja acheté ce produit ne puisse pas le commander à nouveau.

Dans mon formulaire j'ai donc ajouter la contrainte suivante : 
```
->add("product", "text", array(
                "constraints" => array(
                    new Constraints\NotBlank(),
                    new Constraints\Callback(array("methods" => array(
                        array($this, "checkProduct"),
                    ))),
                    new Constraints\Callback(array("methods" => array(
                        array($this, "checkUserProduct"),
                    ))),
                ),
                "label" => "product",
                "label_attr" => array(
                    "for" => "cart_product",
                ),
            ))
```

Et j'ai crée la fonction checkUserProduct() :

```
public function checkUserProduct($value, ExecutionContextInterface $context)
    {

    $OrderProductQuery = OrderProductQuery::create()->toString()
            ->useProductSaleElementsQuery()
                ->endUse()
                ->useOrderQuery()
                ->endUse()
                ->useCustomerQuery()
                ->filterByProductId(117)
                ->endUse()
                ->count();

if ($OrderProductQuery <> 0) {
            $context->addViolation(Translator::getInstance()->trans("Vous ne pouvez pas ajouter ce produit au panier car vous l'avez déja acheter."));
        }

}

```


Pour le moment j'ai réduit ma requete pour essayer de la faire pas à pas car je ne peux plus ajouter le produit au panier mais j'ai aucun message d'erreur qui s'affiche.

Quelqu'un aurait'il une piste ?

Merci

Offline


La requête n'a aucun sens, comment  OrderProductQuery::create()->toString()->useProductSaleElementsQuery() pourrait fonctionner ? Pourquoi toString() ?


OpenStudio Toulouse

Offline


C'est une erreur de ma part, j'ai fait pas mal de test et je souhaitais afficher ma requete pour voir ce qui n'allait pas ( d'ou le toString() ), le reste était en commentaire. Mias rien ne s'affiche et aucun message d'erreur apparait.

Ma fonction est la suivante :

```
public function checkUserProduct($value, ExecutionContextInterface $context)
    {

        $OrderProductQuery = OrderProductQuery::create()
            ->useProductSaleElementsQuery()
                ->endUse()
                ->useOrderQuery()
                ->endUse()
                ->useCustomerQuery()
                ->filterById(107)
                ->endUse()
                ->count();

        if ($OrderProductQuery <> 0) {
            $context->addViolation(Translator::getInstance()->trans("Vous ne pouvez pas ajouter ce produit au panier car vous l'avez déja acheter."));
        }


    }

```

Offline


Il n'existe pas de méthode useProductSaleElementsQuery() dans OrderProductQuery.

Ce que tu veux faire, si j'ai bien compris, c'est vérifier que le client courant n'a pas déjà acheté un certain produit. Le plus simple c'est de passer par la référence du produit :

        $customer = $this->getRequest()->getSession()->getCustomerUser();

        if (null !== $customer) { // Oui, il se peut qu'aucun client ne soit connecté
            $nbAchats = OrderProductQuery::create()
                ->filterByProductRef('la ref du produit')
                ->useOrderQuery()
                ->filterByCustomerId($customer->getId())
                ->endUse()
                ->count();
        } else {
            $nbAchats = 0;
        }
        
        if ($nbAchats > 0) {
            // ...
        }

Ca se traduit par :

select count(*) from order_product op
left join `order` o on o.id = op.order_id
where o.customer_id = nnn
and op.product_ref = 'xxxx'

Mais comme le client peut ne pas être connecté au moment où il ajoute le produit au panier, ta stratégie n'est pas efficace : en effet, le client peut ajouter le produit dans le panier sans être connecté, puis il se connecte (le produit est toujours dans le panier), et paye => achat multiple possible !


OpenStudio Toulouse

Offline


Merci pour votre réponse.

Le client doit être connecté pour pouvoir commander. Sinon le bouton "ajouter au panier" n’apparaît pas.

Pour la requête je préférais passer par l'id du produit ( d'ou ma jointure avec les tables ProductSaleElementsQuery et OrderQuery ) car le client souhaite parfois dupliquer des produits. Dans ce cas la requete serais plutot :
```
$nbAchats = OrderProductQuery::create()
                ->useProductSaleElementsQuery()
                ->filterByProductId($value)
                ->endUse()
                ->useOrderQuery()
                ->filterByCustomerId($customer->getId())
                ->endUse()
                ->count();
```
Par contre ni avec votre requete ni avec la mienne je n'arrive à afficher le message d'erreur :
```
if ($nbAchats > 0) {
            throw new ProductNotFoundException(sprintf(Translator::getInstance()->trans("Vous ne pouvez pas ajouter ce produit %d au panier car vous l'avez déja acheter"), $data["refproduct"]));

            //$context->addViolation(Translator::getInstance()->trans("Vous ne pouvez pas ajouter ce produit au panier car vous l'avez déja acheter"));
        }
```

J'ai essayé les deux versions ci dessus mais il s'affiche de manière aléatoire sur le même produit qu'il ai déja été commandé ou pas.

Même chose pour l'ajout au panier il fonctionne quand il veut.
Je n'arrive pas à définir d'ou vient le problème si c'est la requête ou autre chose.

Merci

Offline


d'ou ma jointure avec les tables ProductSaleElementsQuery

Je le redis : il n'existe pas de méthode useProductSaleElementsQuery() dans la classe OrderProductQuery, Ecrire OrderProductQuery::create()->useProductSaleElementsQuery() cause une erreur fatale à l'éxécution.


OpenStudio Toulouse

Offline


Ah oui effectivement.

Par contre j'ai toujours un petit problème, si le client n'a jamais acheté ce produit c'est bon je peux ajouter le produit au panier. S'il l'a déja acheté, il ne s'ajoute pas mais mon message d'erreur ne s'affiche pas (ou sinon lorsque je change de page).

y à t'il une façon en particulier d'afficher le message des que l'on clique sur le bouton ajouter au panier ?

Merci beaucoup en tout cas.