accountant-ui/accountant-ui/js/accounts.js
2017-06-10 18:03:08 +02:00

264 lines
7.7 KiB
JavaScript

// vim: set tw=80 ts=4 sw=4 sts=4:
/*
This file is part of Accountant.
Accountant is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Accountant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
*/
/* jshint node: true */
'use strict';
var angular = require('angular');
var ngResource = require('angular-resource'),
ngMessages = require('angular-messages'),
ngUiNotification = require('angular-ui-notification'),
ngBootbox = require('ngbootbox');
// Note: ngBootbox seems to have no module.exports.
ngBootbox = 'ngBootbox';
// FIXME Alexis Lahouze 2017-06-06 move into templates.js.
require('../views/account.form.tmpl.html');
var accountModule = angular.module('accountant.accounts', [
ngResource,
ngMessages,
ngUiNotification,
ngBootbox
])
.config(function($resourceProvider) {
// Keep trailing slashes to avoid redirect by flask..
$resourceProvider.defaults.stripTrailingSlashes = false;
})
.factory('Account', function($resource) {
var Account = $resource(
'/api/account/:id', {
id: '@id'
}
);
Account.prototype.getSolds = function() {
var Solds = $resource('/api/account/:id/balances', {id: this.id});
this.solds = Solds.get();
};
Account.prototype.getBalance = function(begin, end) {
var Balance = $resource(
'/api/account/:id/balance', {
id: this.id,
begin: begin.format('YYYY-MM-DD'),
end: end.format('YYYY-MM-DD')
});
this.balance = Balance.get();
};
return Account;
})
.controller('AccountController', function($ngBootbox, Account, Notification) {
var vm = this;
/*
* Return the class for an account current value compared to authorized
* overdraft.
*/
vm.rowClass = function(account) {
// eslint-disable-next-line camelcase
if (!account || !account.authorized_overdraft || !account.current) {
return;
}
// eslint-disable-next-line camelcase
if (account.current < account.authorized_overdraft) {
return 'danger';
} else if (account.current < 0) {
return 'warning';
}
};
/*
* Return the class for a value compared to account authorized overdraft.
*/
vm.valueClass = function(account, value) {
if (!account || !value) {
return;
}
// eslint-disable-next-line camelcase
if (value < account.authorized_overdraft) {
return 'text-danger';
} else if (value < 0) {
return 'text-warning';
}
};
/*
* Add an empty account.
*/
vm.add = function() {
var account = new Account({
// eslint-disable-next-line camelcase
authorized_overdraft: 0
});
// Insert account at the begining of the array.
vm.accounts.splice(0, 0, account);
};
/*
* Cancel account edition. Remove it from array if a new one.
*/
vm.cancelEdit = function(rowform, account, $index) {
if (account.id) {
rowform.$cancel();
} else {
// Account not saved, just remove it from array.
vm.accounts.splice($index, 1);
}
};
/*
* Save account.
*/
vm.save = function(account) {
// var account = vm.accounts[$index];
// account = angular.merge(account, $data);
return account.$save().then(function(data) {
Notification.success('Account #' + data.id + ' saved.');
// TODO Alexis Lahouze 2016-03-08 Update solds
return data;
});
};
/*
* Delete an account.
*/
vm.delete = function(account, $index) {
var id = account.id;
$ngBootbox.confirm(
'Voulez-vous supprimer le compte \'' + account.name + '\' ?',
function(result) {
if (result) {
account.$delete().then(function() {
Notification.success('Account #' + id + ' deleted.');
// Remove account from array.
vm.accounts.splice($index, 1);
});
}
}
);
};
// Load accounts.
vm.accounts = Account.query();
})
.directive('accountFormDialog', function(Account, $ngBootbox, Notification, $log) {
return {
restrict: 'A',
scope: {
account: '=ngModel'
},
link: function(scope, element) {
var title = 'Account';
if (scope.account && scope.account.id) {
title = title + ' #' + scope.account.id;
}
scope.form = {};
scope.submitForm = function() {
// check to make sure the form is completely valid
if (!scope.form.$valid) {
return false;
}
// Authorized overdraft is a positive integer but data is a negative integer.
// eslint-disable-next-line camelcase
scope.data.authorized_overdraft = -scope.data.authorized_overdraft;
angular.copy(scope.data, scope.account);
// Save account
$log.log(scope.account);
return scope.account.$save().then(
function(data) {
Notification.success('Account #' + data.id + ' saved.');
scope.account.getSolds();
return data;
},
function(data) {
Notification.error('Error while saving account #' + data.id);
scope.account.getSolds();
$log.log(data);
return false;
}
);
};
element.on('click', function() {
// Create new account if not passed in ng-model.
if (!scope.account) {
scope.account = new Account({
// eslint-disable-next-line camelcase
authorized_overdraft: 0
});
}
scope.data = {};
angular.copy(scope.account, scope.data);
// Authorized overdraft must be positive in form.
// eslint-disable-next-line camelcase
scope.data.authorized_overdraft = -scope.data.authorized_overdraft;
// Open dialog with form.
$ngBootbox.customDialog({
scope: scope,
title: title,
templateUrl: '/views/account.form.tmpl.html',
onEscape: true,
buttons: {
save: {
label: 'Save',
className: 'btn-success',
callback: scope.submitForm
},
cancel: {
label: 'Cancel',
className: 'btn-default',
callback: true
}
}
});
});
}
};
});
module.exports = accountModule;