Use ngResource for sheduled operations.

This commit is contained in:
Alexis Lahouze 2015-07-15 15:09:00 +02:00
parent 61ef6b19af
commit b8ea699f40
3 changed files with 143 additions and 142 deletions

View File

@ -16,42 +16,19 @@
"""
import dateutil.parser
from flask import json, request
from flask.ext.restful import Resource, fields, reqparse, marshal_with_field
from sqlalchemy.orm.exc import NoResultFound
from accountant import session_scope, session_aware
from accountant import session_aware
from ..models.scheduled_operations import ScheduledOperation
from .. import api, api_api
from .. import api_api
from ..fields import Object
@api.route("/scheduled_operations/<int:account_id>")
def get_scheduled_operations(account_id):
"""
Return entries for an account, year, and month.
"""
with session_scope() as session:
query = ScheduledOperation.get_scheduled_operations_for_account(
session, account_id)
return json.dumps([{
"id": i.id,
"start_date": i.start_date.strftime("%Y-%m-%d"),
"stop_date": i.stop_date.strftime("%Y-%m-%d"),
"day": str(i.day),
"frequency": str(i.frequency),
"label": i.label,
"value": str(i.value),
"category": i.category,
"account_id": i.account_id
} for i in query.all()])
resource_fields = {
'id': fields.Integer,
'start_date': fields.DateTime(dt_format='iso8601'),
@ -76,10 +53,23 @@ parser.add_argument('category', type=str)
parser.add_argument('account_id', type=int)
get_parser = reqparse.RequestParser()
get_parser.add_argument('account', type=int)
class ScheduledOperationListResource(Resource):
@session_aware
@marshal_with_field(fields.List(Object(resource_fields)))
def get(self, session):
kwargs = get_parser.parse_args()
return ScheduledOperation.get_scheduled_operations_for_account(
session, **kwargs
).all()
@session_aware
@marshal_with_field(Object(resource_fields))
def put(self, session):
def post(self, session):
"""
Add a new scheduled operation.
"""
@ -119,7 +109,7 @@ class ScheduledOperationResource(Resource):
@session_aware
@marshal_with_field(Object(resource_fields))
def put(self, scheduled_operation_id, session):
def post(self, scheduled_operation_id, session):
kwargs = parser.parse_args()
assert (id not in kwargs or kwargs.id is None

View File

@ -14,8 +14,20 @@
You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
*/
accountantApp.controller(
"SchedulerController", function($scope, $http, $rootScope, $filter, $routeParams) {
accountantApp
.factory("ScheduledOperations", ["$resource", function($resource) {
return $resource(
"/api/scheduled_operations/:id", {
id: "@id"
}
);
}])
.controller(
"SchedulerController", [
"$scope", "$http", "$rootScope", "$filter", "$routeParams", "ScheduledOperations",
function($scope, $http, $rootScope, $filter, $routeParams, ScheduledOperations) {
// Operations store and selection
$scope.operations = [];
$scope.selectedOperation = null;
@ -23,54 +35,24 @@ accountantApp.controller(
// Placeholder for saved value to cancel entry edition
$scope.savedOperation = null;
$scope.categories = [];
$scope.resetNewOperation = function() {
$scope.newOperation = new ScheduledOperations({});
};
$scope.resetNewOperation();
$scope.loadOperations = function(accountId) {
// Clean up selected entry.
$scope.selectedOperation = null;
$scope.savedOperation = null;
$http.get("/api/scheduled_operations/" + accountId).success($scope.loadOperations_success);
};
$scope.loadOperations_success = function(data) {
var operations = [{
id: null,
start_date: null,
stop_date: null,
day: null,
frequency: null,
label: null,
account_id: null,
category: null,
state: "edit"
}];
if(data) {
operations = operations.concat(angular.fromJson(data));
}
$scope.operations = operations;
$scope.$emit("operationsLoadedEvent", {operations: operations});
};
$scope.iconSaveClass = function(operation) {
if($scope.isNew(operation)) {
return "fa fa-plus";
} else if ($scope.isEditing(operation)) {
return "fa fa-floppy-o";
}
};
$scope.iconCancelClass = function(operation) {
if($scope.isNew(operation)) {
return "fa fa-times";
} else if ($scope.isEditing(operation)) {
return "fa fa-ban";
}
};
$scope.isNew = function(operation) {
return !operation.id;
$scope.operations = ScheduledOperations.query({
account: $routeParams.accountId
}, function(data) {
$scope.$emit("operationsLoadedEvent", {operations: data});
});
};
// Returns true if the entry is in editing state.
@ -82,73 +64,45 @@ accountantApp.controller(
return operation.id && (!operation.state || operation.state === 'display');
};
$scope.saveOperation = function(operation) {
if(!operation.account_id) {
$scope.createOperation = function(operation) {
operation.account_id = $routeParams.accountId;
}
// prepare the Ajax xall to save the sceduled operation.
var type;
var url = "/api/scheduled_operations";
operation.$save(function(data) {
$scope.resetNewOperation();
if(!$scope.isNew(operation)) {
url += "/" + operation.id;
}
$scope.$emit("operationCreatedEvent", data);
});
};
$http.put(url, angular.toJson(operation)).success(function(data) {
$scope.$on("operationCreatedEvent", function(e, operation) {
new PNotify({
type: "success",
title: "Save",
text: data
text: "Operation #" + operation.id + " created."
});
});
$scope.saveOperation = function(operation) {
operation.$save(function(data) {
$scope.$emit("operationSavedEvent", operation);
});
};
$scope.$on("operationSavedEvent", function(e, operation) {
new PNotify({
type: "success",
title: "Save",
text: "Operation #" + operation.id + " saved."
});
});
$scope.editOperation = function(operation) {
// Cancel previous editing.
if($scope.selectedOperation) {
$scope.cancelEditOperation($scope.selectedItem);
}
// Save current entry values.
$scope.savedOperation = angular.copy(operation);
$scope.selectedOperation = operation;
// Enter edit state.
operation.state='edit';
};
$scope.cancelEditOperation = function(operation) {
if ($scope.isNew(operation)) {
operation.id = null;
operation.start_date = null;
operation.stop_date = null;
operation.day = null;
operation.frequency = null;
operation.label = null;
operation.value = null;
operation.category = null;
operation.account_id = $routeParams.accountId;
} else if ($scope.isEditing(operation)) {
if($scope.savedOperation) {
operation.id = $scope.savedOperation.id;
operation.start_date = $scope.savedOperation.start_date;
operation.stop_date = $scope.savedOperation.stop_date;
operation.day = $scope.savedOperation.day;
operation.frequency = $scope.savedOperation.frequency;
operation.label = $scope.savedOperation.label;
operation.value = $scope.savedOperation.value;
operation.category = $scope.savedOperation.category;
operation.account_id = $scope.savedOperation.account_id;
}
$scope.savedOperation = null;
$scope.selectedOperation = null;
operation.state = 'display';
}
operation.$get();
};
$scope.removeOperation = function(operation, modalScope) {
@ -189,4 +143,4 @@ accountantApp.controller(
});
$scope.loadOperations($routeParams.accountId);
});
}]);

View File

@ -34,54 +34,67 @@
<!-- Body of the table containing the entries -->
<tbody>
<tr id="operation_[[operation.id]]" class="form-inline" ng-class="operationRowClass(operation.sold)" ng-repeat="operation in operations">
<tr class="form-inline">
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.start_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
<span ng-show="isDisplaying(operation)">[[operation.start_date]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.start_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
</td>
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.stop_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
<span ng-show="isDisplaying(operation)">[[operation.stop_date]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.stop_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
</td>
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.day"/>
<span ng-show="isDisplaying(operation)">[[operation.day]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.day"/>
</td>
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.frequency"/>
<span ng-show="isDisplaying(operation)">[[operation.frequency]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.frequency"/>
</td>
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.label"/>
<span ng-show="isDisplaying(operation)">[[operation.label]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.label"/>
</td>
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.value"/>
<span ng-show="isDisplaying(operation)">[[operation.value]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.value"/>
</td>
<td>
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.category" bs-typeahead="categories"/>
<span ng-show="isDisplaying(operation)">[[operation.category]]</span>
<input type="text" class="form-control input-sm" ng-model="newOperation.category" bs-typeahead="categories"/>
</td>
<td>
<div class="btn-group" ng-show="isEditing(operation)">
<button class="btn btn-xs btn-success" ng-click="saveOperation(operation)" title="Save">
<span ng-class="iconSaveClass(operation)"></span>
<div class="btn-group">
<button class="btn btn-xs btn-success" ng-click="createOperation(newOperation)" title="Save">
<span class="fa fa-plus"></span>
</button>
<button class="btn btn-xs btn-default" ng-click="cancelEditOperation(operation)" title="Cancel">
<span ng-class="iconCancelClass(operation)"></span>
<button class="btn btn-xs btn-default" ng-click="resetNewOperation()" title="Cancel">
<span class="fa fa-times"></span>
</button>
</div>
</td>
</tr>
<div class="btn-group" ng-show="isDisplaying(operation)">
<tr id="operation_[[operation.id]]" class="form-inline"
ng-repeat-start="operation in operations"
ng-if="isDisplaying(operation)">
<td>[[operation.start_date]]</td>
<td>[[operation.stop_date]]</td>
<td>[[operation.day]]</td>
<td>[[operation.frequency]]</td>
<td>[[operation.label]]</td>
<td>[[operation.value]]</td>
<td>[[operation.category]]</td>
<td>
<div class="btn-group">
<button class="btn btn-xs btn-default" ng-click="editOperation(operation)" title="edit">
<span class="fa fa-pencil-square-o"></span>
</button>
@ -92,6 +105,50 @@
</div>
</td>
</tr>
<tr id="operation_[[operation.id]]" class="form-inline"
ng-repeat-end
ng-if="isEditing(operation)">
<td>
<input type="text" class="form-control input-sm" ng-model="operation.start_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
</td>
<td>
<input type="text" class="form-control input-sm" ng-model="operation.stop_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
</td>
<td>
<input type="text" class="form-control input-sm" ng-model="operation.day"/>
</td>
<td>
<input type="text" class="form-control input-sm" ng-model="operation.frequency"/>
</td>
<td>
<input type="text" class="form-control input-sm" ng-model="operation.label"/>
</td>
<td>
<input type="text" class="form-control input-sm" ng-model="operation.value"/>
</td>
<td>
<input type="text" class="form-control input-sm" ng-model="operation.category" bs-typeahead="categories"/>
</td>
<td>
<div class="btn-group">
<button class="btn btn-xs btn-success" ng-click="saveOperation(operation)" title="Save">
<span class="fa fa-floppy-o"></span>
</button>
<button class="btn btn-xs btn-default" ng-click="cancelEditOperation(operation)" title="Cancel">
<span class="fa fa-times"></span>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>