Jump to content

Code réduction annulé si un produit en promo dans le panier final


Recommended Posts

Bonjour,

Je viens de migrer ma boutique sur Prestashop, je vous invite a aller voir d'ailleurs :-) www.zolimome.com.
Je suis très satisfaite ! En revanche, quelques 'soucis' pour ce démarrage.
Je viens de mettre mon premier code réduction, il est valable sur tous les produits hors promos. En revanche, si un client
cumule dans son panier des promos + autres produits plein tarifs, le code ne fonctionne pas sur les produit plein pot.

Y a t il un contournement, une solution à cela ?

Je vous remercie pour votre aide !

Link to comment
Share on other sites

Salut,

Ta solution est simple tu ne bloque pas sur les produits en promotion.

Mais si je comprends bien, tu dois faire un bon de réduction en pourcentage et tu aimerai que la réduction s'applique que sur les produits qui ne sont pas en promo et ainsi autoriser quand même des panier mix (promo et non promo).
Pour faire cela il faut modifier le module dans le code et trouver où est testé la présence de promo et aussi reprendre tout le calcul.

Tu peux faire une demande de développement sur le forum.

Link to comment
Share on other sites

Salut, juste pour te faire remarqué que tu utilise une typographie pas standard sur le Web (Comic sans ms), ce qui fait que ton site n'aura pas la même tête en fonction des clients. Pas dramatique, mais quand même. En plus ce n'est pas la typo la plus lisible.

Je te conseil de regarder sur ce site http://www.typechart.com/ pour trouver la bonne typo.


Rajout :

Dommage aussi que ton carnet de tendance de la page d'accueil ne soit pas cliquable.
J'avais donné la solution dans le forum pour intégrer les scènes sur la page d'accueil, peut être pourrais t'en servir en décomposant ton image en 2 partie avec les produits sur la scène en dessous de l'image de l'édito.

Link to comment
Share on other sites

  • 2 years later...

je remonte ce post pour savoir si qqun aurait trouver une solution.

je souhaite absolument bloquer certains bon de réductions sur les promos car en ce moment je fais déjà un gros destockage jusqu'à -80% donc je peux pas ajouter encore -10%

 

mais par contre c'est vrai que ca bloque le panier des gens qui souhaitent prendre un article en promo et d'autres articles sans promo. c'est assez embétant.

il faudrait que le bon ne s'applique que aux produits concernés, comme pour le montant quoi.

Link to comment
Share on other sites

  • 2 months later...
  • 1 year later...

Bonjour,

 

en effet cela était possible en 1.4 mais pas en 1.5 ...

 

En faisant l'override de la classe CartRule on s'en sort très bien !

 

Il s'agit de la méthode "public function checkValidity" :

 

il faut rajouter : 

$products = $context->cart->getProducts();
$product_on_sale = false;
foreach($products as $product){
    if(!empty($product["reduction_applies"]) && $product["reduction_applies"] > 0)
        $product_on_sale = true;
}
if ($product_on_sale)
    return (!$display_error) ? false : Tools::displayError('This voucher isn\'t cumulative on products with reduction or marked as on sale');

Il faut place cela après le code suivant : (je vous incite fortement à utiliser l'override pour faire la modification.)

if (strtotime($this->date_to) < time())
    return (!$display_error) ? false : Tools::displayError('This voucher has expired');

Ce qui donne une fonction "checkValidity" qui ressemble à ça : 

public function checkValidity(Context $context, $alreadyInCart = false, $display_error = true)
{
        if (!CartRule::isFeatureActive())
            return false;

        if (!$this->active)
            return (!$display_error) ? false : Tools::displayError('This voucher is disabled');
        if (!$this->quantity)
            return (!$display_error) ? false : Tools::displayError('This voucher has already been used');
        if (strtotime($this->date_from) > time())
            return (!$display_error) ? false : Tools::displayError('This voucher is not valid yet');
        if (strtotime($this->date_to) < time())
            return (!$display_error) ? false : Tools::displayError('This voucher has expired');
        $products = $context->cart->getProducts();
        $product_on_sale = false;
        foreach($products as $product){
            if(!empty($product["reduction_applies"]) && $product["reduction_applies"] > 0)
                $product_on_sale = true;
        }
        if ($product_on_sale)
            return (!$display_error) ? false : Tools::displayError('This voucher isn\'t cumulative on products with reduction or marked as on sale');
        if ($context->cart->id_customer)
        {
            $quantityUsed = Db::getInstance()->getValue('
            SELECT count(*)
            FROM '._DB_PREFIX_.'orders o
            LEFT JOIN '._DB_PREFIX_.'order_cart_rule od ON o.id_order = od.id_order
            WHERE o.id_customer = '.$context->cart->id_customer.'
            AND od.id_cart_rule = '.(int)$this->id.'
            AND '.(int)Configuration::get('PS_OS_ERROR').' != (
                SELECT oh.id_order_state
                FROM '._DB_PREFIX_.'order_history oh
                WHERE oh.id_order = o.id_order
                ORDER BY oh.date_add DESC
                LIMIT 1
            )');
            if ($quantityUsed + 1 > $this->quantity_per_user)
                return (!$display_error) ? false : Tools::displayError('You cannot use this voucher anymore (usage limit reached)');
        }

        // Get an intersection of the customer groups and the cart rule groups (if the customer is not logged in, the default group is 1)
        if ($this->group_restriction)
        {
            $id_cart_rule = (int)Db::getInstance()->getValue('
            SELECT crg.id_cart_rule
            FROM '._DB_PREFIX_.'cart_rule_group crg
            WHERE crg.id_cart_rule = '.(int)$this->id.'
            AND crg.id_group '.($context->cart->id_customer ? 'IN (SELECT cg.id_group FROM '._DB_PREFIX_.'customer_group cg WHERE cg.id_customer = '.(int)$context->cart->id_customer.')' : '= 1'));
            if (!$id_cart_rule)
                return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
        }

        // Check if the customer delivery address is usable with the cart rule
        if ($this->country_restriction)
        {
            if (!$context->cart->id_address_delivery)
                return (!$display_error) ? false : Tools::displayError('You must choose a delivery address before applying this voucher to your order');
            $id_cart_rule = (int)Db::getInstance()->getValue('
            SELECT crc.id_cart_rule
            FROM '._DB_PREFIX_.'cart_rule_country crc
            WHERE crc.id_cart_rule = '.(int)$this->id.'
            AND crc.id_country = (SELECT a.id_country FROM '._DB_PREFIX_.'address a WHERE a.id_address = '.(int)$context->cart->id_address_delivery.' LIMIT 1)');
            if (!$id_cart_rule)
                return (!$display_error) ? false : Tools::displayError('You cannot use this voucher in your country of delivery');
        }

        // Check if the carrier chosen by the customer is usable with the cart rule
        if ($this->carrier_restriction)
        {
            if (!$context->cart->id_carrier)
                return (!$display_error) ? false : Tools::displayError('You must choose a carrier before applying this voucher to your order');
            $id_cart_rule = (int)Db::getInstance()->getValue('
            SELECT crc.id_cart_rule
            FROM '._DB_PREFIX_.'cart_rule_carrier crc
            INNER JOIN '._DB_PREFIX_.'carrier c ON (c.id_reference = crc.id_carrier AND c.deleted = 0)
            WHERE crc.id_cart_rule = '.(int)$this->id.'
            AND c.id_carrier = '.(int)$context->cart->id_carrier);
            if (!$id_cart_rule)
                return (!$display_error) ? false : Tools::displayError('You cannot use this voucher with this carrier');
        }

        // Check if the cart rules appliy to the shop browsed by the customer
        if ($this->shop_restriction && $context->shop->id && Shop::isFeatureActive())
        {
            $id_cart_rule = (int)Db::getInstance()->getValue('
            SELECT crs.id_cart_rule
            FROM '._DB_PREFIX_.'cart_rule_shop crs
            WHERE crs.id_cart_rule = '.(int)$this->id.'
            AND crs.id_shop = '.(int)$context->shop->id);
            if (!$id_cart_rule)
                return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
        }

        // Check if the products chosen by the customer are usable with the cart rule
        if ($this->product_restriction)
        {
            $r = $this->checkProductRestrictions($context, false, $display_error);
            if ($r !== false && $display_error)
                return $r;
            elseif (!$r && !$display_error)
                return false;
        }

        // Check if the cart rule is only usable by a specific customer, and if the current customer is the right one
        if ($this->id_customer && $context->cart->id_customer != $this->id_customer)
        {
            if (!Context::getContext()->customer->isLogged())
                return (!$display_error) ? false : (Tools::displayError('You cannot use this voucher').' - '.Tools::displayError('Please log in'));
            return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
        }

        if ($this->minimum_amount)
        {
            // Minimum amount is converted to the default currency
            $minimum_amount = $this->minimum_amount;
            if ($this->minimum_amount_currency != Configuration::get('PS_CURRENCY_DEFAULT'))
            {
                $minimum_amount_currency = new Currency($this->minimum_amount_currency);
                if ($this->minimum_amount == 0 || $minimum_amount_currency->conversion_rate == 0)
                    $minimum_amount = 0;
                else
                    $minimum_amount = $this->minimum_amount / $minimum_amount_currency->conversion_rate;
            }

            $cartTotal = $context->cart->getOrderTotal($this->minimum_amount_tax, Cart::ONLY_PRODUCTS);
            if ($this->minimum_amount_shipping)
                $cartTotal += $context->cart->getOrderTotal($this->minimum_amount_tax, Cart::ONLY_SHIPPING);

            // If a product is given for free in this rule and already in the cart, the price is subtracted
            if ($this->gift_product && $alreadyInCart)
            {
                $query = new DbQuery();
                
                $query->select('id_product');
                $query->from('cart_product');
                $query->where('id_product = '.(int)$this->gift_product);
                $query->where('id_cart = '.(int)$context->cart->id);
                
                if ((int)$this->gift_product_attribute)
                    $query->where('id_product_attribute = '.(int)$this->gift_product_attribute);
                
                if (Db::getInstance()->getValue($query))
                {
                    $ref = false;
                    $product_price = Product::getPriceStatic(
                        $this->gift_product,
                        $this->minimum_amount_tax,
                        $this->gift_product_attribute,
                        null, null, false, true, 1, null,
                        $context->cart->id_customer ? $context->cart->id_customer : null,
                        $context->cart->id,
                        (int)$context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} ? (int)$context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} : null,
                        $ref, true, true, $context, true
                    );
                    $cartTotal -= $product_price;
                }
            }

            if ($cartTotal < $minimum_amount)
                return (!$display_error) ? false : Tools::displayError('You have not reached the minimum amount required to use this voucher');
        }
        
        // Check if the voucher is already in the cart of if a non compatible voucher is in the cart
        // Important note: this MUST be the last check, because if the tested cart rule has priority over a non combinable one in the cart, we will switch them
        $otherCartRules = $context->cart->getCartRules();
        if (count($otherCartRules))
            foreach ($otherCartRules as $otherCartRule)
            {
                if ($otherCartRule['id_cart_rule'] == $this->id && !$alreadyInCart)
                    return (!$display_error) ? false : Tools::displayError('This voucher is already in your cart');
                if ($this->cart_rule_restriction && $otherCartRule['cart_rule_restriction'] && $otherCartRule['id_cart_rule'] != $this->id)
                {
                    $combinable = Db::getInstance()->getValue('
                    SELECT id_cart_rule_1
                    FROM '._DB_PREFIX_.'cart_rule_combination
                    WHERE (id_cart_rule_1 = '.(int)$this->id.' AND id_cart_rule_2 = '.(int)$otherCartRule['id_cart_rule'].')
                    OR (id_cart_rule_2 = '.(int)$this->id.' AND id_cart_rule_1 = '.(int)$otherCartRule['id_cart_rule'].')');
                    if (!$combinable)
                    {
                        $cart_rule = new CartRule((int)$otherCartRule['id_cart_rule'], $context->cart->id_lang);
                        // The cart rules are not combinable and the cart rule currently in the cart has priority over the one tested
                        if ($cart_rule->priority <= $this->priority)
                            return (!$display_error) ? false : Tools::displayError('This voucher is not combinable with an other voucher already in your cart:').' '.$cart_rule->name;
                        // But if the cart rule that is tested has priority over the one in the cart, we remove the one in the cart and keep this new one
                        else
                            $context->cart->removeCartRule($cart_rule->id);
                    }
                }
            }
        
        if (!$display_error)
            return true;
}

(à placer dans override/classes/CartRule.php)

 

 

Cordialement,

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...