Tutoriel : Règles de prix panier + bonus promotions avancées

janvier 22nd, 2015 | by | magento

Jan
22

Les règles de prix catalogue ou panier pour gérer des promotions peuvent devenir rapidement très compliquées et entrainer des erreurs ou des oublis. Nous allons voir précisemment dans cet article comment créer ces règles, avec les conditions à mettre, les actions à faire et toutes les options disponibles. Nous verrons également des exemples précis sur lesquels vous pourrez vous appuyer pour des règles plus complexes.

Les règles de prix panier ont 4 options :

  • Remise en pourcentage du prix du produit
  • Remise d'une valeur fixe
  • Remise d'une valeur fixe pour l'ensemble du panier
  • X achetés, Y gratuits (la valeur de la remise est Y)

Pour créer une nouvelle règle, nous avons à renseigner des champs obligatoires indiqués par une petite étoile rouge.

 

Règles de prix panier

 

Remise en pourcentage du prix du produit

Produit en promotion par rapport au prix original. Par exemple : Lorsque l'on renseigne une valeur de 15 dans le champ "Remise" cela veut dire que le prix final du produit sera le prix original avec une réduction de 15%.
Il y a plusieurs options à notre disposition, voici les 4 sections :

  • X% pour tout
  • X% pour une catégorie particulière
  • X% pour des produits spécifiques
  • X% pour des produits spécifiques lorsque vous en commandez plus de Y

Pour paramétrer l'option "Remise en pourcentage du prix du produit" vous devez suivre les étapes suivantes

Depuis le tableau de bord, aller dans "Promotions" -> "Règles de prix panier". Cette page affiche toutes les promotions de votre boutique, vous pouvez les modifier ou les supprimer. Pour ajouter une nouvelle réduction, cliquez sur "Ajouter une nouvelle règle" en haut à droite de l'écran. Remplissez l'onglet "Informations générales" comme indiqué précédemment.

Pour paramétrer le "X% pour tout" vous devez suivre les étapes suivantes :Voici un exemple avec 15% de réduction.

Onglet Conditions : Pas besoin de cet onglet pour ce paramétrage.

Onglet Actions : Suivre les indications sur la capture d'écran ci-dessous. Une fois celles-ci faites, cliquez sur "Sauvegarder".

 

Remise en pourcentage du prix du produit

 

Pour paramétrer l'option "X% pour une catégorie particulière" vous devez suivre les étapes suivantes : Voici un exemple avec 15% de réduction sur une seule catégorie.

Onglet Conditions : Pas besoin de cet onglet pour ce paramétrage.

Onglet Actions : Suivre les indications sur la capture d'écran ci-dessous. Une fois celles-ci faites, cliquez sur "Sauvegarder".

 

X% pour une catégorie particulière

 

Pour paramétrer l'option "X% pour des produits spécifiques" vous devez suivre les étapes suivantes : Voici un exemple avec 15% de réduction sur les 3 produits ayant ces SKU.

Onglet Conditions : Pas besoin de cet onglet pour ce paramétrage.

Onglet Actions : Suivre les indications sur la capture d'écran ci-dessous. Une fois celles-ci faites, cliquez sur "Sauvegarder".

 

X% pour des produits spécifiques

 

Pour paramétrer l'option "X% pour des produits spécifiques lorsque vous en commandez plus de Y" vous devez suivre les étapes suivante

Pour faire une réduction en pourcentage sur des produits spécifiques de votre boutique seulement si un client commande un certains nombre de ces produits, suivez ces étapes. Dans l'exemple nous ferons 15% sur 3 SKU différents si le client commande 5 produits ou plus de ces 3 SKU.

Onglet Conditions : Sélectionnez "Sous-sélection de produits" en cliquant sur le petit + vert et créez la condition si le panier contient 5 produits ou plus sur une combinaison de 3 produits.

 

X% pour des produits spécifiques lorsque vous en commandez plus de Y

 

Onglet Actions : Appliquer la promotion seulement pour les 2 produits avec les SKU définis et pas sur les autres produits du panier. Une fois que vous renseignez les éléments, cliquez sur sauvegarder.

 

X% pour des produits spécifiques lorsque vous en commandez plus de Y

 

Remise d'une valeur fixe

Cette option est pour faire une remise fixe du prix original de chaque produit dans votre panier. Par exemple : En mettant 5 dans "Remise" cela signifie que le prix final du produit aura 5€ de réduction.

Pour paramétrer "Remise d'une valeur fixe" vous devez suivre les étapes suivantes :

Onglet Conditions : Pas besoin de cet onglet pour ce paramétrage.

Onglet Actions : Sélectionnez simplement "Remise d'une valeur fixe" dans "Appliquer" puis mettez 5 dans "Remise". Même si c'est très simple, testez quand même sur votre site.

 

Remise d'une valeur fixe

 

Remise d'un montant fixe pour l'ensemble du panier

C'est exactement le même paramétrage que "Remise d'une valeur fixe" sauf qu'au lieu d'imputer la remise à chaque produit dans le panier, cela ne se fera qu'une seule fois sur le montant total.

X achetés, Y gratuits (la valeur de la remise est Y)

Pour paramétrer "X achetés, Y gratuit" vous devez suivre les étapes suivantes :

Onglet Conditions : Pas besoin de cet onglet pour ce paramétrage.

Onglet Actions : Dans notre exemple nous allons offrir 1 produit pour l'achat de 5 produits identiques. Dans le champ remise cela va être le nombre de produits offerts, donc 1. Dans le champ "Quantité pour obtenir la remise (Achetez-en X)" mettre 5. Vous pouvez n'appliquer cette offre qu'à certains produits en utilisant la partie en dessous "Appliquer la règle seulement aux articles du panier qui remplissent les conditions suivantes" comme nous l'avons vu précédemment.

 

X achetés, Y gratuit

 

Nous avons vu toutes les options ou presque disponible sous Magento.
En revanche il arrive qu'il faille aller plus loin dans les règles de promotion et pour cela je vous conseille le module Special Promotions d'Amasty qui permet bien plus de choses :

- Avoir une réduction si le montant total du panier est supérieur à un prix fixe. Acheter des produits pour 500€ et avoir une remise sur le produit le moins cher (ou le plus cher) sélectionné dans certaines catégories.
- Paramétrer n'importe quelle combinaison de réduction avec les produits les moins chers ou les plus chers. Acheter 5 produits et avoir le plus cher avec 60% de réduction.
- Chaque n-ième produit pour un prix fixe. Acheter une télévision et en avoir une autre pour seulement 200€.
- Chaque n-ième produit avec une réduction. Chaque 2ème t-shirt (3ème, 4ème…) avec 20%, 30%, 40% ou même gratuit.
- Acheter X et avoir Y avec une réduction. Acheter 2 téléphones et obtenir 50% de réduction sur les écouteurs.
- Acheter X et avoir Y à un prix fixe. Acheter un ordinateur portable et obtenir un sac pour seulement 50€
- Tous les produits après N à un prix fixe. Acheter 3 produits au tarif normal (60€) et payer seulement 50€ pour les suivants.
- Tous les produits après N avec une réduction. Acheter 4 produits et avoir 20% de réduction sur les suivants.
- Afficher les différentes remises séparemment. "30€ de reduction sur chaque ordinateur : Lenovo G580 - 135€"
- Et bien d'autre choses...

Vous avez également une version Pro : Lien vers la version Pro qui permet en plus :

- Créer des remises suivant le nombre de commande que les clients ont passées. 20% pour tous les clients qui ont fait plus de 10 commandes.
- Créer des remises suivant le nombre de jours depuis l'inscription du client. 10% de réduction pour les clients qui sont membre de la boutique depuis déjà un an.
- Et bien d'autre choses...

Le support est réactif et vous avez une FAQ très complète pour pouvoir paramétrer le module comme vous le souhaitez.

No Comments »

Augmenter le nombre maximun de produits par categorie

janvier 14th, 2015 | by | magento

Jan
14

 

Suite à la migration d'un client sur un nouveau serveur j'ai été confronté à un problème pour ajouter des produits au dela de 1000 pour une catégorie.
Les produits étaient ajoutés puis lorsque l'on sauvegardait nous avions bien le message disant que la catégorie avait bien été sauvegardée mais les produits n'étaient pas ajoutés…

Le problème vient de la variable php max_input_vars.
Le plus simple est d'augmenter cette valeur dans votre php.ini ou via votre htaccess mais nous allons voir comment modifier cela uniquement pour la sauvegarde des catégories sur Magento.

Nous allons donc surcharger le contrôleur d'administration des catégories.

Il faut donc créer un fichier config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- /app/code/local/NAMESPACE/Categorylimit/etc/config.xml -->
<config>
   ...
   <admin>
      <routers>
         <adminhtml>
            <args>
               <namespace_categorylimit before="Mage_Adminhtml">Namespace_Categorylimit_Adminhtml</namespace_catergorylimit>
            </args> 
         </adminhtml>
      </routers>
   </admin>
   ...
</config>

Ce fichier dit à Magento d'appeler notre module avant "Mage_Adminhtml". Il reste donc à surcharger la methode save du CategoryController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
// /app/etc/local/NAMESPACE/Categorylimit/controllers/Adminhtml/Catalog/CategoryController.php
 
class Namespace_Categorylimit_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Catalog_CategoryController
{
 
  /**
     * Category save
     */
    public function saveAction()
    {
        if (!$category = $this->_initCategory()) {
            return;
        }
 
        $storeId = $this->getRequest()->getParam('store');
        $refreshTree = 'false';
        if ($data = $this->getRequest()->getPost()) {
            $category->addData($data['general']);
            if (!$category->getId()) {
                $parentId = $this->getRequest()->getParam('parent');
                if (!$parentId) {
                    if ($storeId) {
                        $parentId = Mage::app()->getStore($storeId)->getRootCategoryId();
                    }
                    else {
                        $parentId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
                    }
                }
                $parentCategory = Mage::getModel('catalog/category')->load($parentId);
                $category->setPath($parentCategory->getPath());
            }
 
            /**
             * Process "Use Config Settings" checkboxes
             */
            if ($useConfig = $this->getRequest()->getPost('use_config')) {
                foreach ($useConfig as $attributeCode) {
                    $category->setData($attributeCode, null);
                }
            }
 
            /**
             * Create Permanent Redirect for old URL key
             */
            if ($category->getId() && isset($data['general']['url_key_create_redirect']))
            // && $category->getOrigData('url_key') != $category->getData('url_key')
            {
                $category->setData('save_rewrites_history', (bool)$data['general']['url_key_create_redirect']);
            }
 
            $category->setAttributeSetId($category->getDefaultAttributeSetId());
 
            if (isset($data['category_products']) &&
                !$category->getProductsReadonly()) {
                $products = array();
                $cat_products_array = explode('&', $data['category_products']);
foreach($cat_products_array as $products) {
    $temp_array = array();
    parse_str($products, $temp_array);
    list($key, $val) = each($temp_array);
    if (!empty($key) && !empty($val)) {
        $products[$key] = $val;
    }
}
                $category->setPostedProducts($products);
            }
 
            Mage::dispatchEvent('catalog_category_prepare_save', array(
                'category' => $category,
                'request' => $this->getRequest()
            ));
 
            /**
             * Proceed with $_POST['use_config']
             * set into category model for proccessing through validation
             */
            $category->setData("use_post_data_config", $this->getRequest()->getPost('use_config'));
 
            try {
                $validate = $category->validate();
                if ($validate !== true) {
                    foreach ($validate as $code => $error) {
                        if ($error === true) {
                            Mage::throwException(Mage::helper('catalog')->__('Attribute "%s" is required.', $category->getResource()->getAttribute($code)->getFrontend()->getLabel()));
                        }
                        else {
                            Mage::throwException($error);
                        }
                    }
                }
 
                /**
                 * Check "Use Default Value" checkboxes values
                 */
                if ($useDefaults = $this->getRequest()->getPost('use_default')) {
                    foreach ($useDefaults as $attributeCode) {
                        $category->setData($attributeCode, false);
                    }
                }
 
                /**
                 * Unset $_POST['use_config'] before save
                 */
                $category->unsetData('use_post_data_config');
 
                $category->save();
                Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('catalog')->__('The category has been saved.'));
                $refreshTree = 'true';
            }
            catch (Exception $e){
                $this->_getSession()->addError($e->getMessage())
                    ->setCategoryData($data);
                $refreshTree = 'false';
            }
        }
        $url = $this->getUrl('*/*/edit', array('_current' => true, 'id' => $category->getId()));
        $this->getResponse()->setBody(
            '<script type="text/javascript">parent.updateContent("' . $url . '", {}, '.$refreshTree.');</script>'
        );
    }
}

En fait la modification porte sur cette ligne :

1
parse_str($data['category_products'], $products);

que l'on remplace par :

1
2
3
4
5
6
7
8
9
$cat_products_array = explode('&', $data['category_products']);
foreach($cat_products_array as $products) {
    $temp_array = array();
    parse_str($products, $temp_array);
    list($key, $val) = each($temp_array);
    if (!empty($key) && !empty($val)) {
        $products[$key] = $val;
    }
}

Pour expliquer, on découpe les produits de la catégorie une plusieurs morceaux pour ne plus être limiter par le serveur.

Il ne reste plus qu'à déclarer notre module app/etc/modules/Namespace_Categorylimit.xml

No Comments »

Résoudre le problème « Index process is working now. Please try run this process later »

décembre 29th, 2014 | by | magento

Déc
29

Lorsque l'on essaie de ré-indexer les données de Magento, il arrive que l'on tombe sur cette erreur et une fois tombé dessus, difficile de s'en sortir sans manipulation spécifique.
Vider le cache ne solutionne pas le problème. La solution se trouve dans le dossier /var/locks/. Le site créé un fichier, avec un id correspondant à chaque type d'indexation, pour dire qu'il est en cours de ré-indexation et bloquer tout autre action.
Sauf que parfois ces fichiers ne sont pas supprimés : manque de droit, indexation non terminée normalement...

Il faut donc supprimer tous les fichiers du dossier /var/locks/ et mettre ce dossier en 755 (ou 777 s'il le faut) pour que le serveur puisse recréer les fichiers .lock

Si cela ne fonctionne toujours pas, il faudra certainement aller voir du coté du script /shell/indexer.php pour indexer manuellement.

Et voilà, vous pouvez ré-indexer toutes vos données !

No Comments »

SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED

octobre 29th, 2014 | by | magento, sql

Oct
29

 

Cette erreur est survenue un jour ou j'ai voulu supprimer un produit dans le backoffice.

 

SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`DBNAME`.`q`.`items_count` - 1)'

 

Impossible de supprimer le produit !

Voici la solution :

- Allez dans votre base de données et faites une sauvegarde (toujours)
- Allez dans la table sales_flat_quote et affichez la structure- Modifiez le champ items_count et modifiez l'attribut en "Blank"
- Sauvegardez

 

Qu'est ce que signifie l'attribut UNSIGNED ?

Avec le petit tableau qui va bien

 

No Comments »

Désactiver les logs dans la base de données sur Magento

octobre 20th, 2014 | by | magento

Oct
20

A la recherche d'optimisations pour améliorer la vitesse de chargement de Magento, je me suis penché sur les logs.

Car Magento logs énormément de choses et pas seulement dans les fichiers du dossier var/log, il enregistre énormément de choses dans la base de donnés notamment sur les clients.

Cela prend beaucoup de ressource car fait appel à la base pour chaque insertion mais l’alourdi également inutilement.
On se retrouve rapidement avec plusieurs centaines de Mo voir Go de logs.

Désactiver le log dans System > Configuration > Advanced > Disable Modules Output ne suffit pas car il n'a pas de "output" à proprement parlé.

De plus, modifier dans System > Configuration > Developer > Log Settings > Enabled désactivera seulement les logs fichier du dossier var/log

Pour vraiment arrêter les logs sql voici comment faire :

1 - Ouvrir le fichier app/etc/local.xml

2 - Insérer ce code avant la balise fermante </config>

<frontend>
    <events>
        <controller_action_predispatch>
            <observers><log><type>disabled</type></log></observers>
        </controller_action_predispatch>
        <controller_action_postdispatch>
            <observers><log><type>disabled</type></log></observers>
        </controller_action_postdispatch>
        <customer_login>
            <observers><log><type>disabled</type></log></observers>
        </customer_login>
        <customer_logout>
            <observers><log><type>disabled</type></log></observers>
        </customer_logout>
        <sales_quote_save_after>
            <observers><log><type>disabled</type></log></observers>
        </sales_quote_save_after>
        <checkout_quote_destroy>
            <observers><log><type>disabled</type></log></observers>
        </checkout_quote_destroy>
    </events>
</frontend>

3 - sauvegarder le fichier

4 - Aller dans System > Configuration > Advanced et mettre Disable pour Mage_Log

5 - Pour finir, nettoyer le cache dans System > Cache Management

Magento n'écrira plus dans les tables de logs !

Ce n'est pas fini car il faut maintenant vider ces tables.

Toujours faire une sauvegarde quand on modifie la base !

Il suffit donc de faire des TRUNCATE :

TRUNCATE log_customer;
TRUNCATE log_quote;
TRUNCATE log_summary;
TRUNCATE log_summary_type;
TRUNCATE log_url;
TRUNCATE log_url_info;
TRUNCATE log_visitor;
TRUNCATE log_visitor_info;
TRUNCATE log_visitor_online;
TRUNCATE report_event;

 

 

No Comments »