Carnet Wiki

paniers et commandes

Version 6 — Mai 2014 — 77.196.xx.xx

(De : Nathalie Brunelli, le 5 mai 2014 - complété le 21 mai 2014 )

Voici comment j’ai mis en place une boutique avec le trio Paniers-Commandes de Paniers-Commandes sous SPIP 3.
Le site sur lequel on peut voir le mécanisme en œuvre est bonplanmicro.com.
Étant donnée la demande particulière de mon client, je n’ai pas mis en place de paiement en ligne. Il s’agit donc plus exactement d’un bon de commande.

Ça bouge beaucoup du côté du plugin Commandes.

Étape 1
Installation et réglages de bases des plugins Pour ma part , j’ai installé Commandes + Commandes de paniers + Paniers Panier pour un site qui a pour vocation de proposer très exactement un bon de commande .

- Pour Commandes : [http://contrib.- Pour Commandes : la version du trunk (donc en cours de chamboulements) : http://zone.spip.net/Commandes-4527->http://contrib.spip.net/Commandes-4527]
org/trac/spip-zone/browser/_plugins_/commandes/trunk - Pour Pour Commandes de paniers :  : [http://plugins http://plugins .spip.net/panier2commande.html->http://plugins.spip.net/panier2commande.html]
html ( et sûrement de nouvelles choses sur la zone )
- Pour Pour Paniers : [http://plugins http://plugins .spip.net/paniers.html->http://plugins.spip.net/paniers.html]
html - La page qui m’a fait découvrir tout cela est ici : [http://contrib http://contrib .spip.net/Z-Commerce->http://contrib.spip.net/Z-Commerce] net/Z-Commerce

Ces plugins ont été développés il y a quelques mois déjà, sur une belle idée collective de créer un système d’e-commerce digne de ce nom basé sur Zpip, mais ça a été abandonné, puis repris par d’autres, des versions différentes existent un peu partout,
et il y a plein de dépendances à d’autres plugins . Récemment , certaines personnes très motivées ont repris A noter que ces pistes pour notre plus grand plaisir plugins font l’objet de nouveaux développements .
Il est à noter le fonctionnement très modulaire et la dépendance à certains plugins (notamment Saisies et API Prix) pour le bon fonctionnement de cette jolie mécanique (voir donc les docs respectives).

Étape 2
Création des champs extras sur la table spip_articles
 : pour l’affichage notamment de #PRIX et #PRIX_HT.

Étape 3
Préparation de la fiche-produit

Voici les étapes que j’ai suivies :

Je suis partie du squelette - D’abord , dans le fichier article ( à copier et renommer si on veut créer , tu insères un squelette dédié à notre boutique ) bouton d’ajout au panier  :

[(#BOUTON_ACTION{<:action_ajouter:>,#URL_ACTION_AUTEUR{remplir_panier,article-#ID_ARTICLE,#SELF},ajax})]   

-* Insertion de l’appel des champs créés pour mes besoins

  • Intégration du bouton « Ajouter au panier » :
    [(#BOUTON_ACTION{<:action_ajouter:>,#URL_ACTION_AUTEUR{remplir_panier,article-#ID_ARTICLE,#SELF},ajax})] &lt;/code >
     -*  -  Quelque part dans l'interface, j'ai mis le minipanier (fourni dans le plugin Paniers, dans noisettes/) :
    <code  class="spip">	<INCLURE{fond=inclure/minipanier}>	

    => dès qu’on clique sur le bouton, le minipanier se met à jour.
    -* Le bouton pour accéder au panier :

    [(#BOUTON_ACTION<:paniers:voir_mon_panier :>,[(#URL_PAGEcommande_panier|parametre_urllang, #LANG)]
    )]

    (oui, parametre #LANG car mon site est trilingue.
    Pour ceux qui sont dans le même cas, je laisse les références au multilinguisme... ayant perdu parfois du temps avec ça)

Étape 4
Page de visualisation du panier

-* Chez moi, elle s’appelle commande_panier.
-* J’appelle - Ensuite , j’ai créé une page qui récapitule le panier ( chez moi , elle s’appelle commande_panier ), dans laquelle j’ai mis ceci :
<code class=« spip »><div class=« spip  »> <div class=« ajax »>#FORMULAIRE_PANIER


=> on affiche alors trouve un tableau récapitulant les produits ajoutés au panier, leur quantité, leur prix, etc... avec la possibilité de modifier ces quantités (bouton Recalculer). )

En Et ( en dessous de ce code, ) j’ai inséré des boutons :

		<BOUCLE_ispanier(CONDITION){si #SESSION{id_panier}|oui}>
<table class="nobord" width="100%"><tr>
	            <td style="text-align:left" width="50%">[(#BOUTON_ACTION{<:mon_panier_vider:>,#URL_ACTION_AUTEUR{supprimer_panier_encours,'',#SELF},ajax})]</td>
	            <td style="text-align:right" width="50%">[(#BOUTON_ACTION{<:passer_etape_suivante:> 2 >>,[(#URL_PAGE{commande_validation}|parametre_url{lang, #LANG})]})]</td>
	            </tr></table>
	</BOUCLE_ispanier>

Pour appeler cette page :

	<BOUCLE_ispanier(CONDITION){si #SESSION{id_panier}|oui}>
     		 [(#BOUTON_ACTION{<:paniers:voir_mon_panier:>,[(#URL_PAGE{commande_panier}|parametre_url{lang, #LANG})]})]
	 </BOUCLE_ispanier>

Étape 5
Page de validation de la commande

-  Ma page commande_validation appelée contient :

	 [(#REM) Récap panier ]
	  <h2><:paniers:mon_panier:></h2>
	      <div class="ajax">#FORMULAIRE_PANIER</div>
	      <BOUCLE_ispanier(CONDITION){si #SESSION{id_panier}|oui}>
	     	 <table class="nobord" width="100%"><tr>
	     	 <td style="text-align:left" width="50%"> 
	   	   [(#BOUTON_ACTION{<:mon_panier_vider:>,#URL_ACTION_AUTEUR{supprimer_panier_encours,'',#SELF},ajax})]      
	    	  </td>
	  	    <td style="text-align:right" width="50%">
	 	     <BOUCLE_isclient(CONDITION){si #SESSION{id_auteur}|oui}>
	    	  [(#BOUTON_ACTION{<:commander:>  >>,#URL_ACTION_AUTEUR{commandes_paniers,'',#URL_PAGE{commande_terminee}|parametre_url{lang, #LANG}},ajax})]
	    	  </BOUCLE_isclient>
	      	</td>
	     	 </tr></table>
		</BOUCLE_ispanier>

Ce code provoque la transformation du panier en commande (c’est là qu’interviennent les bouts de code de Commandes de paniers). A cet instant, le panier est vidé, une commande est créée.
Commande que l’on trouve dans Dans l’espace privé ( Édition , dans Edition > Commandes). , tu y trouveras ta commande .

Étape 6
Page de remerciement

-  Ma dernière page commande_terminée comporte un message de remerciement et la liste des commandes associées à l’auteur connecté ceci :

      <B_traitement>
     <h2 class="gris"><:commande_merci:></h2>
      <p><:explication_fin_commande:></p>
      <h2 align="center"><:commande_recapitulatif:>
        
      #ANCRE_PAGINATION
      <BOUCLE_traitement(COMMANDES){id_auteur=#SESSION{id_auteur}}{statut?}{tout}{par date} {inverse}{pagination 5}><p><:commande_numero:>#REFERENCE&lt;/p >
       <p>&lt;:commande_date :>  :  #DATE&lt;/p >
       <p>&lt;:modifier_commande_statut :>  &#91;&lt;span  class="bleu">(#STATUT|commandes_lister_statuts)&lt;/span >] </p>
      
      <p><:details_commande:></p>
      <INCLURE{fond=inclure/commande,id_commande=#ID_COMMANDE,statut=#STATUT}>
      <div class="separator"></div>


<p><:commande_numero:>#REFERENCE</p>
      <p><:commande_date:> : #DATE</p>
      <p><:modifier_commande_statut:> [<span class="bleu">(#STATUT|commandes_lister_statuts)</span>]</p>
      
      <p><:details_commande:></p>
      <INCLURE{fond=inclure/commande,id_commande=#ID_COMMANDE,statut=#STATUT}>


</BOUCLE_traitement>
      [<p class="pagination">(#PAGINATION)</p>]
      </B_traitement>
      
      <p>message  d'erreur&lt;/p <p>&lt;:commande_probleme :>  &lt;:ou_pas_connecte 
            
      &lt;// B_traitement >
            
      &lt;//B_traitement >
 

La boucle interroge désormais la table Commandes et récapitule les articles qui s’y trouvent.


(de Tcharlss, le 6 mai 2014)

Depuis peu, Commandes prend en charge ces types « facturation » et « livraison ». Enfin, prendre en charge est un grand mot : il complète la liste des types proposés par la saisie #SAISIE{type_adresse}, qui est utilisée dans le formulaire d’édition d’une adresse, voilà tout.

Alors pour cette histoire de #TYPE sur les coordonnées, je crois que tu voulais des clarifications dans ton message précédent.
Le type sert à qualifier le lien entre une adresse un objet, et non pas l’adresse elle même. Là est la subtilité, il ne sert pas à dire : ceci est une adresse de type « livraison », mais : cette adresse est liée à cet objet en tant qu’adresse de type « livraison ». Autrement dit, le champ ’type’ n’est pas dans la table ’spip_adresses’, mais dans ’spip_adresses_liens’.
Tout l’intérêt, c’est qu’une même adresse peut être liée plusieurs fois à un objet grâce à ce champ ’type’. Par défaut, les tables de liens sont dépourvues de ce champ, ce qui fait qu’un objet ne peut-être lié à un autre objet qu’une seule fois : on ne peut par exemple associer un auteur à un article qu’une seule fois, tandis qu’on peut associer une adresse à un article plusieurs fois avec des types différents. (note : c’est aussi l’enjeu du plugin « rôles » de M.Marcillaud. Sauf qu’il parle de « rôle » au lieu de « type ».)

Si par exemple tu as un formulaire d’inscription perso, dans lequel tu veux proposer la saisie d’une adresse de livraison, tu peux faire comme ça :

-  Dans le squelette du formulaire, les champs de l’adresse doivent être nommés comme ceux du formulaire d’édition normal d’une adresse : ’voie’, ’complement’ etc.
Tu peux ne mettre que ceux qui t’intéressent d’ailleurs, c’est l’intérêt.

-  Dans les fonctions charger, verifier et traiter du formulaire, ’charger_fonction’ permet de réutiliser les fonctions de n’importe quel autre formulaire.
Par exemple, dans la fonction traiter, si tu rajoutes ceci en plus de tes traitements persos :

$associer_objet = "auteur|$id_auteur";
set_request('type','livraison');
// traitements du formulaire classique des adresses
$traiter_adresses_dist = charger_fonction('traiter', 'formulaires/editer_adresse');
$res = $traiter_adresses_dist('new',$retour,$associer_objet);

Hop, l’adresse va être créée et associée à l’auteur x, avec le type ’livraison’. Pour récupérer l’identifiant : $id_adresse = $res['id_adresse'];

Autrement, pour lier ponctuellement une adresse existante avec une commande par exemple :

include_spip('action/editer_liens');
objet_associer(array('adresse'=>$id_adresse), array('commande'=>$id_commande), array('type'=>'livraison'));

Mais attention ! Si jamais tu as besoin de lier 2 fois une même adresse à une commande, l’API a une limitation : elle est actuellement conçue pour faire un unique lien d’objet à objet. Donc en faisant comme suit, le 2e lien va écraser le premier (à moins d’avoir le plugin ’rôle’ installé) :

objet_associer(array('adresse'=>$id_adresse), array('commande'=>$id_commande), array('type'=>'livraison'));
objet_associer(array('adresse'=>$id_adresse), array('commande'=>$id_commande), array('type'=>'facturation'));

Dans ce cas là, il faut faire les liens « à la main » :

sql_insertq( 'spip_adresses_liens', array(
                'id_adresse' => $id_adresse,
                'objet' => 'commande',
                'id_objet' => $id_commande,
                'type' => 'livraison'
                )
            );
// idem pour facturation