var transactionControllers = angular.module('transactionControllers', ['ngResource']); function amountToNumber(amount) { var number = amount.toString().replace(',', '.'); if (number.charAt(0) !== '+' && number.charAt(0) !== '-') { number = '-' + number; } return number; } function numberToAmount(number) { var amount = number.toFixed(2).toString().replace('.', ','); if (amount.charAt(0) !== '-' && amount !== '0,00') { amount = "+" + amount; } return amount; } transactionControllers.controller('TransactionListCtrl', [ '$scope', '$routeParams', '$resource', '$q', '$uibModal', '$log', 'Transaction', function($scope, $routeParams, $resource, $q, $uibModal, $log, Transaction) { function refreshExpenses() { var accountUsers = $resource($scope.account._links.users.href).get(); accountUsers.$promise.then(function(data) { $scope.accountUsers = accountUsers._embedded.users; // get outstandings (expenses and withdrawals) for all users of the account var promises = new Array($scope.accountUsers.length); for (i = 0; i < $scope.accountUsers.length; i++) { var resource = $resource('/transactions/search/outstandings', { accountId: $scope.account.id, userId: $scope.accountUsers[i].id }).get(); promises[i] = resource.$promise; } $q.all(promises).then(function(data) { for (i = 0; i < data.length; i++) { $scope.accountUsers[i].outstandings = new Array(data[i]._embedded.transactions.length); $scope.accountUsers[i].outstandingSum = 0.0; for (j = 0; j < data[i]._embedded.transactions.length; j++) { $scope.accountUsers[i].outstandings[j] = new Object(); $scope.accountUsers[i].outstandings[j].date = data[i]._embedded.transactions[j].date; $scope.accountUsers[i].outstandings[j].description = data[i]._embedded.transactions[j].description; $scope.accountUsers[i].outstandings[j].href = data[i]._embedded.transactions[j]._links.self.href; $scope.accountUsers[i].outstandings[j].category = data[i]._embedded.transactions[j].category.name; if ($scope.accountUsers[i].outstandings[j].category === 'Private Entnahme') { // magic strings ftw $scope.accountUsers[i].outstandingSum += data[i]._embedded.transactions[j].amount; $scope.accountUsers[i].outstandings[j].amount = numberToAmount(data[i]._embedded.transactions[j].amount); } else { $scope.accountUsers[i].outstandingSum -= data[i]._embedded.transactions[j].amount; $scope.accountUsers[i].outstandings[j].amount = numberToAmount(-data[i]._embedded.transactions[j].amount); } } $scope.accountUsers[i].outstandingAmount = numberToAmount($scope.accountUsers[i].outstandingSum); } }); }); } $scope.refreshList = function() { // reset form if ($scope.form) { $scope.form.$setPristine(); $scope.form.$setUntouched(); } $scope.transaction = { amount: undefined, date: new Date(), creditor: "" }; if (typeof $scope.categories !== 'undefined') { $scope.transaction.category = $scope.categories[0]; } // get recent transactions var transactions = $resource('/transactions/search/forAccount', { accountId: $scope.account.id, size: $scope.pageSize, sort: 'date,desc' }).get(); transactions.$promise.then(function(data) { $scope.transactions = transactions._embedded.transactions; $scope.nextPageAvailable = (transactions.page.totalPages !== transactions.page.number + 1); $scope.prevPageAvailable = (transactions.page.number > 0); $scope.pageNumber = transactions.page.number; for (i = 0; i < $scope.transactions.length; i++) { $scope.transactions[i].amount = numberToAmount($scope.transactions[i].amount); } }); refreshExpenses(); } $scope.checkCategory = function() { var radioButtons = document.getElementsByName('expenseBy'); var userLabels = document.getElementsByClassName('userLabel'); // if this is selected to be a withdrawal, preselect the current user and lock the radio buttons if ($scope.transaction.category.name === 'Private Entnahme') { for (i = 0; i < userLabels.length; i++) { if (userLabels[i].innerHTML.indexOf($scope.userinfo.name) >= 0) { userLabels[i].getElementsByTagName('INPUT')[0].checked = true; } } for (i = 0; i < radioButtons.length; i++) { radioButtons[i].disabled = true; } } else { for (i = 0; i < radioButtons.length; i++) { radioButtons[i].disabled = false; } radioButtons[0].checked = true; } } $scope.initList = function() { $scope.pageSize = 20; var userinfo = $resource('/user').get(); userinfo.$promise.then(function(data) { $scope.userid = userinfo.name; userinfo = $resource('/users/search/findByUsername', { username: $scope.userid }).get(); userinfo.$promise.then(function(data) { $scope.userinfo = userinfo; }); var accountInfo = $resource('/accounts/search/findByUserName', { username: $scope.userid }).get(); accountInfo.$promise.then(function(data) { $scope.accounts = accountInfo._embedded.accounts; if ($scope.account == undefined) { $scope.account = $scope.accounts[0]; if ($routeParams.account != undefined) { for (i = 0; i < $scope.accounts.length; i++) { if ($scope.accounts[i].name == $routeParams.account) $scope.account = $scope.accounts[i]; } } } var categories = $resource('/categories/search/listForAccount', { accountId: $scope.account.id }).get(); categories.$promise.then(function(data) { $scope.categories = categories._embedded.categories; $scope.refreshList(); }); }); }); } $scope.submitTransaction = function() { if (document.getElementById('amountInput').value) { document.getElementById('transactionSubmit').disabled = true; $scope.waitingForSubmission = true; var newTransaction = new Transaction({ "account" : $scope.account._links.self.href, "amount" : amountToNumber($scope.transaction.amount), "date" : $scope.transaction.date, "description" : $scope.transaction.description, "category" : $scope.transaction.category._links.self.href, "creditor" : $scope.transaction.creditor }); newTransaction.$save(function(transaction) { document.getElementById('transactionSubmit').disabled = false; $scope.waitingForSubmission = false; $scope.refreshList(); $scope.lastSubmission = newTransaction; }); } } $scope.deleteLastSubmission = function() { var testTrns = $resource($scope.lastSubmission._links.self.href).delete(function() { $scope.lastSubmission = undefined; $scope.refreshList(); }); }; $scope.moreTransactions = function() { if ($scope.nextPageAvailable) { $scope.pageNumber++; var transactions = $resource('/transactions/search/forAccount', { accountId: $scope.account.id, size: $scope.pageSize, sort: 'date,desc', page: $scope.pageNumber }).get(); transactions.$promise.then(function(data) { for (i = 0; i < transactions._embedded.transactions.length; i++) { transactions._embedded.transactions[i].amount = numberToAmount(transactions._embedded.transactions[i].amount); } $scope.transactions = $scope.transactions.concat(transactions._embedded.transactions); $scope.nextPageAvailable = (transactions.page.totalPages !== transactions.page.number + 1); $scope.prevPageAvailable = (transactions.page.number > 0); $scope.pageNumber = transactions.page.number; }); } }; $scope.updateSuggestions = function(val) { var suggestions = $resource('/transactions/search/descriptions', { accountId: $scope.account.id, prefix: val.toLowerCase() }).get(); return suggestions.$promise.then(function(data) { var newSuggestions = new Array(suggestions._embedded.transactions.length); for (i = 0; i < suggestions._embedded.transactions.length; i++) { newSuggestions[i] = suggestions._embedded.transactions[i].description; } return newSuggestions; }); }; $scope.openDetails = function(transaction) { var modalInstance = $uibModal.open({ templateUrl: 'detailsTemplate.html', controller: 'DetailsModalCtrl', resolve: { transactionId: transaction.id, categories: function () { return $scope.categories; }, accountUsers: function () { return $scope.accountUsers; } } }); modalInstance.result.then(function(editedTransaction) { $scope.lastSubmission = undefined; if (editedTransaction.amount != undefined) { transaction.amount = editedTransaction.amount; transaction.date = editedTransaction.date; transaction.description = editedTransaction.description; transaction.creditor = $resource(editedTransaction.creditor).get(); transaction.category = $resource(editedTransaction.category).get(); } else { // if the transaction has been deleted, only the ID is returned for (i = 0; i < $scope.transactions.length; i++) { if ($scope.transactions[i].id == editedTransaction) { $scope.transactions.splice(i, 1); } } } refreshExpenses(); }, function () { $log.info('DetailsModal dismissed ' + new Date()); }); }; $scope.openOutstandings = function(user) { var modalInstance = $uibModal.open({ templateUrl: 'outstandingsTemplate.html', controller: 'OutstandingsModalCtrl', resolve: { accountUser: user } }); modalInstance.result.then(function() { $scope.refreshList(); }, function () { $log.info('OutstandingsModal dismissed ' + new Date()); }); }; // initialize (http://stackoverflow.com/a/25662066/3761783) $scope.initList(); } ]); transactionControllers.controller('DetailsModalCtrl', [ '$scope', '$resource', '$uibModalInstance', 'Transaction', 'transactionId', 'categories', 'accountUsers', function($scope, $resource, $uibModalInstance, Transaction, transactionId, categories, accountUsers) { $scope.accountUsers = accountUsers; var transaction = Transaction.get({ id: transactionId }); transaction.$promise.then(function(data) { transaction.amount = numberToAmount(transaction.amount); transaction.date = new Date(transaction.date); transaction.creditor = $resource(transaction._links.creditor.href).get(); transaction.category = $resource(transaction._links.category.href).get(); transaction.category.$promise.then(function(data) { $scope.transaction = transaction; $scope.categories = categories; for (i = 0; i < $scope.categories.length; i++) { if ($scope.categories[i].name == $scope.transaction.category.name) { $scope.transaction.category = $scope.categories[i]; break; } } transaction.creditor.$promise.then(function(data) { $scope.transaction.creditor = $scope.transaction.creditor._links.user.href; }, function(error) { // transactions without a creditor return a HTTP 404 error $scope.transaction.creditor = ""; }); }); }); $scope.ok = function () { $scope.transaction.category = $scope.transaction.category._links.self.href; $scope.transaction.amount = amountToNumber($scope.transaction.amount); $scope.transaction.$update(function(data) {}).then( $uibModalInstance.close($scope.transaction) ); }; $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); }; $scope.deleteTransaction = function() { var deletedTransactionId = $scope.transaction.id; $resource($scope.transaction._links.self.href).remove().$promise.then(function() { $uibModalInstance.close(deletedTransactionId); }); } } ]); transactionControllers.controller('OutstandingsModalCtrl', [ '$scope', '$uibModalInstance', '$http', '$resource', '$q', 'accountUser', function($scope, $uibModalInstance, $http, $resource, $q, accountUser) { $scope.accountUser = accountUser; $scope.ok = function () { $uibModalInstance.close(); }; $scope.close = function () { $uibModalInstance.dismiss('close'); }; $scope.clearOutstandings = function() { var promises = new Array($scope.accountUser.outstandings.length); for (i = 0; i < $scope.accountUser.outstandings.length; i++) { if ($scope.accountUser.outstandings[i].category === 'Private Entnahme') { // delete withdrawals var resource = $resource($scope.accountUser.outstandings[i].href).remove(); promises[i] = resource.$promise; } else { // remove creditor from expenses promises[i] = $http.patch($scope.accountUser.outstandings[i].href, '{ "creditor" : "" }'); } } $q.all(promises).then(function(data) { $uibModalInstance.close('cleared outstandings'); }); } } ]);