cryoth Posted July 24, 2020 Share Posted July 24, 2020 (edited) Bonjour à tous, Je reviens avec un cas un peu spécifique qui me donne du fil à retordre, j'utilise un module d'abonnement qui lors d'une commande de type "abonnement" va passer un premier achat et recevoir des signaux de paiement à interval régulier pour les paiement suivant. A chaque signal reçu une commande est créée à partir de la commande originel. Cependant, le prix du 1er versement diffère des suivants, le changement de prix est généré par une 'CartRule' de type "Discount". Je voudrais pouvoir supprimer cette réduction de prix sur les commandes automatisés, et j'ai effectué la suppression des CartRule sur le panier : foreach ($new_cart->getCartRules() as $rule) { if ($this->removeRule($subscription, $cart, $new_cart, $rule)) { $new_cart->removeCartRule($rule['id_cart_rule']); } } Cependant lorsque j'envoi mon panier vers la classe PaymentModule afin de valider la commande ( validateOrder() ) il se trouve que les réductions sont ré-appliqués à nouveau sur mon panier. Du coup je me demande si ma façon de faire est la bonne, comment faire en sorte de faire sauter ma réduction de façon propre, dois-je plutot me tourner vers la classe CartRule et lui appliquer un filtre spécifique ? Ou même existe-t-il une option dans prestashop qui permette de gérer mon cas avec un premier prix spécifique sans avoir à utiliser les réductions ? Actuellement je tente d'override la classe PaymentModule depuis mon module pour empêcher l'application d'un discount si un paramètre $noDiscount est passé : public function validateOrder( $id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, $noDiscount = false, Shop $shop = null ) // Début de la fonction ... // Make sure CartRule caches are empty CartRule::cleanCache(); // Modification anti-discount if($noDiscount){ $cart_rules = $this->context->cart->getCartRules(CartRule::FILTER_ACTION_ALL, true); }else{ $cart_rules = $this->context->cart->getCartRules(); } foreach ($cart_rules as $cart_rule) { if (($rule = new CartRule((int) $cart_rule['obj']->id)) && Validate::isLoadedObject($rule)) { if ($error = $rule->checkValidity($this->context, true, true)) { $this->context->cart->removeCartRule((int) $rule->id); if (isset($this->context->cookie, $this->context->cookie->id_customer) && $this->context->cookie->id_customer && !empty($rule->code)) { Tools::redirect('index.php?controller=order&submitAddDiscount=1&discount_name=' . urlencode($rule->code)); } else { $rule_name = isset($rule->name[(int) $this->context->cart->id_lang]) ? $rule->name[(int) $this->context->cart->id_lang] : $rule->code; $error = $this->trans('The cart rule named "%1s" (ID %2s) used in this cart is not valid and has been withdrawn from cart', array($rule_name, (int) $rule->id), 'Admin.Payment.Notification'); PrestaShopLogger::addLog($error, 3, '0000002', 'Cart', (int) $this->context->cart->id); } } } } // Autre modification au moment de l'appel de createOrderCartRules() if($noDiscount){ $cart_rules_list = array(); }else{ $cart_rules_list = $this->createOrderCartRules( $order, $this->context->cart, $order_list, $total_reduction_value_ti, $total_reduction_value_tex, $id_order_state ); } J'espère que vous pourrez m'aider Edited July 24, 2020 by cryoth (see edit history) Link to comment Share on other sites More sharing options...
cryoth Posted July 24, 2020 Author Share Posted July 24, 2020 (edited) Je me rends vraiment compte que les réductions sont vérifiés et recréés à de nombreux endroits lors de la création de la commande et j'ai l'impression de coder à contre-courant ... Peut-être que modifier la commande n'est pas la solution mais que je dois créer une réduction spécifique ? Donnez-moi votre avis car je voudrais pouvoir produire quelque chose qui suive un minimum les bonnes pratiques. Edited July 24, 2020 by cryoth (see edit history) Link to comment Share on other sites More sharing options...
Mediacom87 Posted July 24, 2020 Share Posted July 24, 2020 Bonjour, Lorsque vous créez le panier, vous ajoutez une produit, peut être pourriez-vous ajouter ce produit avec un prix spécifique et pas son prix de base ? 1 Link to comment Share on other sites More sharing options...
cryoth Posted July 24, 2020 Author Share Posted July 24, 2020 Bonjour @Mediacom87, J'avais eut la même réflexion dans un premier temps mais lors de mes tests j'ai vu que je ne pouvais pas retirer le prix spécifique d'un produit au moment de la commande non plus. Le prix spécifique prends le dessus sur le prix de base au moment de la création de la commande et j'ai du abandonner l'idée pour me tourner vers les réductions qui sont plus facilement manipulables. Mais au bout du compte les 2 solutions retrouvent leur prix d'origine au moment de la création de commande. Link to comment Share on other sites More sharing options...
cryoth Posted July 24, 2020 Author Share Posted July 24, 2020 Je tente un coup de poker et j'override la classe CartRule et plus spécifiquement la fonction checkValidity. L'idée est de créer une vérification si mon panier est un abonnement en cours et si c'est le cas la fonction checkValidity() retournera immédiatement false. Etant donné que checkValidity est la fonction référence pour l'ajout des règles au panier, j'espère que ça empêchera l'ajout des réductions... Link to comment Share on other sites More sharing options...
cryoth Posted July 24, 2020 Author Share Posted July 24, 2020 (edited) Je viens de réussir à mettre en place mon système de paiement avec suppression des réductions, je partage la démarche pour ceux qui se retrouveraient dans le même cas. Au final j'ai opté pour un override de la classe CartRule : // === Code ajouté au début de la fonction checkValidity() de CartRule === $isSubscriptionLive = Db::getInstance()->getValue(' SELECT count(*) FROM ' . _DB_PREFIX_ . 'ogone_cloned_cart WHERE id_cart = ' . (int) $context->cart->id . ' AND id_customer = ' . (int) $context->cart->id_customer . ' '); // Si abonnement est en cours et 1er versement déjà effectué if($isSubscriptionLive > 0){ return false; } // === Code exécuté au moment du clone de mon panier === // Ajout du nouveau cart à la liste pour pouvoir l'identifier comme non affecté par les réductions $result = Db::getInstance()->insert('ogone_cloned_cart', array( 'id_ogone_cloned' => NULL, 'id_cart' => (int) $new_cart->id, 'id_initial_cart' => (int) $subscription->id_cart, 'id_customer' => (int) $new_cart->id_customer, 'date_add' => date('Y-m-d H:i:s') )); Les données passent par une table faite spécialement pour l'occasion et qui permettent à checkValidity() de savoir si le panier dois ou non recevoir une réduction En espérant que ça servira à certains, Enjoy Edited July 24, 2020 by cryoth (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now