Micro Application 3: StockVoiture avec Angular.Js (avec Optimisation Financière)

Introduction stockvoiture


Aujourd’hui, je vais créer une micro-application de gestion financière d’un garage avec Angular.js et un peu de Jquery. A tester ici .

Voici ce que l’application permet :

  • Enregistrer une nouvelle voiture avec son prix et le cout de ses réparations
  • Modifier une voiture enregistrée
  • Visionner les statistiques de ventes
  • Optimiser la revente Globale par pourcentage, en temps réel, et visionner les bénéfices, en tenant compte des frais de réparation sur tout le garage à un instant t.
  • Tout se mets à jour en temps réel avec Angular.js

Note : j’ai inventé le code de zéro, je ne l’ai pas repris. Bien sur, cette appli est « expandable » à l’infini

Description :


Langage : Angular.js, Html5.0, Css3.0, Jquery

Temps de réalisation : 5h30

Type : Micro-Application Front office

Back-end possible : Php, Java.

 

Notes :


Dans ma prochaine micro application, je vais ajouter des graphiques qui s’actualiseront en temps réel pour effectuer des stas en temps réel.

Ne pas trop regarder les css ici, car j’aurais pu les compresser bien plus en les rendant génériques.

Demain je reviendrais dessus pour ajouter d’autres « optimiseurs »… L’idéal à l’avenir serait carrément d’y ajouter le simplexe !

Note importante: avec Angular, on peut effecter des opérations sur des vars, directement dans le html avec les moustache.

Deuxième note : toutes les données tiennent dans un simple tableau, il est très facile de les stocker en BDD avec JAva ou Php, OU d’importer un fichier Json avec 1500 voitures.

 

Le Code


<html lang="fr" ng-app="achat">
	<head>
		<meta http-equiv="content-type" content="text/html;charset=iso-8859-15" />
		<!-- -----------------------------------------------DEBUT DU CHARGEMENT DES LIBRAIRIES------------------------ -->
		<!--	APPEL LIB ANGULAR -->
		<script	type="text/javascript" 	src="angular-1.3.13/angular.min.js"></script>
		<!--	APPEL LIB JQUERY -->
		<script	type="text/javascript" 	src="librairies/jquery.js"></script>
		<!-- -----------------------------------------------FIN DU CHARGEMENT DES LIBRAIRIES------------------------ ----->
		<script>
			
			var myApp = angular.module('achat',[]);
				
			// Controleur Angular
			myApp.controller('NameCtrl', function($scope) {
				
				//Initialisation des Variables
				$scope.formtitre	= "Ajouter une Voiture";
				$scope.voitures 	= []; 
				$scope.nom			='Auto';
				$scope.marque		='Marque';
				$scope.serie		='Série';
				$scope.achat		=0;
				$scope.revente		=0;
				$scope.reparation 	=0;
				$scope.age			=1;
				$scope.etat			=50;
				$scope.esperance 	=50;
				$scope.optimise1	= 0;	
				var date = new Date();
				$scope.date		= date;
				$scope.alert	='Rien à signaler';
				
				//Initialisation des CSS
				document.getElementById("modif").disabled = true; 
				
					// Données de démonstration				
					$scope.voitures.push({
						nom: 		"Mondeo",
						marque: 	"Ford",
						serie:		"gs",
						achat:		10000,		
						revente:	10000,		
						reparation:	1000, 	
						age:		3,			
						etat:		75,			
						esperance:	15, 	
					});		
									
					$scope.voitures.push({
						nom: 		"Laguna",
						marque: 	"Renault",
						serie:		"D",
						achat:		12000,		
						revente:	12000,		
						reparation:	275.5, 	
						age:		7,			
						etat:		35,			
						esperance:	80, 	
					});	

					$scope.voitures.push({
						nom: 		"C3",
						marque: 	"Citroen",
						serie:		"D",
						achat:		22000,		
						revente:	13000,		
						reparation:	1253.5, 	
						age:		2,			
						etat:		90,			
						esperance:	80, 	
					});	
						
							
				$("#modif").hide();
				
			// Réinitialisation du formulaire
				$scope.init	= function(){
					$scope.formtitre	= "Ajouter une Voiture";
					$scope.nom			='Auto';
					$scope.marque		='Marque';
					$scope.serie		='Série';
					$scope.achat		=0;
					$scope.revente		=1;
					$scope.reparation 	=0;
					$scope.age			=1;
					$scope.etat			=1;
					$scope.esperance 	=1;
				
				}
				
				
				// Enregistre une voiture
				$scope.enregistrer	=	function(){
				
					if ($scope.nom == ''){
					$scope.alert='Le Champs nom de la Voiture est Vide';
					}
					
					if ($scope.voitures.length > 29){
					$scope.alert='N\'ajoutez pas plus de 30 Voitures';
					}
					
					else {
					// Ajoute le nom et le prix de l'objet au tableau
					$scope.voitures.push({
						nom: 		$scope.nom,
						marque: 	$scope.marque,
						serie:		$scope.serie,
						achat:		$scope.achat,		
						revente:	$scope.achat,		
						reparation:	$scope.reparation, 	
						age:		$scope.age,			
						etat:		$scope.etat,			
						esperance:	$scope.esperance, 	
					});
					
					$scope.alert='Voiture ajoutée';
					// Initialise le contenu des champs après un push de variables dans le tableau
					$scope.init();
					}
				}
					
				
				// Affiche les données d'une voiture enregistrée dans le formulaire et permet de Modifier .
				$scope.modifierClique	=	function(index){
					//Esthetique et css
					document.getElementById("modif").disabled = false; 
					$scope.init();
					$scope.formtitre="Modifier une Voiture"; 
					$(".modifboutton").css( 'color', 'red' );// Change le curseur en une main
					$("#modif").show();
					$("#btnr").hide();
					$(".formulaire").css( 'background-color', 'red' );
					$(".modifboutton").attr('disabled', 'disabled');
					//Variable index mise dans le scope global, pour faire rapide, mais non conseillé je crois.
					window.index = index;
					
					//Initialisation des curseurs avec les données de la voiture enregistrées dans le tableau voitures[]
					$scope.nom			= $scope.voitures[index].nom;
					$scope.marque		= $scope.voitures[index].marque	;
					$scope.serie		= $scope.voitures[index].serie;
					$scope.achat		= $scope.voitures[index].achat;
					$scope.revente		= $scope.voitures[index].revente;
					$scope.reparation 	= $scope.voitures[index].reparation;
					$scope.age			= $scope.voitures[index].age	;
					$scope.etat			= $scope.voitures[index].etat;
					$scope.esperance 	= $scope.voitures[index].esperance;
					$scope.alert		=	'Modifiez la voiture';
				}
				
				// Enregistre les données modifiées d'une voiture en RAM, dans le tableau voitures[] .
				$scope.rmodifs	=	function(){
					i=window.index;
					$scope.voitures[i].nom		=	$scope.nom;	
					$scope.voitures[i].marque	=	$scope.marque;
					$scope.voitures[i].serie	=	$scope.serie;
					$scope.voitures[i].achat	=	$scope.achat;
					$scope.voitures[i].revente	=	$scope.revente;	
					$scope.voitures[i].reparation=	$scope.reparation;
					$scope.voitures[i].age		=	$scope.age	;
					$scope.voitures[i].etat		=	$scope.etat	;
					$scope.voitures[i].esperance=	$scope.esperance ;
					$scope.alert				=	'Voiture Modifiée';
						
					// Esthétiques et Css
					$(".modifboutton").css( 'color', 'blue' );
					$(".modifboutton").prop('disabled', false);
					$(".formulaire").css( 'background-color', 'ivory' );
					document.getElementById("modif").disabled = true; 
					$scope.alert	='La voiture a été modifiée';
					$scope.init();
					$("#btnr").show();
					$("#modif").hide();
				}
				
				// Affiche combien il y a de lignes dans le tableau
				$scope.getTotalItems = function () {
					return $scope.voitures.length;
				};
				
				
				// Supprime une voiture dans liste
				$scope.supprimeClique = function (index) {
						$scope.voitures.splice(index, 1);
				};
			
			
				// Affiche le prix total 
				$scope.getTotal = function(){
					var total = 0;
					for(var i = 0; i < $scope.voitures.length; i++){
					total += $scope.voitures[i].achat;
					}
					return total;
				}
				
				// Affiche le prix total des réparations 
				$scope.getTotalReparation = function(){
					var total = 0;
					for(var i = 0; i < $scope.voitures.length; i++){
					total += $scope.voitures[i].reparation;
					}
					return total;
				}
				
				// Affiche le prix total des reventes 
				$scope.getTotalRevente = function(){
					var total = 0;
					for(var i = 0; i < $scope.voitures.length; i++){
						total += $scope.voitures[i].revente;
					}
				return total;
				}
			
				// Affiche le bénéfice total
				$scope.getTotalBenefice= function(){
					var total = 0;
					for(var i = 0; i < $scope.voitures.length; i++){
						total += $scope.voitures[i].revente;
					}
				return total;
				}
			
				// Optimise le prix de  vente du pourcentage choisi dans le curseur
				$scope.opt1= function(){
					var total = 0;
					$scope.optimise1 = parseInt($scope.optimise1,10);
					
					for(var i = 0; i < $scope.voitures.length; i++){
						var x=Math.round($scope.voitures[i].achat/100)*$scope.optimise1;
						$scope.voitures[i].revente = $scope.voitures[i].achat + x ;
					}
				}
			// Fin du Controleur Angular
			});
			
		</script>
		

	</head>

<body ng-controller="NameCtrl" class="body">
<div class="gauche">
	<div class="infos">	
		<h1><p>Informations<img src="stockvoiture.jpg" id="logo" ></p></h1>
		<p>{{alert}}</p>
	</div>	

	<div class="formulaire" ><h1><p>{{formtitre}}</p></h1>
		<p>
			<table class="CSSTableGenerator ">
				<tr>
					<th>	<img src="toto.jpg">					</th>
					<th><p>Votre voiture s'appelle <b>{{nom}}</b>	</th>
					<th><b>Prix d'achat </b>{{achat}} Euros 		</th>		
					<th><b>Age </b>{{age}}  ans						</th>		
				</tr>
			</table>
		
		<form>
			<table class="table">
				<td>
					<label >Nom :</label> 	<br>
					<input ng-model="nom" 		type="text" class ="champs" /><br>
					<label >Prix D'achat:</label>   <br>     
					<input ng-model="achat"  type="number"  class ="champs" /> {{achat}} Euros<br>
					<label >Couts de réparation:</label>     <br>   
					<input ng-model="reparation" type="number" class ="champs" />{{reparation}} Euros<br>	
				</td>
				<td>
					<label >Marque:</label> 	<br>
					<input ng-model="marque" type="text" class ="champs" /><br>
					<label >Age du véhicule:</label>   <br>     
					<input ng-model="age" type="range" min="0" max="50"class ="champs"  /> Ans<br>
					<label >Etat général:</label>        <br>
					<input ng-model="etat" type="range" min="0" max="100" class ="champs" /> %<br>
					<label >Esperance de revente :</label>     <br>   
					<input ng-model="esperance" type="range" min="0" max="100"   class ="champs" /> %<br>	
				</td>
			</table>
					<button class="btn btnspe" ng-click="enregistrer()" id="btnr"> Ajouter la Voiture</button>
					<button class="btn btnspe" ng-click="rmodifs($index)" id="modif" >Modifier la Voiture</button>
		</form>	
		</p>
	</div>	
		
	<div class="vision" > <h1><p>Statistiques du Garage</p></h1>
		<table class="CSSTableGenerator ">
			<tr>
				<td> Nb de voitures	</td>
				<td> Total Achat	</td>
				<td> Total Réparations	</td>
				<td> Total Reventes	</td>
				<td> Bénéfices</td>	
			</tr>
			<tr>
				<td>{{getTotalItems()}}</td>
				<td>{{getTotal()}}</td>
				<td>{{getTotalReparation()}}</td>
				<td>{{getTotalRevente()}}</td>
				<td>{{getTotalRevente()-getTotal()-getTotalReparation()}}</td>
			</tr>
		</table>
	</div>

	<div class="optimisation"><h1><p>Optimisations Financières</p></h1>
		<img src="euro.png" style="width:60px;height:60px;margin-left:10px;">
		<label >Gain de Revente Global:</label><br>
		 <p>  -<input ng-model="optimise1" 	type="range" min="-100" max="+100" class ="champs" />+ {{optimise1}}  %</p>
		<button ng-click="opt1()" class="btn btnspe">Augmenter les prix de revente</button>
	</div>	


</div>



<div class="droite">
<br>
	<div class="liste"><h1><p>Mon garage de Voitures({{getTotalItems()}})</p></h1>
		<input type="search" ng-model="q" placeholder="Rechercher une Voiture" />
		<table class="CSSTableGenerator " >
			<tr>
				<td>Photo</td>
				<td>Nom</td>
				<td>Prix d'achat</td>
				<td>Revente Prédictionnelle</td>
				<td><b>Age</td>
				<td></td>
				<td></td>
			</tr>
		   <tr  ng-repeat="voiture in voitures | filter:q as results" >
				<td><img src="toto.jpg"></img>	</td>
				<td>{{voiture.nom}} 			</td>
				<td>{{voiture.achat}} Euros		</td>
				<td>{{voiture.revente}} Euros		</td>
				<td>{{voiture.age}} ans			</td>
				<td><button ng-click="modifierClique($index)" class="modifboutton">Modifier</button></td>
				<td><button ng-click="supprimeClique($index)" >Supprimer</button></td>
			</tr>
		</table>	
	</div>	
</div>
</body>
		
	
		
<style>
.body{
	font-family:arial;
	font-size:1.2em;
	<!-- background:url("http://localhost/angular/fond.jpg") repeat scroll 0 0 rgba(0, 0, 0, 0); -->
	background-color:tan;
}	

h1{
	font-size:1.2em;
	background-color:tan;
	-webkit-border-radius: 10px 10px 10px 10px;
	border-radius: 10px 10px 10px 10px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;
}

p{
	margin-left:15px;
}

.gauche{
	min-width:800px;
	<!-- background-color:red; -->
	max-width:auto;
	max-height:auto;
	height:auto;
	float:left;
}

.droite{
	float:left;
	min-width:800px;
	margin-left:10px;
	float:initial;
}

#logo{
	<!-- position:absolute; -->
	height:80px;
	width:130px;
	margin-left: 10px;
	}label{
	margin-left:10px;
}

.table{
	font-size:0.8em;
	background-color:ivory;
	margin-left:auto;
	margin-right:auto;
}

.formulaire{
	height:390px;
	width:auto;
	background-color:ivory;
	float:center;
	margin-right: auto ;
	text-align:left;
	-webkit-border-radius: 10px 10px 10px 10px;
	border-radius: 10px 10px 10px 10px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;
}

.modifboutton{
disabled:disabled;
}

.vision{
	margin-top:15px;
	height:140px;
	width:auto;
	background-color:ivory;
	float:center;
	margin-right: auto ;
	-webkit-border-radius: 10px 10px 10px 10px;
	border-radius: 10px 10px 10px 10px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;
}

.optimisation{
	margin-top:15px;
	height:250px;
	width:auto;
	background-color:ivory;
	margin-top:;
	margin-right: auto ;
	-webkit-border-radius: 10px 10px 10px 10px;
	border-radius: 10px 10px 10px 10px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;
	text-align:left;
}

.liste{
	min-height:20px;
	max-height:920px;
	height:auto;
	background-color:ivory;
	-webkit-border-radius: 10px 10px 10px 10px;
	border-radius: 10px 10px 10px 10px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;$
	margin-left:510px;
	overflow:auto;
}

.infos{
	<!-- margin-top:100px; -->
	min-height:20px;
	height:auto;
	width:auto;
	background-color:ivory;
	-webkit-border-radius: 10px 10px 10px 10px;
	border-radius: 10px 10px 10px 10px;
	-webkit-box-shadow:inset 2px 2px 2px 2px #635453;
	box-shadow:inset 2px 2px 2px 2px #635453;$
	margin-top:auto;
	<!-- margin-left:500px; -->
	margin-right:auto;
}

.champs{
	margin-top:5px;
	width:100px;
	align: left ;
	margin-left: auto ;
	margin-right: auto ;	
	-webkit-border-radius: 5px 5px 5px 5px;
	border-radius: 5px 5px 5px 5px;
	margin-left:15px;
}

.CSSTableGenerator {
	margin:0px;padding:0px;
	width:100%;
	box-shadow: 10px 10px 5px #888888;
	border:1px solid #000000;
	-moz-border-radius-bottomleft:0px;
	-webkit-border-bottom-left-radius:0px;
	border-bottom-left-radius:0px;
	-moz-border-radius-bottomright:0px;
	-webkit-border-bottom-right-radius:0px;
	border-bottom-right-radius:0px;
	-moz-border-radius-topright:0px;
	-webkit-border-top-right-radius:0px;
	border-top-right-radius:0px;
	-moz-border-radius-topleft:0px;
	-webkit-border-top-left-radius:0px;
	border-top-left-radius:0px;
}

.CSSTableGenerator table{
border-collapse: collapse;
border-spacing: 0;
width:100%;
height:100%;
margin:0px;padding:0px;
}

.CSSTableGenerator tr:last-child td:last-child {
	-moz-border-radius-bottomright:0px;
	-webkit-border-bottom-right-radius:0px;
	border-bottom-right-radius:0px;
}

.CSSTableGenerator table tr:first-child td:first-child {
	-moz-border-radius-topleft:0px;
	-webkit-border-top-left-radius:0px;
	border-top-left-radius:0px;
}

.CSSTableGenerator table tr:first-child td:last-child {
-moz-border-radius-topright:0px;
-webkit-border-top-right-radius:0px;
border-top-right-radius:0px;
}

.CSSTableGenerator tr:last-child td:first-child{
	-moz-border-radius-bottomleft:0px;
	-webkit-border-bottom-left-radius:0px;
	border-bottom-left-radius:0px;
}

.CSSTableGenerator tr:hover td{
background-color:#cccc99;
}

.CSSTableGenerator td{
	vertical-align:middle;
	border-style:ridge;
	border-color:tan;
	background-color:#eeeeee;
	border:1px solid #000000;
	border-width:0px 1px 1px 0px;
	text-align:left;
	padding:7px;
	font-size:14px;
	font-family:Arial;
	font-weight:normal;
	color:#000000;
}

.CSSTableGenerator tr:last-child td{
	border-width:0px 1px 0px 0px;
}

.CSSTableGenerator tr td:last-child{
	border-width:0px 0px 1px 0px;
}

.CSSTableGenerator tr:last-child td:last-child{
border-width:0px 0px 0px 0px;
}

.CSSTableGenerator tr:first-child td{
	background:-o-linear-gradient(bottom, #003366 5%, #003f7f 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #003366), color-stop(1, #003f7f) );
	background:-moz-linear-gradient( center top, #003366 5%, #003f7f 100% );
	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#003366", endColorstr="#003f7f");	background: -o-linear-gradient(top,#003366,003f7f);
	background-color:#003366;
	border:0px solid #000000;
	text-align:center;
	border-width:0px 0px 1px 1px;
	font-size:14px;
	font-family:Arial;
	font-weight:bold;
	color:#ffffff;
}

.CSSTableGenerator tr:first-child:hover td{
background:-o-linear-gradient(bottom, #003366 5%, #003f7f 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #003366), color-stop(1, #003f7f) );
background:-moz-linear-gradient( center top, #003366 5%, #003f7f 100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#003366", endColorstr="#003f7f");	background: -o-linear-gradient(top,#003366,003f7f);
background-color:#003366;
}

.CSSTableGenerator tr:first-child td:first-child{
border-width:0px 0px 1px 0px;
}

.CSSTableGenerator tr:first-child td:last-child{
border-width:0px 0px 1px 1px;
}

.btn,modifboutton{
	background: #323c42;
	background-image: -webkit-linear-gradient(top, #323c42, #2980b9);
	background-image: -moz-linear-gradient(top, #323c42, #2980b9);
	background-image: -ms-linear-gradient(top, #323c42, #2980b9);
	background-image: -o-linear-gradient(top, #323c42, #2980b9);
	background-image: linear-gradient(to bottom, #323c42, #2980b9);
	-webkit-border-radius: 4;
	-moz-border-radius: 4;
	border-radius: 4px;
	text-shadow: 3px 6px 9px #666666;
	font-family: Arial;
	color: #ffffff;
	font-size: 14px;
	padding: 12px 18px 10px 20px;
	border: solid #1f628d 4px;
	text-decoration: none;
	width:200px;
}

.btnspe{
	align:right;
	float:right;
}

.btnspe2{
	align:right;
	float:right;
}

.btn:hover {
	background: #fc6f3c;
	background-image: -webkit-linear-gradient(top, #fc6f3c, #d9349f);
	background-image: -moz-linear-gradient(top, #fc6f3c, #d9349f);
	background-image: -ms-linear-gradient(top, #fc6f3c, #d9349f);
	background-image: -o-linear-gradient(top, #fc6f3c, #d9349f);
	background-image: linear-gradient(to bottom, #fc6f3c, #d9349f);
	text-decoration: none;
}
		
</style>
</html>
Publicités