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 import dateutil.parser
from flask import json, request
from flask.ext.restful import Resource, fields, reqparse, marshal_with_field from flask.ext.restful import Resource, fields, reqparse, marshal_with_field
from sqlalchemy.orm.exc import NoResultFound 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 ..models.scheduled_operations import ScheduledOperation
from .. import api, api_api from .. import api_api
from ..fields import Object 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 = { resource_fields = {
'id': fields.Integer, 'id': fields.Integer,
'start_date': fields.DateTime(dt_format='iso8601'), 'start_date': fields.DateTime(dt_format='iso8601'),
@ -76,10 +53,23 @@ parser.add_argument('category', type=str)
parser.add_argument('account_id', type=int) parser.add_argument('account_id', type=int)
get_parser = reqparse.RequestParser()
get_parser.add_argument('account', type=int)
class ScheduledOperationListResource(Resource): 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 @session_aware
@marshal_with_field(Object(resource_fields)) @marshal_with_field(Object(resource_fields))
def put(self, session): def post(self, session):
""" """
Add a new scheduled operation. Add a new scheduled operation.
""" """
@ -119,7 +109,7 @@ class ScheduledOperationResource(Resource):
@session_aware @session_aware
@marshal_with_field(Object(resource_fields)) @marshal_with_field(Object(resource_fields))
def put(self, scheduled_operation_id, session): def post(self, scheduled_operation_id, session):
kwargs = parser.parse_args() kwargs = parser.parse_args()
assert (id not in kwargs or kwargs.id is None 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 You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see <http://www.gnu.org/licenses/>. along with Accountant. If not, see <http://www.gnu.org/licenses/>.
*/ */
accountantApp.controller( accountantApp
"SchedulerController", function($scope, $http, $rootScope, $filter, $routeParams) {
.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 // Operations store and selection
$scope.operations = []; $scope.operations = [];
$scope.selectedOperation = null; $scope.selectedOperation = null;
@ -23,54 +35,24 @@ accountantApp.controller(
// Placeholder for saved value to cancel entry edition // Placeholder for saved value to cancel entry edition
$scope.savedOperation = null; $scope.savedOperation = null;
$scope.categories = [];
$scope.resetNewOperation = function() {
$scope.newOperation = new ScheduledOperations({});
};
$scope.resetNewOperation();
$scope.loadOperations = function(accountId) { $scope.loadOperations = function(accountId) {
// Clean up selected entry. // Clean up selected entry.
$scope.selectedOperation = null; $scope.selectedOperation = null;
$scope.savedOperation = null; $scope.savedOperation = null;
$http.get("/api/scheduled_operations/" + accountId).success($scope.loadOperations_success); $scope.operations = ScheduledOperations.query({
}; account: $routeParams.accountId
}, function(data) {
$scope.loadOperations_success = function(data) { $scope.$emit("operationsLoadedEvent", {operations: 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;
}; };
// Returns true if the entry is in editing state. // Returns true if the entry is in editing state.
@ -82,73 +64,45 @@ accountantApp.controller(
return operation.id && (!operation.state || operation.state === 'display'); return operation.id && (!operation.state || operation.state === 'display');
}; };
$scope.saveOperation = function(operation) { $scope.createOperation = function(operation) {
if(!operation.account_id) {
operation.account_id = $routeParams.accountId; operation.account_id = $routeParams.accountId;
}
// prepare the Ajax xall to save the sceduled operation. operation.$save(function(data) {
var type; $scope.resetNewOperation();
var url = "/api/scheduled_operations";
if(!$scope.isNew(operation)) { $scope.$emit("operationCreatedEvent", data);
url += "/" + operation.id; });
} };
$http.put(url, angular.toJson(operation)).success(function(data) { $scope.$on("operationCreatedEvent", function(e, operation) {
new PNotify({ new PNotify({
type: "success", type: "success",
title: "Save", title: "Save",
text: data text: "Operation #" + operation.id + " created."
}); });
});
$scope.saveOperation = function(operation) {
operation.$save(function(data) {
$scope.$emit("operationSavedEvent", operation); $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) { $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. // Enter edit state.
operation.state='edit'; operation.state='edit';
}; };
$scope.cancelEditOperation = function(operation) { $scope.cancelEditOperation = function(operation) {
if ($scope.isNew(operation)) { operation.$get();
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';
}
}; };
$scope.removeOperation = function(operation, modalScope) { $scope.removeOperation = function(operation, modalScope) {
@ -189,4 +143,4 @@ accountantApp.controller(
}); });
$scope.loadOperations($routeParams.accountId); $scope.loadOperations($routeParams.accountId);
}); }]);

View File

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