Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer :Approvisionnement des stocks en Php
Dans la formation précédente, nous avons appris à établir les
relations entre les tables d'une base de données MySql. Ces liaisons sont fondamentales pour appliquer la
règle de l'intégrité référentielle et permettre les
mises à jour en cascade. Bref nous assurons la sécurité des données et préservons leur intégrité. Cette
base de données permet d'archiver les commandes des clients au travers de quatre tables. C'est sur cette ossature que nous allons monter certaines applications.
La première consiste à offrir une
interface Web permettant la
mise à jour des stocks, par le jeu des approvisionnements du magasin.
Sources et présentation de la problématique
Cette conception requière de nombreuses sources que nous proposons de réceptionner.
La décompression conduit au fichier de la page Web principale, nommé
index.php. Il s'agit de l'interface Html destinée à gérer l'approvisionnement des stocks. Ce fichier est accompagné de certaines pages satellites à la racine et de ses ressources externes dans les sous dossiers.
Comme vous le savez, ce projet doit être référencé dans
EasyPhp. Un nom doit lui être attribué et son adresse issue de l'explorateur Windows doit être renseignée. Les deux serveurs,
Http et Database Server doivent être démarrés.
Dès lors, vous pouvez accéder à l'
interface d'administration PhpMyAdmin en cliquant sur le
bouton Open du module MySql Administration.
Si vous avez suivi la formation précédente, vous devez disposer de la
base de données stocks, composée de cinq tables, dont quatre sont reliées entre elles.
Si vous ne la possédez pas, vous devez créer la base de données stocks avec le
système d'interclassement utf8_general_ci. Vous devez alors y importer le
fichier stocks.sql situé dans le
sous dossier bdd du dossier de décompression. De même, vous devez créer le compte utilisateur avec les droits d'accès, selon les informations suivantes :
- Nom d'utilisateur : gStock,
- Nom d'hôte : l'adresse locale, ici : 127.0.0.1,
- Mot de passe : gS123k12,
Ces informations sont en effet exploitées dans le
fichier connexion.php, situé dans le
sous dossier commun, pour
établir la connexion à la base de données MySql.
- Dans le volet de gauche, déployer l'arborescence de la base de données stocks,
- Puis, cliquer sur le lien de la table articles pour afficher son contenu,
C'est cette table précisément qui va retenir toute notre attention pour le développement de l'application Web destinée Ã
gérer l'approvisionnement des stocks. Les produits du magasin y sont référencés de façon unique, sur le
champ Article_code de la clé primaire. Et c'est le
champ Article_Qte que nous devons mettre à jour par le
code Php, en fonction des
approvisionnements.
- Depuis l'interface d'EasyPhp, cliquer sur le lien du projet pour afficher sa page d'accueil,
Si aucune erreur n'est générée, cela signifie que la base de données existe bien et que le compte utilisateur a correctement été créé.
Sur cette interface, une
liste déroulante Html doit proposer à l'administrateur de choisir la référence à actualiser. Au chargement, nous devons donc la remplir par le
code Php, en fonction des références détenues dans la
table MySql articles. Au choix validé, certaines de ses informations doivent être réceptionnées et affichées, comme la désignation du produit et sa quantité en stock. L'administrateur doit alors saisir la nouvelle quantité livrée. Dès lors, après un clic sur le bouton, le
stock doit être mis à jour en
base de données MySql et la nouvelle quantité doit être livrée dans le dernier champ.
Remplir une liste déroulante par le code Php
Nous devons donc questionner la
table articles par le
code Php. Il s'agit d'exécuter une simple
requête SQL. Nous avions mis en oeuvre ces techniques notamment dans la
formation pour relier des listes déroulantes sur une page Web. Il est question de parcourir chaque
enregistrement extrait à l'aide d'une
boucle afin de reconstruire dynamiquement le
contenu Html de la liste déroulante.
- A la racine du dossier de décompression, cliquer droit sur le fichier index.php,
- Dans le menu contextuel, choisir de l'ouvrir avec un éditeur tel que le Notepad ++,
A partir de la ligne 34, vous notez la présence du
formulaire Html:
...
<form id="formulaire" name="formulaire" method="post" action="rep_stock.php">
<div class="titre_h1" style="height:250px;">
<div style="width:10%; height:75px; float:left;"></div>
<div style="width:35%; height:75px; float:left; font-size:16px; font-weight:bold; text-align:left;">
Référence à mettre à jour :<br />
<select id="ref_produit" name="ref_produit">
<option value="0">Choisir une référence</option>
<?php
?>
</select>
</div>
...
La méthode de ce dernier est
post. La page appelée pour le traitement est
rep_stock.php. Il s'agit donc d'un code à externaliser afin d'exploiter la
technologie Ajax permettant de ne pas recharger toute la
page Web. Mais nous n'en sommes pas encore là . Nous souhaitons remplir la
liste déroulante ref_produit. Elle est bien déclarée dans ce formulaire grâce à la
balise Html Select. Elle possède déjà une ligne, celle de la proposition par défaut, grâce à sa
balise option. Ce sont ces balises que nous devons inscrire à la suite, autant de fois qu'il existe de références article dans la
base de données MySql. C'est pourquoi, une
section de code Php vierge est prévue juste en dessous.
- Dans les bornes de la section Php, ajouter les lignes suivantes :
...
<select id="ref_produit" name="ref_produit">
<option value="0">Choisir une référence</option>
<?php
$requete = "SELECT Article_code FROM articles ORDER BY Article_code;";
$retours = mysqli_query($liaison, $requete);
while($retour = mysqli_fetch_array($retours))
{
echo "<option value='".$retour["Article_code"]."'>".$retour["Article_code"]."</option>";
}
?>
</select>
...
Il s'agit désormais de techniques classiques que nous maîtrisons sur le bout des doigts. Nous stockons la
syntaxe de la requête Sql dans une variable que nous nommons
$requete. Elle extrait toutes les références (SELECT Article_code) à partir de la table articles (FROM articles) en les restituant dans l'ordre alphabétique croissant (ORDER BY Article_code). C'est alors la
fonction Php mysqli_query qui exécute cette requête passée en second paramètre, selon les informations de connexion passées en premier paramètre. Il en résulte un
tableau de variables des enregistrements que nous stockons dans la
variable $retours. Nous découpons son information grâce à la
fonction mysqli_fetch_array. Cette action est entreprise dans une
boucle while, permettant de réceptionner les champs jusqu'au dernier enregistrement. Et à chaque passage dans la boucle, donc pour chaque référence, nous construisons une ligne supplémentaire pour la
liste déroulante Html (<option). Nous concaténons son information avec celle du champ réceptionné ($retour["Article_code"]).
- Enregistrer les modifications (CTRL + S) et basculer sur la fenêtre du navigateur,
- Rafraîchir la page Web à l'aide de la touche F5 du clavier par exemple,
- Puis, déployer la liste déroulante,
Comme vous le remarquez, toutes les références issues de la
table articles ont parfaitement été réceptionnées pour remplir la
liste déroulante Html. L'administrateur n'a plus qu'à désigner celle qu'il s'agit d'approvisionner.
Il est important de comprendre que nous avons pu directement
exécuter une requête Sql sur la
base de données, grâce à l'initialisation de la chaîne de connexion ($liaison), dans le
fichier connexion.php. Celui-ci est déclaré dans la
construction par imbrications.
Extraire les données d'une référence
Pour restituer la désignation et la quantité du produit, nous devons exécuter une nouvelle
requête Sql, mais avec
clause Where cette fois. Cette clause doit porter sur la référence de l'article désigné pour isoler les informations de son enregistrement. Ce code doit être déclenché au choix dans la liste déroulante. Il doit être exécuté dans la
page externe rep_stock.php, appelée à soumission du formulaire.
C'est la
fonction javascript recolter placée en entête de code qui doit se charger de réceptionner la valeur du traitement.
...
<script language='javascript' type="text/javascript">
function recolter()
{
document.getElementById("formulaire").request({
onComplete:function(transport){
document.getElementById('qte_produit_aps').value = transport.responseText;
}
});
}
</script>
...
Elle exploite des propriétés et méthodes issues de la classe ajoutée en référence dans le fichier
entete.php. Cette classe émane du
fichier prototype.js, placé dans le
sous dossier js du dossier de décompression. Tous les éléments nécessaires sont donc déjà déclarés et imbriqués. Nous avions en effet démontré ces techniques dans la
formation Php pour relier des listes déroulantes.
Mais ce fichier externe est amené à réaliser deux traitements différents. Il peut s'agir de la récupération des informations d'une référence. Il peut aussi s'agir de la
mise à jour des stocks, au clic sur le bouton. Nous devons transmettre un paramètre qui identifiera de façon explicite le traitement à entreprendre. Et pour cela, nous avons besoin d'une petite zone de saisie masquée pour porter la valeur.
- Dans le formulaire, sous la liste déroulante, ajouter le contrôle input suivant :
...
}
?>
</select>
<input type="text" id="tampon" name="tampon" style="visibility:hidden;" />
</div>
...
Cette zone de texte est masquée (style="visibility:hidden;") et est identifiée sous le
nom tampon.
Désormais, au changement de valeur dans la
liste déroulante, le traitement serveur doit être appelé, juste après avoir inscrit le paramètre du traitement dans la zone de texte.
- Ajouter l'évènement onchange à la liste déroulante, comme suit :
...
Référence à mettre à jour :<br />
<select id="ref_produit" name="ref_produit" onchange="document.getElementById('tampon').value = 'recup';recolter();">
<option value="0">Choisir une référence</option>
<?php
...
Au choix d'une référence, le paramètre recup est inscrit dans la zone de texte. C'est la
méthode Javascript getElementById de l'objet document qui permet de pointer sur le contrôle tampon passé en paramètre. Sa
propriété value permet alors d'accéder à son contenu, que nous affectons. Puis, dans la foulée, nous appelons la
fonction recolter. Cette action a pour effet de
soumettre le formulaire. Donc le paramètre de la zone de texte sera bien transmis pour que le code serveur puisse aviser.
- A la racine du dossier de décompression, cliquer droit sur le fichier rep_stock.php,
- Dans le menu contextuel, choisir de l'ouvrir avec le Notepad,
Vous notez la présence d'un
code Php existant. Il permet d'initialiser la
connexion à la base de données. C'est ainsi que nous pourrons exécuter les
requêtes Sql. A l'issue, nous prenons soin de fermer cette connexion pour libérer les ressources.
<?php
$liaison2 = mysqli_connect('127.0.0.1', 'gStock', 'gS123k12');
mysqli_select_db($liaison2, 'stocks');
mysqli_close($liaison2);
?>
Avant la fermeture de la connexion, nous devons réaliser le traitement serveur. Ce
traitement Php est conditionnel. Si le paramètre transmis est le
texte recup, nous devons exécuter une
requête sélection pour restituer les informations liées à la référence sélectionnée dans la liste déroulante. Sinon, nous devons exécuter une
requête Sql de mise à jour (Update) pour actualiser les stocks de la référence choisie. Comme vous le savez, c'est l'
instruction Php $_POST qui permet de réceptionner les valeurs transmises, issues des
contrôles Html encapsulés dans le
formulaire.
- Avant la fermeture de la connexion, ajouter l'instruction Php conditionnelle suivante :
...
mysqli_select_db($liaison2, 'stocks');
if(isset($_POST["tampon"]) && $_POST["tampon"]=="recup")
{
}
else
{
}
mysqli_close($liaison2);
...
Grâce à la
fonction Php isset, nous testons l'existence du contenu transmis. Dans le même temps, nous vérifions si ce paramètre indique qu'il s'agit de réceptionner les informations liées à la référence ($_POST["tampon"]=="recup"). Si ce paramètre ne vaut pas le texte recup (else), nous prévoyons le traitement pour la mise à jour du stock.
- Dans la branche If de l'instruction conditionnelle, ajouter les lignes Php suivantes :
...
if(isset($_POST["tampon"]) && $_POST["tampon"]=="recup")
{
$requete = "SELECT * FROM articles WHERE Article_code ='".$_POST["ref_produit"]."';";
$retours = mysqli_query($liaison2, $requete);
$retour = mysqli_fetch_array($retours);
$chaine = $retour["Article_designation"]."|".$retour["Article_Qte"];
print($chaine);
}
else
{
}
...
Nous mémorisons la
syntaxe Sql de la requête permettant d'extraire toutes les informations (SELECT *) de la table articles (FROM articles), pour lesquelles la référence est celle choisie par l'utilisateur (WHERE Article_code ='".$_POST["ref_produit"]."'). Nous exécutons cette requête sur la base de données MySql, comme toujours grâce à la
fonction Php mysqli_query. Comme cette référence est issue du
champ de la clé primaire, il en résulte un enregistrement unique. Donc, il n'est nul nécessaire d'enclencher une boucle pour les parcourir. C'est pourquoi, nous exploitons directement la
fonction Php mysqli_fetch_array afin de découper les informations de l'enregistrement sur les champs qu'il contient. Nous n'avons plus qu'à les réceptionner par leurs noms. C'est ce que nous faisons en les concaténant dans une chaîne de texte. Notez l'utilisation du caractère remarquable de la barre verticale (|). Nous l'exploiterons à réception pour dissocier les données et les ventiler dans les
contrôles Html respectifs. C'est l'
instruction Print qui permet de renvoyer le résultat du traitement à la page appelante.
- Enregistrer les modifications et revenir sur le code de la page index.php,
Dans le
traitement Ajax de la
fonction Javascript recolter, nous devons réceptionner ces informations. Mais cette réception est une fois de plus conditionnelle. Si le paramètre transmis est le
texte recup, nous devons découper l'information pour renseigner les
contrôles Html des_produit et
qte_produit_avt. Dans le cas contraire, il s'agit d'un
approvisionnement de stocks. Donc nous devons actualiser l'information du
contrôle qte_produit_aps. Souvenez-vous, c'est la
propriété responseText de l'
objet transport qui permet de récupérer la donnée du traitement externalisé.
- Adapter le code Javascript de la fonction recolter, comme suit :
...
<script language='javascript' type="text/javascript">
function recolter()
{
document.getElementById("formulaire").request({
onComplete:function(transport){
if(document.getElementById('tampon').value == 'recup')
{
var tab_info = transport.responseText.split('|');
document.getElementById('des_produit').value = tab_info[0];
document.getElementById('qte_produit_avt').value = tab_info[1];
}
else
{
document.getElementById('qte_produit_aps').value = transport.responseText;
}
}
});
}
</script>
...
Nous réalisons de nouveau le test sur le paramètre transmis, mais cette fois à l'aide d'une
instruction conditionnelle Javascript. S'il s'agit du texte recup, nous savons que l'information est détenue dans une chaîne, séparée par le caractère remarquable de la barre verticale. C'est pourquoi nous exploitons la méthode split pour tronçonner l'information dans un tableau de variables (tab_info), affecté à la volée. Puis, nous affectons les
contrôles Html respectifs dans l'ordre où ces éléments ont été empilés. La désignation est mémorisée dans la première rangée (tab_info[0]). La quantité est stockée dans la deuxième colonne du tableau (tab_info[1]).
Dans le cas contraire (else), nous conservons l'instruction qui était proposée par défaut. Elle consiste à retranscrire la
quantité mise à jour, dans le contrôle Html prévu à cet effet. Mais nous n'avons pas encore développé le code serveur Php dédié.
- Enregistrer les modifications (CTRL + S) et basculer sur la fenêtre du navigateur,
- Rafraîchir la page Web à l'aide de la touche F5 du clavier,
- Puis, choisir une référence dans la liste déroulante,
La désignation et la quantité rattachées au produit sélectionné sont instantanément récupérées et restituées sur la page Html, dans leurs contrôles respectifs. Grâce à la
technologie Ajax, le traitement est réalisé sans recharger la page Web. Les mises à jour sont chirurgicales.
Mise à jour des stocks
Nous devons maintenant traiter le cas de l'
approvisionnement du stock pour la référence sélectionnée. L'administrateur choisit une référence, saisit la quantité à ajouter au stock et valide en cliquant sur le bouton. Ce clic doit d'abord saisir un autre paramètre dans le contrôle Html masqué. Puis il doit appeler le traitement serveur, soit la
fonction recolter. Ce traitement serveur doit exécuter une
requête Sql de mise à jour (Update) pour ajouter la quantité inscrite, dans la
table MySql.
- Revenir dans le code de la page index.php,
- Ajouter le gestionnaire d'évènement dans la balise Html du bouton, comme suit :
...
<div style="width:10%; height:75px; float:left;"></div>
<div style="width:35%; height:75px; float:left; font-size:16px; font-weight:bold; text-align:left;">
<input type="button" id="valider" name="valider" value="Valider la mise à jour" onclick="document.getElementById('tampon').value = 'maj';recolter();"/>
</div>
...
Au clic sur le bouton, nous changeons le paramètre transmis par le
contrôle Html tampon. Cette action aura pour effet de basculer le traitement serveur dans la
branche else du code externalisé. Puis, comme précédemment, nous appelons la fonction de réception des données, soit la
fonction Javascript recolter.
- Enregistrer les modifications (CTRL + S) et basculer dans le code de la page rep_stock.php,
- Dans la branche else, ajouter les instructions Php suivantes :
...
$chaine = $retour["Article_designation"]."|".$retour["Article_Qte"];
print($chaine);
}
else
{
$requete = "UPDATE articles SET Article_Qte = Article_Qte + ".$_POST['qte_produit']." WHERE Article_code ='".$_POST["ref_produit"]."';";
$retours = mysqli_query($liaison2, $requete);
if($retours==1)
print("ok");
else
print("nok");
}
mysqli_close($liaison2);
...
Nous mettons à jour (Update) le champ Article_Qte de la table articles (SET Article_Qte) en l'incrémentant de la valeur saisie par l'administrateur ($_POST['qte_produit']) pour la référence désignée grâce à la liste déroulante (WHERE Article_code ='".$_POST["ref_produit"]."'). Nous exécutons cette requête sur la base de données grâce à la
fonction Php mysqli_query. Grâce à cette
clause Where, si la mise à jour réussit, une seule ligne est affectée. Donc si la variable de stockage $retours vaut 1, nous en déduisons que le stock a bien été actualisé. Nous retournons l'information textuelle ok pour en attester.
Remarque : En amont dans la page index.php, il serait intéressant de tester si la valeur saisie est bien numérique pour ne pas enclencher le traitement serveur inutilement. Nous avions proposé une
formation Javascript pour tester les valeurs numériques. Mais dans tous les cas, puisque le champ de réception dans la base de données est typé comme un entier, si une information textuelle lui est passée, la
requête de mise à jour échoue. Et à ce titre, nous retournons bien l'information nécessaire pour le traitement en aval (nok).
- Enregistrer les modifications (CTRL + S) et revenir dans le code de la page index.php,
- Ajouter le code Javascript suivant dans la branche else de la fonction recolter :
...
document.getElementById('des_produit').value = tab_info[0];
document.getElementById('qte_produit_avt').value = tab_info[1];
}
else
{
if(transport.responseText == "ok")
document.getElementById('qte_produit_aps').value = parseInt(document.getElementById('qte_produit_avt').value) + parseInt(document.getElementById('qte_produit').value);
}
}
...
Si la valeur réceptionnée est bien l'information ok, nous affichons le résultat de la mise à jour du stock dans le champ prévu à cet effet, d'identifiant qte_produit_aps. Pour ce faire, nous additionnons les valeurs contenues dans les deux contrôles qte_produit_avt et qte_produit. Comme l'information retournée est considérée par défaut comme du texte, nous l'encapsulons dans la
fonction Javascript parseInt, afin de forcer l'addition sur des valeurs numériques.
- Enregistrer les modifications et basculer sur le navigateur Web,
- Recharger la page internet en validant la barre d'adresse par la touche Entrée,
- Sélectionner une référence, par exemple b007,
- Dans la zone Quantité en + ou +, saisir le nombre 12,
- Puis, ordonner l'approvisionnement en cliquant sur le bouton Valider la mise à jour,
Après traitement serveur, la nouvelle quantité approvisionnée s'affiche dans le dernier contrôle Html prévu à cet effet.
- Revenir sur l'interface d'administration de PhpMyAdmin,
- Puis, afficher le contenu de la table articles,
En consultant la référence de l'article désigné depuis l'interface Web, vous constatez que sa
quantité en stock a parfaitement été mise à jour. Notre
code serveur Php est donc totalement fonctionnel. Si vous tentez une actualisation en tapant du texte à la place d'une valeur numérique, vous remarquez que rien ne se produit.
Néanmoins, certaines imperfections restent à corriger. Si après une mise à jour, vous sélectionnez une nouvelle référence, les anciennes valeurs restent stockées dans les
contrôles qte_produit et
qte_produit_aps. Il est donc préférable de réinitialiser leur contenu à chaque changement dans la liste déroulante. De plus, il serait judicieux d'adresser un message de confirmation explicite à l'issue du traitement. En bas à droite de la page Web, vous notez la présence de la mention :
Réponse serveur. Celle-ci est inscrite dans un calque, soit une
balise Div. Pour qu'elle soit pilotable par le code, elle doit posséder un identifiant.
- Revenir dans le code de la page index.php,
- En bas du code Html, ajouter l'identifiant suivant à ce calque :
...
<div id="msg_reponse" style="width:35%; height:75px; float:left; font-size:16px; font-weight:bold; text-align:left;">
<?php
echo "Réponse serveur";
?>
</div>
...
- Puis, adapter le code de la fonction recolter selon les mentions en gras,
...
if(document.getElementById('tampon').value == 'recup')
{
var tab_info = transport.responseText.split('|');
document.getElementById('des_produit').value = tab_info[0];
document.getElementById('qte_produit_avt').value = tab_info[1];
document.getElementById('qte_produit_aps').value = "";
document.getElementById('qte_produit').value = "";
}
else
{
if(transport.responseText=="ok")
{
document.getElementById('qte_produit_aps').value = parseInt(document.getElementById('qte_produit_avt').value) + parseInt(document.getElementById('qte_produit').value);
document.getElementById('msg_reponse').innerText = "Le stock a été mis à jour avec succès";
}
else
document.getElementById('msg_reponse').innerText = "Une erreur est survenue, le stock est inchangé";
}
...
Après enregistrement et différents essais, nous pouvons constater que :
- Un message de confirmation explicite est livré à l'administrateur,
- Les champs sont réinitialisés après choix d'une nouvelle référence,
- La mise à jour peut s'enchaîner depuis la même interface pour une autre référence.
Voilà donc pour ce premier volet consistant à bâtir une interface Web pour gérer l'
approvisionnement dynamique des stocks en
base de données MySql. De fil en aiguille, nous bâtirons le système complet de
facturation avec gestion des stocks.