Certains de nos clients nous remontent une interrogation concernant des stocks négatifs sous Prestashop en version 1.6.* ou 1.7.* alors qu’ils ont précisé dans l’interface d’administration une interdiction des commandes hors-stock.

Cela arrive quelque soit la configuration de « En cas de rupture de stock » choisie : « Refuser les commandes » ou « Par défaut: Refuser les commandes tel que défini dans les préférences produits ».

Il faut d’abord comprendre comment Prestashop vérifie les stocks des produits lors de la validation de panier.

Prestashop décrémente les stocks uniquement lorsqu’un panier est transformé en commande. C’est à dire que l’on a reçu la validation du serveur bancaire pour un paiement par carte bleue / Paypal ou la validation d’un paiement par chèque ou virement bancaire. Il ne réserve pas les quantités lors de la mise au panier d’un produit.

Donc si vous avez un site à fort trafic comme peut l’être Social animals lors d’un lancement, votre site peut se retrouver à avoir largement plus de quantité en panier que de quantité réelle en stock.

Prestashop va vérifier qu’il existe du stock présent tout au long du tunnel de commande (Excepté pour les versions 1.7.2 – Voir plus bas). Mais lors de la bascule sur le serveur de paiement bancaire, il n’y a plus de vérification.

Prenons par exemple, un produit avec 10 quantités en stock. Vous avez 20 clients qui ajoute 1 exemplaire au panier. Prestashop l’autorise puisqu’il a 10 quantités de ce produit disponible. Tous les clients avancent en même temps dans le tunnel d’achat (Probabilité d’autant plus grande que vous avez un site à fort trafic). A chacune des étapes de commande, Prestashop les valident puisque le produit a des quantités suffisantes pour chacun des paniers. Ces 20 clients sont redirigés vers le serveur de paiement par carte bancaire. A ce moment, même s’ils ne payent pas tous au même instant, Prestashop, va recevoir 20 confirmations de paiement pour ce produit. Or Il ne peut refuser les 10 dernières commandes puisqu’il a reçu un paiement. Il va donc valider les commandes et donc décrémenter les quantités pour ce produit. Ce qui nous amène à avoir un stock de -10 pour ce produit, alors que l’on a explicitement interdit le hors-stock.

Voila pourquoi, certains produits se retrouvent avec des stocks négatifs.

Comment éviter cela, il faut donc calquer le fonctionnement de sa boutique virtuelle à une boutique physique et lors de la mise d’un produit dans un panier, il faut décrémenter le stock disponible. Cela évite d’avoir plus de produits dans les paniers que de stocks disponibles.

Pour cela nous avons trouvé un module Prestashop LonelyStock que l’on a mis en test chez un de nos clients. Ce module permet de réserver les quantités disponibles lors de la mise au panier d’un produit. Passé un certain temps, si le client n’a pas fait de commande, le produit est supprimé du panier et les quantités sont de nouveau disponible pour l’achat.

!!! Attention !!!

Ce n’est pas une solution miracle. Cela permet de diminuer grandement les stocks négatifs mais cela ne peut pas vous garantir un stock négatif ou  des problèmes sur vos commandes. En effet, Prestashop vérifie le stock des produits tout au long du tunnel de commande, excepté à la dernière étape « Choix de la méthode de paiement ». En effet, lors du choix de la méthode de paiement, Prestashop délègue les prochaines opérations aux modules de paiement qui ne vérifient pas forcément les quantités de stocks  disponibles.

Si nous reprenons un exemple d’un produit avec une quantité de 10. Avec le module, il existe au maximum 10 personnes avec une quantité de 1 dans le panier. Ils arrivent tous en même temps sur la page de sélection de paiement. Ils leur restent à tous 3 minutes pour commander. Ils cliquent tous sur la méthode de paiement par carte bancaire et sont redirigés vers le serveur bancaire de paiement par carte bleue. Sur ces 10 personnes, 7 personnes payent directement et en moins de 3 minutes leurs commandes. Les quantités pour ce produit passent donc de 10 à 7. Or les 3 dernières personnes mettent plus de 3 minutes. Leurs quantités sont donc libérées et 3 autres personnes peuvent donc acheter ces produits. La quantité des produits sera donc de -3 ou si les produits ont été supprimés de leurs paniers, les commandes auront un montant reçu supérieur au montant du panier (Puisque le panier n’aura plus le produit).

 

L’inconvénient de ce module est la réservation du stock par des concurrents /  personnes mal intentionnées qui peuvent ajouter des produits dans leur panier sans finaliser la commande ce qui empêchent d’autres « véritables » clients d’acheter ce produit. C’est pour cela que le paramétrage du chronomètre est cruciale.

 

Aucune vérification des stocks pour un Prestashop 1.7.2.*

Comme nous l’avons vu, Prestashop doit vérifier le stock des produits à chaque étape du tunnel de commande. Or sur les versions 1.7.2.*, il existe un bug, corrigé en version 1.7.3.0 qui  ne vérifie pas les stocks disponibles. Sans devoir effectuer une mise à jour complète, ou appliquer un commit (celui-ci modifie le thème donc incomplet dans un thème spécifique),voici les fichiers à modifier :

Le fichier controller qui va permettre de vérifier la disponibilité.

!! Attention de toujours faire une sauvegarde de vos fichiers avant de les modifier. !!

Si vous ne comprenez pas ce que vous faites, ne pas modifier votre fichier et demande à votre agence ou une agence de développement spécialisée dans Prestashop d’apporter ces modifications sur votre site Internet.

override/controllers/front/OrderController.php

<?php
/**
* 2007-2017 Pliciweb Solutions
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
*  @author    Pliciweb Solutions <contact@pliciweb.com>
*  @copyright  2007-2017 Pliciweb Solutions
*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*  International Registered Trademark & Property of Pliciweb Solutions
*/

class OrderController extends OrderControllerCore
{
/**
* Initialize order controller
* @see FrontController::init()
*/
public function init()
{
parent::init();

$isAvailable = $this->areProductsAvailable();

if (true !== $isAvailable) {
$this->errors[] = $isAvailable;
$this->redirectWithNotifications($this->context->link->getPageLink('cart').'?action=show');
}
}

/**
* Check if the products in the cart are available
*
* @return bool|string
*/
private function areProductsAvailable()
{
$product = $this->context->cart->checkQuantities(true);

if (true === $product || !is_array($product)) {
return true;
}
if ($product['active']) {
return $this->trans(
'Nous n\'avons plus assez de produit %product% en stock depuis votre dernière venue ! Nous sommes désolé. Vous pouvez essayer de commander une plus petite quantité, mais si vous avez toujours ce message, c\'est que ce produit est en rupture momentanée.',
array('%product%' => $product['name']),
'Shop.Notifications.Error'
);
}

return $this->trans(
'This product (%product%) is no longer available.',
array('%product%' => $product['name']),
'Shop.Notifications.Error'
);
}

Et voici le fichier thème à modifier pour désactiver le bouton de poursuite d’achat sur la page panier :

themes/PRSADD052/templates/checkout/_partials/cart-detailed-actions.tpl

qui transforme la ligne

{elseif empty($cart.products) }

en

{elseif empty($cart.products) || (true !== $isAvailable)}

Comme toujours, si vous avez des corrections / améliorations / remarques, n’hésitez pas à nous les transmettre