expenses prevision page start with example

This commit is contained in:
Baptiste Lemoine 2018-08-23 12:18:02 +02:00
parent 5acff1b274
commit e371483c59
No known key found for this signature in database
GPG Key ID: 3A3B8ADA21ADF899
9 changed files with 372 additions and 356 deletions

0
.gitmodules vendored Normal file → Executable file
View File

282
app/Resources/views/logged/previsionnel.html.twig Normal file → Executable file
View File

@ -1,146 +1,154 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %} {% trans_default_domain 'FOSUserBundle' %}
{% block body %} {% block body %}
<div id="wrapper"> {% verbatim %}
<div class="previsionnel"
ng-app="caisse"
ng-controller="previsionnelCtrl as pCtrl"
>
<h1>Prévisionnel</h1>
<div class="row">
<div class="col-6 col-xs-12 col-sm-6">
<div class="config">
<h2>
Configuration
</h2>
Euros disponibles au départ:
<input type="number" ng-model="disponibility">
Dépenses mensuelles: {{ sumMonthlyExpenses }}
</div>
<div class="postes">
<h2>Postes de dépenses</h2>
<p class="desc">
Indiquez les catégories de dépenses mensuelles que vous faites pour faire évoluer la simulation de budget restant dans plusieurs mois.
</p>
<table class="exepnse-table">
<thead>
<tr>
<td>
Nom
</td>
<td>
débute dans X mois
</td>
<td>
mois répétitions
</td>
<td>
prix répétitions
</td>
<td>
prix mensuel
</td>
<td>
prix annuel
</td>
</tr>
</thead>
<tbody> <div id="wrapper">
<div class="previsionnel"
ng-app="caisse"
ng-controller="previsionnelCtrl as pCtrl"
>
<h1>Prévisionnel</h1>
<div class="row">
<div class="col-6 col-xs-12 col-sm-6">
<div class="config">
<h2>
Configuration
</h2>
Euros disponibles au départ:
<input type="number" ng-model="disponibility">
Dépenses mensuelles: {{ sumMonthlyExpenses }}
</div>
<div class="postes">
<h2>Postes de dépenses
<button ng-click="addExpense()">+</button>
</h2>
<p class="desc">
Indiquez les catégories de dépenses mensuelles que vous faites pour faire évoluer la
simulation de budget restant dans plusieurs mois.
</p>
<table class="exepnse-table">
<thead>
<tr>
<td>
Nom
</td>
<td>
débute dans X mois
</td>
<td>
mois répétitions
</td>
<td>
prix répétitions
</td>
<td>
prix mensuel
</td>
<td>
prix annuel
</td>
</tr>
</thead>
</tbody> <tbody>
<tr ng-repeat="e in pCtrl.expenses">
<td> </tbody>
{{ e.name }} <tr ng-repeat="e in expenses">
</td> <td>
<td> <input type="text" ng-model="e.name">
{{ e.delay }}débute dans X mois </td>
</td> <td>
<td>
{{ e.repeat }} <input type="text" ng-model="e.delay">
</td> </td>
<td> <td>
{{ e.repeat * e.amount }} <input type="text" ng-model="e.repeat">
</td> </td>
<td> <td class="text-right padded">
{{ e.amount }} {{ e.repeat * e.amount }}
</td> </td>
<td> <td>
{{ e.amount * 12 }} <input type="text" ng-model="e.amount">
</td> </td>
</tr> <td class="text-right padded">
</table> {{ e.amount * 12 }}
<div class="well"> </td>
<strong> </tr>
Exemples: </table>
</strong> <div class="well">
appartement <strong>
mutuelle Exemples:
transport en commun </strong>
assurance voiture appartement
assurance moto mutuelle
trucs de loisirs divers transport en commun
gaz assurance voiture
elec assurance moto
internet trucs de loisirs divers
épargne gaz
impots elec
cottisation URSSAF internet
resto au boulot épargne
courses impots
serveur wouaibe cottisation URSSAF
abonnement protonmail VPN resto au boulot
abonnement service audio, vidéo courses
carburant véhicule serveur wouaibe
donations abonnement protonmail VPN
médecin abonnement service audio, vidéo
chat carburant véhicule
chien donations
licorne médecin
chat
chien
licorne
</div>
</div>
</div>
<div class="col-6 col-xs-12 col-sm-6">
<h2>Simulation sur 5 ans (60 mois)</h2>
{{previsionTable.length}} lignes
<table>
<thead>
<tr>
<td>
Month in the future
</td>
<td>
date
</td>
<td>
Dépenses
</td>
<td>
Disponibilité
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="line in previsionTable">
<td>
{{ $index }}
</td>
<td>
-
</td>
<td>
{{ line.expense }}
</td>
<td ng-class="{ 'bg-warning' : line.available < 0}">
{{ line.available }}
</td>
</tr>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
<div class="col-6 col-xs-12 col-sm-6">
<h2>Simulation sur 5 ans (60 mois)</h2>
<table>
<thead>
<tr>
<td>
Month in the future
</td>
<td>
date
</td>
<td>
Dépenses
</td>
<td>
Disponibilité
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="line in previsionTable">
<td>
{{ $index }}
</td>
<td>
-
</td>
<td>
{{ line.expense }}
</td>
<td ng-class="{ 'bg-warning' : line.available < 0}">
{{ line.available }}
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
</div> {% endverbatim %}
</div> {% endblock %}
{% endblock %}

View File

@ -16,250 +16,250 @@ console.log('hello console for main.js');
var stuff = ['initialstuff']; var stuff = ['initialstuff'];
angular angular
.module('caisse', []) .module('caisse', [])
.controller('CaisseCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) { .controller('CaisseCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
$scope.productsFromDB = []; // loaded products $scope.productsFromDB = []; // loaded products
$scope.categories = []; // product categories $scope.categories = []; // product categories
$scope.sellingComment = "un gens"; // comment about the client or the current selling $scope.sellingComment = "un gens"; // comment about the client or the current selling
$scope.initLoadDone = false; // becames true after first init of product loading $scope.initLoadDone = false; // becames true after first init of product loading
$scope.recentSellings = []; $scope.recentSellings = [];
$scope.lesParams = {}; $scope.lesParams = {};
$scope.countProductsSoldForActiveFestival = {}; $scope.countProductsSoldForActiveFestival = {};
$scope.paidAmount = 0; $scope.paidAmount = 0;
$scope.expressSelling = true; $scope.expressSelling = true;
$scope.pausedSelling = []; $scope.pausedSelling = [];
$scope.show_config = { $scope.show_config = {
stock_count: false, stock_count: false,
sold: true, sold: true,
}; };
$scope.activeItemsSold = []; // list of products ID to sell $scope.activeItemsSold = []; // list of products ID to sell
$scope.activeSelling = []; // list of products to sell $scope.activeSelling = []; // list of products to sell
$scope.activeFestival = { // an event where selling take place $scope.activeFestival = { // an event where selling take place
id : null, id: null,
name : "le festival", name: "le festival",
dateCreation : new Date(), dateCreation: new Date(),
chiffreAffaire: 0, chiffreAffaire: 0,
clientsCount : 0, clientsCount: 0,
commentaire : "" commentaire: ""
}; };
/** /**
* get the sum of products prices * get the sum of products prices
* @param list * @param list
* @returns {number} * @returns {number}
*/ */
$scope.sumOfList = function (list) { $scope.sumOfList = function (list) {
let counter = 0; let counter = 0;
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
counter += list[i].price; counter += list[i].price;
} }
return counter; return counter;
}; };
/** /**
* sum of current selling list prices * sum of current selling list prices
* @returns {number} * @returns {number}
* @constructor * @constructor
*/ */
$scope.CurrentSellingTotal = function () { $scope.CurrentSellingTotal = function () {
return $scope.sumOfList($scope.activeSelling); return $scope.sumOfList($scope.activeSelling);
}; };
$scope.regenActiveSellingIds = function () { $scope.regenActiveSellingIds = function () {
$scope.activeItemsSold = []; $scope.activeItemsSold = [];
$scope.paidAmount = 0; $scope.paidAmount = 0;
for (let obj in $scope.activeSelling) { for (let obj in $scope.activeSelling) {
$scope.activeItemsSold.push(obj.id); $scope.activeItemsSold.push(obj.id);
} }
$scope.paidAmount += $scope.sumOfList($scope.activeSelling); $scope.paidAmount += $scope.sumOfList($scope.activeSelling);
}; };
$scope.stuff = stuff; $scope.stuff = stuff;
$scope.setActiveSelling = function (selling) { $scope.setActiveSelling = function (selling) {
$scope.activeSelling = selling; $scope.activeSelling = selling;
}; };
$scope.pauseSelling = function (selling) { $scope.pauseSelling = function (selling) {
$scope.pausedSelling.push(selling); $scope.pausedSelling.push(selling);
}; };
/** /**
* add to current sell list * add to current sell list
* @param product * @param product
*/ */
$scope.addProduct = function (product) { $scope.addProduct = function (product) {
product.stockCount--; product.stockCount--;
$scope.activeSelling.push(product); $scope.activeSelling.push(product);
$scope.activeItemsSold.push(product.id); $scope.activeItemsSold.push(product.id);
$scope.regenActiveSellingIds(); $scope.regenActiveSellingIds();
}; };
/** /**
* remove from current sell list * remove from current sell list
* @param product * @param product
*/ */
$scope.removeProduct = function (product, index) { $scope.removeProduct = function (product, index) {
product.stockCount++; product.stockCount++;
$scope.activeSelling.splice($index, 1); $scope.activeSelling.splice($index, 1);
$scope.regenActiveSellingIds() $scope.regenActiveSellingIds()
}; };
$scope.pauseSelling = function () { $scope.pauseSelling = function () {
$scope.pausedSelling.push(angular.copy($scope.activeSelling)); $scope.pausedSelling.push(angular.copy($scope.activeSelling));
$scope.activeSelling = []; $scope.activeSelling = [];
}; };
$scope.setBackPausedSelling = function (sellingList, index) { $scope.setBackPausedSelling = function (sellingList, index) {
$scope.activeSelling = angular.copy(sellingList); $scope.activeSelling = angular.copy(sellingList);
$scope.pausedSelling.splice(index, 1); $scope.pausedSelling.splice(index, 1);
}; };
$scope.clearSellingComment = function () { $scope.clearSellingComment = function () {
$scope.sellingComment = ''; $scope.sellingComment = '';
document.querySelector('#sellingCommentInput').focus(); document.querySelector('#sellingCommentInput').focus();
}; };
$scope.clearCurrentSelling = function () { $scope.clearCurrentSelling = function () {
$scope.paidAmount = 0; $scope.paidAmount = 0;
// $scope.sellingComment = ""; // $scope.sellingComment = "";
$scope.activeSelling = []; $scope.activeSelling = [];
}; };
// http related calls // http related calls
$scope.fetchProductsFromDB = function () { $scope.fetchProductsFromDB = function () {
console.log('fetch products...'); console.log('fetch products...');
$http.get('get-my-products').then((rep) => { $http.get('get-my-products').then((rep) => {
console.log('ok', rep); console.log('ok', rep);
customCategories = []; customCategories = [];
for (let c of rep.data.categories) { for (let c of rep.data.categories) {
c.hidden = false; c.hidden = false;
customCategories.push(c); customCategories.push(c);
} }
console.log('customCategories', customCategories); console.log('customCategories', customCategories);
$scope.categories = customCategories; $scope.categories = customCategories;
$scope.productsFromDB = customCategories; $scope.productsFromDB = customCategories;
// $scope.recentSellings = rep.data.history; // $scope.recentSellings = rep.data.history;
// festoche // festoche
$scope.activeFestival.id = rep.data.lastFestival.id; $scope.activeFestival.id = rep.data.lastFestival.id;
$scope.activeFestival.name = rep.data.lastFestival.name; $scope.activeFestival.name = rep.data.lastFestival.name;
$scope.activeFestival.dateCreation = rep.data.lastFestival.dateCreation; $scope.activeFestival.dateCreation = rep.data.lastFestival.dateCreation;
$scope.activeFestival.commentaire = rep.data.lastFestival.commentaire; $scope.activeFestival.commentaire = rep.data.lastFestival.commentaire;
$scope.activeFestival.chiffreAffaire = rep.data.lastFestival.chiffreAffaire; $scope.activeFestival.chiffreAffaire = rep.data.lastFestival.chiffreAffaire;
$scope.activeFestival.fondDeCaisseAvant = rep.data.lastFestival.fondDeCaisseAvant; $scope.activeFestival.fondDeCaisseAvant = rep.data.lastFestival.fondDeCaisseAvant;
$scope.activeFestival.fondDeCaisseApres = rep.data.lastFestival.fondDeCaisseApres; $scope.activeFestival.fondDeCaisseApres = rep.data.lastFestival.fondDeCaisseApres;
$scope.activeFestival.clientsCount = rep.data.lastFestival.clientsCount; $scope.activeFestival.clientsCount = rep.data.lastFestival.clientsCount;
// stat count for items // stat count for items
$scope.countProductsSoldForActiveFestival = rep.data.lastFestival.sold; $scope.countProductsSoldForActiveFestival = rep.data.lastFestival.sold;
console.log(' $scope.countProductsSoldForActiveFestival', $scope.countProductsSoldForActiveFestival); console.log(' $scope.countProductsSoldForActiveFestival', $scope.countProductsSoldForActiveFestival);
//done //done
$scope.initLoadDone = true; $scope.initLoadDone = true;
}, (err) => { }, (err) => {
console.log(err); console.log(err);
$scope.initLoadDone = true; $scope.initLoadDone = true;
}); });
}; };
/** /**
* sell one product, assuming the client has the right amount of money * sell one product, assuming the client has the right amount of money
* @param product * @param product
*/ */
$scope.expressSell = function (product) { $scope.expressSell = function (product) {
$scope.addProduct(product); $scope.addProduct(product);
$scope.sendForm(); $scope.sendForm();
}; };
$scope.recentId = 0; $scope.recentId = 0;
$scope.logger = function (stuff) { $scope.logger = function (stuff) {
console.log('logger', stuff); console.log('logger', stuff);
}; };
$scope.sendForm = function () { $scope.sendForm = function () {
console.log('$scope.sellingComment', this.sellingComment); console.log('$scope.sellingComment', this.sellingComment);
let lesParams = { let lesParams = {
paidByClient : this.paidAmount, paidByClient: this.paidAmount,
sellingComment: this.sellingComment, sellingComment: this.sellingComment,
activeSelling : this.activeSelling, activeSelling: this.activeSelling,
activeFestival: this.activeFestival activeFestival: this.activeFestival
}; };
$scope.recentSellings.push({ $scope.recentSellings.push({
id : this.recentId++, id: this.recentId++,
amount : this.CurrentSellingTotal(), amount: this.CurrentSellingTotal(),
paidAmount: this.paidAmount, paidAmount: this.paidAmount,
products : products:
angular angular
.copy(this.activeSelling) .copy(this.activeSelling)
}); });
console.log('$scope.recentSellings', this.recentSellings); console.log('$scope.recentSellings', this.recentSellings);
$scope.lesParams = lesParams; $scope.lesParams = lesParams;
$http({ $http({
method : 'POST', method: 'POST',
url : 'add-selling', url: 'add-selling',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
data : lesParams // pass in data as strings data: lesParams // pass in data as strings
}).then(function (rep) { }).then(function (rep) {
$scope.clearCurrentSelling(); $scope.clearCurrentSelling();
// if successful, bind success message to message // if successful, bind success message to message
$scope.successMessage = rep.data.message; $scope.successMessage = rep.data.message;
$scope.activeFestival.chiffreAffaire = rep.data.newChiffreAffaire; $scope.activeFestival.chiffreAffaire = rep.data.newChiffreAffaire;
$scope.activeFestival.clientsCount = rep.data.clientsCount; $scope.activeFestival.clientsCount = rep.data.clientsCount;
$scope.countProductsSoldForActiveFestival = rep.data.activeFestival.sold; $scope.countProductsSoldForActiveFestival = rep.data.activeFestival.sold;
$scope.showTemporaryMessage(); $scope.showTemporaryMessage();
console.log(rep); console.log(rep);
if (!rep.success) { if (!rep.success) {
// if not successful, bind errors to error variables // if not successful, bind errors to error variables
$scope.errors = rep.errors; $scope.errors = rep.errors;
} }
}, function (rep) { }, function (rep) {
console.log('nope! ', rep.data); console.log('nope! ', rep.data);
}) })
; ;
}; };
$scope.sellingOk = false; $scope.sellingOk = false;
$scope.tempMessage = {}; $scope.tempMessage = {};
$scope.showTemporaryMessage = function(){ $scope.showTemporaryMessage = function () {
if($scope.sellingOk ){ if ($scope.sellingOk) {
return; return;
} }
$scope.sellingOk = true; $scope.sellingOk = true;
$timeout.cancel($scope.tempMessage ); $timeout.cancel($scope.tempMessage);
$scope.tempMessage = $timeout(function(){ $scope.tempMessage = $timeout(function () {
$scope.sellingOk=false; $scope.sellingOk = false;
},2000) }, 2000)
}; };
$scope.init = (function () { $scope.init = (function () {
$scope.fetchProductsFromDB(); $scope.fetchProductsFromDB();
})(); })();
}]) }])
.controller('previsionnelCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) { .controller('previsionnelCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
let exampleExpenses = [ let exampleExpenses = [
{name: "appart", amount: 600}, {name: "appart", amount: 600, delay: 0, repeat: 60},
{name: "assurance voiture", amount: 50}, {name: "assurance voiture", amount: 50, delay: 0, repeat: 60},
{name: "internet", amount: 20}, {name: "internet", amount: 20, delay: 0, repeat: 60},
{name: "elec", amount: 100}, {name: "elec", amount: 100, delay: 0, repeat: 60},
{name: "transports", amount: 70}, {name: "transports", amount: 70, delay: 0, repeat: 60},
{name: "chat", amount: 20}, {name: "chat", amount: 20, delay: 0, repeat: 60},
]; ];
/** /**
* expenses kind of the user * expenses kind of the user
* @type {Array} * @type {Array}
*/ */
$scope.disponibility=5000; $scope.disponibility = 5000;
// $scope.expenses=[]; // $scope.expenses=[];
$scope.expenses=exampleExpenses; $scope.expenses = exampleExpenses;
/** /**
* sum of all monthly expenses, ignoring delay * sum of all monthly expenses, ignoring delay
* @returns {number} * @returns {number}
*/ */
$scope.sumMonthlyExpenses = ()=>{ $scope.sumMonthlyExpenses = () => {
let sum = 0; let sum = 0;
$scope.expenses.forEach((elem)=>{ $scope.expenses.forEach((elem) => {
sum += elem.amount; sum += elem.amount;
}) })
return sum; return sum;
}; };
$scope.previsionTable = ()=>{ $scope.previsionTable = () => {
let turns = 60; let turns = 60;
let monthly = $scope.sumMonthlyExpenses(); let monthly = $scope.sumMonthlyExpenses();
let available = $scope.disponibility; let available = $scope.disponibility;
let previsionTable=[]; let previsionTable = [];
for (let i=0;i<=turns;i++){ for (let i = 0; i <= turns; i++) {
// TODO take in account delays in expenses // TODO take in account delays in expenses
let newLine = { let newLine = {
expense: monthly, expense: monthly,
@ -271,18 +271,26 @@ angular
}; };
// http related calls // http related calls
$scope.fetchExpenses = ()=>{ $scope.fetchExpenses = () => {
console.log('fetch expenses...'); console.log('fetch expenses...');
$http.get('get-my-expenses').then((rep) => { $http.get('get-my-expenses').then((rep) => {
console.log('get-my-expenses',rep); console.log('get-my-expenses', rep);
}) })
}; };
// save // save
$scope.save = ()=>{ $scope.save = () => {
console.log('update expenses...'); console.log('update expenses...');
$http.post('save-my-expenses', $scope.expenses) $http.post('save-my-expenses', $scope.expenses)
.then((rep) => { .then((rep) => {
console.log('save-my-expenses',rep); console.log('save-my-expenses', rep);
}) })
}; };
$scope.addExpense = () => {
$scope.expenses.push({
name: "",
repeat: 0,
delay: 0,
amount: 0,
})
}
}]); }]);

0
crowdin.yml Normal file → Executable file
View File

0
src/AppBundle/Entity/ExpenseKind.php Normal file → Executable file
View File

0
src/AppBundle/Entity/SerieFestival.php Normal file → Executable file
View File

0
src/AppBundle/Repository/ExpenseKindRepository.php Normal file → Executable file
View File

0
translations/de Normal file → Executable file
View File

0
translations/en Normal file → Executable file
View File