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' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block body %}
<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</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>
{% verbatim %}
<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>
<tr ng-repeat="e in pCtrl.expenses">
<td>
{{ e.name }}
</td>
<td>
{{ e.delay }}débute dans X mois
</td>
<td>
{{ e.repeat }}
</td>
<td>
{{ e.repeat * e.amount }}
</td>
<td>
{{ e.amount }}
</td>
<td>
{{ e.amount * 12 }}
</td>
</tr>
</table>
<div class="well">
<strong>
Exemples:
</strong>
appartement
mutuelle
transport en commun
assurance voiture
assurance moto
trucs de loisirs divers
gaz
elec
internet
épargne
impots
cottisation URSSAF
resto au boulot
courses
serveur wouaibe
abonnement protonmail VPN
abonnement service audio, vidéo
carburant véhicule
donations
médecin
chat
chien
licorne
<tbody>
</tbody>
<tr ng-repeat="e in expenses">
<td>
<input type="text" ng-model="e.name">
</td>
<td>
<input type="text" ng-model="e.delay">
</td>
<td>
<input type="text" ng-model="e.repeat">
</td>
<td class="text-right padded">
{{ e.repeat * e.amount }}
</td>
<td>
<input type="text" ng-model="e.amount">
</td>
<td class="text-right padded">
{{ e.amount * 12 }}
</td>
</tr>
</table>
<div class="well">
<strong>
Exemples:
</strong>
appartement
mutuelle
transport en commun
assurance voiture
assurance moto
trucs de loisirs divers
gaz
elec
internet
épargne
impots
cottisation URSSAF
resto au boulot
courses
serveur wouaibe
abonnement protonmail VPN
abonnement service audio, vidéo
carburant véhicule
donations
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 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>
{% endblock %}
{% endverbatim %}
{% endblock %}

View File

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