caisse-bliss/assets/js/parts/main.js

502 lines
18 KiB
JavaScript
Executable File

require('../../../node_modules/canvasjs/dist/canvasjs.3');
// JS is equivalent to the normal "bootstrap" package
// no need to set this to a variable, just require it
require('bootstrap-sass');
// or you can include specific pieces
// require('bootstrap-sass/javascripts/bootstrap/tooltip');
// require('bootstrap-sass/javascripts/bootstrap/popover');
require('./globalActions');
require('./dashboard');
var PrevisionnelCtrl = require('./previsionnel');
var stuff = ['initialstuff'];
// TODO split controllers in other files
angular
.module('caisse', [])
.controller('CaisseCtrl', ['$scope', '$http', '$timeout', '$rootScope', function ($scope, $http, $timeout,$rootScope) {
$scope.productsFromDB = []; // loaded products
$scope.categories = []; // product categories
$scope.sellingComment = ""; // 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.simpleDisplay = false;
$scope.paidAmount = 0;
$scope.pausedSelling = [];
$scope.show_config = {
expressSelling: true,
stock_count: false,
sold : false,
};
$scope.activeItemsSold = []; // list of products ID to sell
$scope.activeSelling = []; // list of products to sell
$scope.activeSellingFiltered = []; // list of products to sell
$scope.activeFestival = { // an event where selling take place
id : null,
name : "le festival",
productComment : "",
dateCreation : new Date(),
chiffreAffaire: 0,
clientsCount : 0,
commentaire : ""
};
/**
* change to simple display
*/
$scope.toggleSimpleDisplay = function () {
// debugger;
$scope.simpleDisplay = !$scope.simpleDisplay;
}
/**
* set the right paid amount
*/
$scope.setRightAmountPaid = function () {
// debugger;
$scope.paidAmount += $scope.sumOfList($scope.activeSelling);
}
/**
* deduplicate the active selling items in the view,
* show a count for each of them when there are more than one
*/
$scope.refreshDeduplicateSellings = () => {
let soldObjectsIdsCount = {}
$scope.activeSellingFiltered = {};
$scope.activeSelling.forEach(elem => {
let groupId = elem.id;
let group = soldObjectsIdsCount[groupId];
if (group) { // sort elements by the product id corresponding
group.count++;
group.totalPrice += (elem.price * 1);
group.sellings.push(elem);
} else {
soldObjectsIdsCount[groupId] = {
groupId : groupId,
count : 1,
name : elem.name,
unitPrice : elem.price * 1,
totalPrice: elem.price * 1,
sellings : [elem],
}
}
});
$scope.activeSellingFiltered = soldObjectsIdsCount;
$scope.setRightAmountPaid();
}
/**
* 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 * 1;
}
return counter;
};
/**
* sum of current selling list prices
* @returns {number}
* @constructor
*/
$scope.CurrentSellingTotal = function () {
return $scope.sumOfList($scope.activeSelling);
};
$scope.categoriesVisibleCount = function () {
let count = 0;
$scope.categories.forEach(function (elem) {
elem.hidden ? count++ : "";
});
return count;
}
$scope.regenActiveSellingIds = function () {
$scope.activeItemsSold = [];
$scope.paidAmount = 0;
for (let obj in $scope.activeSelling) {
$scope.activeItemsSold.push(obj.id);
}
};
$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--;
product.enabled = true;
$scope.activeSelling.push(product);
$scope.activeItemsSold.push(product.id);
$scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
$scope.setRightAmountPaid();
};
/**
* remove from current sell list
* @param product
*/
$scope.removeProduct = function (product, index) {
product.stockCount++;
$scope.activeSelling.splice($index, 1);
$scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
};
/**
* remove all products of a certain group id in the active Selling
* @param productId
* @returns {*}
*/
$scope.removeGroupeProducts = function (productId) {
console.log("##### removeGroupeProducts", productId);
console.log("$scope.activeSelling", $scope.activeSelling);
$scope.activeSelling = $scope.activeSelling.filter(elem => elem.id != productId)
console.log("$scope.activeSelling", $scope.activeSelling);
$scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
}
$scope.removeAll = function () {
$scope.categories.forEach(category => {
if (category.products && category.products.length) {
category.products.forEach(product => {
product.enabled = false
});
}
});
$scope.activeSelling = [];
$scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
};
$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 () {
console.log(' $scope.sellingComment', $scope.sellingComment);
$scope.sellingComment = '';
// document.querySelector('.client-now input').focus();
document.querySelector('.client-now input').select();
};
$scope.clearCurrentSelling = function () {
$scope.paidAmount = 0;
$scope.clearSellingComment();
$scope.activeSelling = [];
$scope.removeAll();
};
// http related calls
$scope.fetchProductsFromDB = function () {
console.log('fetch products...');
$http.get('logged/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;
});
};
/**
* sell one product, assuming the client has the right amount of money
* @param product
*/
$scope.expressSell = function (product) {
$scope.removeAll();
$scope.addProduct(product);
$scope.sendForm();
};
$scope.recentId = 0;
$scope.logger = function (stuff) {
console.log('logger', stuff);
};
$scope.sendForm = function () {
console.log('$scope.sellingComment', $scope.sellingComment);
console.log('$rootScope.sellingComment', $rootScope.sellingComment);
console.log('$scope.sellingComment done');
console.log("$scope.activeSelling", $scope.activeSelling);
let lesParams = {
paidByClient : $scope.paidAmount,
sellingComment: $scope.activeFestival.productComment,
activeSelling : $scope.activeSelling,
activeFestival: $scope.activeFestival
};
$scope.recentSellings.push({
id : $scope.recentId++,
amount : $scope.CurrentSellingTotal(),
paidAmount: $scope.paidAmount,
products :
angular
.copy($scope.activeSelling)
});
console.log('lesParams sellingComment', lesParams.sellingComment);
console.log('$scope.recentSellings', $scope.recentSellings);
$scope.lesParams = lesParams;
$http({
method : 'POST',
url : 'logged/add-selling',
headers: {
'Content-Type': 'application/json'
},
data : lesParams // pass in data as strings
}).then(function (rep) {
// 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();
$scope.clearCurrentSelling();
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.showTemporaryErrorMessage();
})
;
};
$scope.sellingOk = false;
$scope.sellingError = false;
$scope.tempMessage = {};
$scope.showTemporaryMessage = function () {
console.log('show message');
if ($scope.sellingOk) {
$scope.sellingOk = false;
return;
}
$scope.sellingOk = true;
$timeout.cancel($scope.tempMessage);
$scope.tempMessage = $timeout(function () {
console.log('hide message');
$scope.sellingOk = false;
}, 2000)
};
$scope.showTemporaryErrorMessage = function () {
console.log('show message');
if ($scope.sellingError) {
$scope.sellingError = false;
return;
}
$scope.sellingError = true;
$timeout.cancel($scope.tempMessage);
$scope.tempMessage = $timeout(function () {
console.log('hide message');
$scope.sellingError = false;
}, 2000)
};
$scope.init = (function () {
$scope.fetchProductsFromDB();
})();
}])
.controller('previsionnelCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
$scope.config = {
initialLoadingDone : false,
loading : false,
lines : 24,
debounceTime : 300, // miliseconds to wait before updating model and saving changes
/**
* expenses kind of the user
*/
disponibility : 5000,
averageMonthlyEarnings: 600,
warningThershold : 2000,
showDelays : false,
showRepeats : false,
monthsBeforeNoMoney : null,
};
let exampleExpenses = [
{name: "appart", amount: 800, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "assurance voiture", amount: 50, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "internet", amount: 20, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "elec", amount: 100, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "chat", amount: 20, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "transports", amount: 70, delay: 0, repeat: $scope.config.lines, enabled: false},
];
// $scope.expenses=[];
$scope.expenses = exampleExpenses;
/**
* sum of all monthly expenses, ignoring delay
* @returns {number}
*/
$scope.sumMonthlyExpenses = () => {
let sum = 0;
$scope.expenses.forEach((elem) => {
if (elem.enabled) {
sum += elem.amount;
}
})
return sum;
};
$scope.previsionTable = [];
$scope.calculatePrevisionTable = () => {
let turns = $scope.config.lines;
let monthly = $scope.sumMonthlyExpenses();
let available = $scope.config.disponibility;
let previsionTable = [];
let changedNoMoneyConfig = false;
$scope.config.monthsBeforeNoMoney = null;
for (let i = 0; i <= turns; i++) {
// TODO take in account delays in expenses
available = available - monthly + $scope.config.averageMonthlyEarnings;
let newLine = {
expense : monthly,
available: available,
};
if (available <= 0 && !changedNoMoneyConfig) {
$scope.config.monthsBeforeNoMoney = i;
changedNoMoneyConfig = true;
}
previsionTable.push(newLine);
}
$scope.previsionTable = previsionTable;
$scope.makeGraphPointsOfPrevisionTable(previsionTable);
return previsionTable;
};
$scope.graphPointsPrevision = [];
$scope.makeGraphPointsOfPrevisionTable = (previsionTable) => {
console.log("previsionTable", previsionTable);
$scope.graphPointsPrevision = [];
for (let i = 0; i < previsionTable.length; i++) {
$scope.graphPointsPrevision.push({
label: previsionTable[i].available + " euros restants dans " + i + " mois",
y : previsionTable[i].available,
x : i,
})
}
}
$scope.updateconf = (rep) => {
// update view calculs
$scope.calculatePrevisionTable();
$scope.updateCanevas()
// flags
$scope.config.loading = false;
$scope.config.initialLoadingDone = true;
$scope.config.disponibility = rep.data.disponibility;
$scope.config.averageMonthlyEarnings = rep.data.averageMonthlyEarnings;
// default data when user has nothing saved
console.log('rep.data.expenses.length', rep.data.expenses.length)
if (!rep.data.expenses.length) {
$scope.expenses = exampleExpenses;
} else {
$scope.expenses = rep.data.expenses;
}
};
// http related calls
$scope.fetchExpenses = () => {
console.log('fetch expenses...');
$scope.config.loading = true;
$http.get('logged/get-my-expenses').then((rep) => {
console.log('logged/get-my-expenses', rep.data.expenses);
$scope.updateconf(rep)
},
$scope.manageError)
};
$scope.save = function () {
if ($scope.config.loading) {
console.log('already saving');
return;
}
console.log('update expenses...');
$scope.config.loading = true;
$http.post('logged/save-my-expenses', {
expenses: $scope.expenses,
config : $scope.config
})
.then((rep) => {
console.log('logged/save-my-expenses', rep);
$scope.updateconf(rep)
},
$scope.manageError)
};
$scope.addExpense = function () {
$scope.expenses.push({
name : "",
repeat: 0,
delay : 0,
amount: 0,
})
};
$scope.init = function () {
$scope.fetchExpenses();
};
$scope.manageError = (error) => {
console.error(error);
$scope.config.loading = false;
};
$scope.updateCanevas = function () {
var dataPoints = $scope.graphPointsPrevision;
var chartContainer = new CanvasJS.Chart("simulationPrevision", {
title: {
text: "Euros disponibles dans le temps"
},
// animationEnabled: true,
data : [
{
// Change type to "doughnut", "line", "splineArea", etc.
type : "splineArea",
dataPoints: dataPoints
}
]
});
chartContainer.render();
};
$scope.init();
}]);