Rewrote views with Restful resources.
This commit is contained in:
parent
c62941a704
commit
be1bba3bc8
@ -15,36 +15,22 @@
|
||||
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from flask import json, request
|
||||
from flask.ext.restful import Resource, fields, reqparse, marshal_with_field
|
||||
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from forms.accounts import AccountForm
|
||||
|
||||
from accountant import session_scope
|
||||
from accountant import session_scope, session_aware
|
||||
|
||||
from . import auth
|
||||
from .. import api
|
||||
from .. import api, api_api
|
||||
|
||||
from ..models.accounts import Account
|
||||
from ..models.entries import Entry
|
||||
from ..models.operations import Operation
|
||||
|
||||
|
||||
@api.route("/accounts", methods=["GET"])
|
||||
@auth.login_required
|
||||
def get_accounts():
|
||||
"""
|
||||
Returns accounts with their solds.
|
||||
"""
|
||||
with session_scope() as session:
|
||||
query = Account.get_accounts(session)
|
||||
|
||||
return json.dumps([{
|
||||
"id": i.id,
|
||||
"name": i.name,
|
||||
"authorized_overdraft": i.authorized_overdraft,
|
||||
"current": str(i.current),
|
||||
"pointed": str(i.pointed),
|
||||
"future": str(i.future)
|
||||
} for i in query.all()])
|
||||
from ..fields import Object
|
||||
|
||||
|
||||
@api.route("/accounts/<account_id>/<year>/<month>/")
|
||||
@ -82,50 +68,114 @@ def get_months(account_id):
|
||||
} for i in query.all()])
|
||||
|
||||
|
||||
@api.route("/accounts", methods=["PUT"])
|
||||
@auth.login_required
|
||||
def add_account():
|
||||
with session_scope() as session:
|
||||
account = Account(request.json['name'],
|
||||
request.json['authorized_overdraft'])
|
||||
resource_fields = {
|
||||
'id': fields.Integer,
|
||||
'name': fields.String,
|
||||
'authorized_overdraft': fields.Fixed(decimals=2),
|
||||
'current': fields.Float,
|
||||
'pointed': fields.Float,
|
||||
'future': fields.Float,
|
||||
}
|
||||
|
||||
|
||||
parser = reqparse.RequestParser()
|
||||
parser.add_argument('name', type=str, required=True)
|
||||
parser.add_argument('authorized_overdraft', type=float, required=True)
|
||||
|
||||
|
||||
class AccountListResource(Resource):
|
||||
@session_aware
|
||||
@marshal_with_field(fields.List(Object(resource_fields)))
|
||||
def get(self, session=None):
|
||||
"""
|
||||
Returns accounts with their balances.
|
||||
"""
|
||||
return Account.get_accounts(session).all(), 200
|
||||
|
||||
def put(self):
|
||||
"""
|
||||
Batch update, not implemented.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def post(self, session=None):
|
||||
"""
|
||||
Create a new account.
|
||||
"""
|
||||
kwargs = parser.parse_args()
|
||||
|
||||
account = Account(**kwargs)
|
||||
|
||||
session.add(account)
|
||||
|
||||
return json.dumps("Account added.")
|
||||
return account, 201
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Batch delete, not implemented.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@api.route("/accounts/<account_id>", methods=["PUT"])
|
||||
@auth.login_required
|
||||
def update_account(account_id):
|
||||
account_form = AccountForm()
|
||||
class AccountResource(Resource):
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def get(self, account_id, session=None):
|
||||
"""
|
||||
Get account.
|
||||
"""
|
||||
try:
|
||||
return Account.get(session, account_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
if account_form.validate():
|
||||
with session_scope() as session:
|
||||
account = session.query(Account).get(account_id)
|
||||
|
||||
account.name = request.json['name']
|
||||
account.authorized_overdraft = request.json['authorized_overdraft']
|
||||
|
||||
session.merge(account)
|
||||
|
||||
return json.dumps("Account #%s updated." % account_id)
|
||||
else:
|
||||
return json.dumps({
|
||||
'ok': False,
|
||||
'error_type': 'validation',
|
||||
'errors': account_form.errorsi
|
||||
})
|
||||
|
||||
|
||||
@api.route("/accounts/<account_id>", methods=["DELETE"])
|
||||
@auth.login_required
|
||||
def delete_account(account_id):
|
||||
with session_scope() as session:
|
||||
query = session.query(Account)
|
||||
query = query.filter(Account.id == account_id)
|
||||
|
||||
account = query.first()
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def delete(self, account_id, session=None):
|
||||
try:
|
||||
account = Account.get(session, account_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
session.delete(account)
|
||||
|
||||
return json.dumps("Account #%s deleted." % account_id)
|
||||
return account
|
||||
|
||||
def patch(self, id):
|
||||
pass
|
||||
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def put(self, account_id, session=None):
|
||||
kwargs = parser.parse_args()
|
||||
|
||||
assert (id not in kwargs or kwargs.id is None
|
||||
or kwargs.id == account_id)
|
||||
|
||||
account_form = AccountForm()
|
||||
|
||||
if account_form.validate():
|
||||
try:
|
||||
account = Account.get(session, account_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
# SQLAlchemy objects ignore __dict__.update() with merge.
|
||||
for k, v in kwargs.items():
|
||||
setattr(account, k, v)
|
||||
|
||||
session.merge(account)
|
||||
|
||||
return account
|
||||
else:
|
||||
return json.dumps({
|
||||
'ok': False,
|
||||
'error_type': 'validation',
|
||||
'errors': account_form.errors
|
||||
})
|
||||
|
||||
|
||||
api_api.add_resource(AccountListResource, '/accounts')
|
||||
api_api.add_resource(AccountResource, '/accounts/<int:account_id>')
|
||||
|
@ -14,15 +14,22 @@
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from flask import json, request
|
||||
import dateutil.parser
|
||||
|
||||
from accountant import session_scope
|
||||
from flask import json
|
||||
from flask.ext.restful import Resource, fields, reqparse, marshal_with_field
|
||||
|
||||
from .. import api
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from accountant import session_scope, session_aware
|
||||
|
||||
from .. import api, api_api
|
||||
|
||||
from ..models.entries import Entry
|
||||
from ..models.operations import Operation
|
||||
|
||||
from ..fields import Object
|
||||
|
||||
|
||||
@api.route("/entries/<account_id>/<year>/<month>")
|
||||
def get_entries(account_id, year, month):
|
||||
@ -47,48 +54,90 @@ def get_entries(account_id, year, month):
|
||||
} for i in query.all()])
|
||||
|
||||
|
||||
@api.route("/entries", methods=["PUT"])
|
||||
def add_entry():
|
||||
with session_scope() as session:
|
||||
entry = Entry(
|
||||
operation_date=request.json['operation_date'],
|
||||
pointed=request.json['pointed'],
|
||||
label=request.json['label'],
|
||||
value=request.json['value'],
|
||||
category=request.json['category'],
|
||||
account_id=request.json['account_id'],
|
||||
scheduled_operation_id=request.json['scheduled_operation_id']
|
||||
)
|
||||
resource_fields = {
|
||||
# 'id': fields.Integer,
|
||||
'operation_date': fields.DateTime(dt_format='iso8601'),
|
||||
'label': fields.String,
|
||||
'value': fields.Fixed(decimals=2),
|
||||
'pointed': fields.Boolean,
|
||||
'category': fields.String,
|
||||
'account_id': fields.Integer,
|
||||
'scheduled_operation_id': fields.Integer,
|
||||
}
|
||||
|
||||
parser = reqparse.RequestParser()
|
||||
# Must use lambda because the parser passes other parameters badly interpreted
|
||||
# by dateutil.parser.parse
|
||||
parser.add_argument('operation_date', type=lambda a: dateutil.parser.parse(a))
|
||||
parser.add_argument('label', type=str)
|
||||
parser.add_argument('value', type=float)
|
||||
parser.add_argument('pointed', type=bool)
|
||||
parser.add_argument('category', type=str)
|
||||
parser.add_argument('account_id', type=int)
|
||||
parser.add_argument('scheduled_operation_id', type=int)
|
||||
|
||||
|
||||
class EntryListResource(Resource):
|
||||
def put(self, *args):
|
||||
return self.post()
|
||||
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def post(self, session=None):
|
||||
kwargs = parser.parse_args()
|
||||
|
||||
entry = Entry(**kwargs)
|
||||
|
||||
session.add(entry)
|
||||
|
||||
return json.dumps("Entry added.")
|
||||
return entry
|
||||
|
||||
|
||||
@api.route("/entries/<entry_id>", methods=["PUT"])
|
||||
def update_entry(entry_id):
|
||||
with session_scope() as session:
|
||||
entry = session.query(Entry).get(entry_id)
|
||||
class EntryResource(Resource):
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def get(self, entry_id, session=None):
|
||||
"""
|
||||
Get entry.
|
||||
"""
|
||||
try:
|
||||
return Entry.get(session, entry_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
entry.id = entry_id
|
||||
entry.operation_date = request.json['operation_date']
|
||||
entry.pointed = request.json['pointed']
|
||||
entry.label = request.json['label']
|
||||
entry.value = request.json['value']
|
||||
entry.category = request.json['category']
|
||||
entry.account_id = request.json['account_id']
|
||||
entry.scheduled_operation_id = request.json['scheduled_operation_id']
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def put(self, entry_id, session=None):
|
||||
kwargs = parser.parse_args()
|
||||
|
||||
assert (id not in kwargs or kwargs.id is None
|
||||
or kwargs.id == entry_id)
|
||||
|
||||
try:
|
||||
entry = Entry.get(session, entry_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
# SQLAlchemy objects ignore __dict__.update() with merge.
|
||||
for k, v in kwargs.items():
|
||||
setattr(entry, k, v)
|
||||
|
||||
session.merge(entry)
|
||||
|
||||
return json.dumps("Entry #%s updated." % entry_id)
|
||||
return entry
|
||||
|
||||
|
||||
@api.route("/entries/<entry_id>", methods=["DELETE"])
|
||||
def delete_entry(entry_id):
|
||||
with session_scope() as session:
|
||||
entry = session.query(Entry).filter(Entry.id == entry_id).first()
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def delete(self, entry_id, session=None):
|
||||
try:
|
||||
entry = Entry.get(session, entry_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
session.delete(entry)
|
||||
|
||||
return json.dumps("Entry #%s deleted." % entry_id)
|
||||
return entry
|
||||
|
||||
|
||||
api_api.add_resource(EntryListResource, "/entries")
|
||||
api_api.add_resource(EntryResource, "/entries/<int:entry_id>")
|
||||
|
@ -14,16 +14,23 @@
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from flask import json, request
|
||||
import dateutil.parser
|
||||
|
||||
from accountant import session_scope
|
||||
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 ..models.scheduled_operations import ScheduledOperation
|
||||
|
||||
from .. import api
|
||||
from .. import api, api_api
|
||||
|
||||
from ..fields import Object
|
||||
|
||||
|
||||
@api.route("/scheduled_operations/<account_id>")
|
||||
@api.route("/scheduled_operations/<int:account_id>")
|
||||
def get_scheduled_operations(account_id):
|
||||
"""
|
||||
Return entries for an account, year, and month.
|
||||
@ -45,57 +52,94 @@ def get_scheduled_operations(account_id):
|
||||
} for i in query.all()])
|
||||
|
||||
|
||||
@api.route("/scheduled_operations", methods=["PUT"])
|
||||
def add_scheduled_operation():
|
||||
with session_scope() as session:
|
||||
scheduledOperation = ScheduledOperation(
|
||||
start_date=request.json['start_date'],
|
||||
stop_date=request.json['stop_date'],
|
||||
day=request.json['day'],
|
||||
frequency=request.json['frequency'],
|
||||
label=request.json['label'],
|
||||
value=request.json['value'],
|
||||
category=request.json['category'],
|
||||
account_id=request.json['account_id']
|
||||
)
|
||||
resource_fields = {
|
||||
'id': fields.Integer,
|
||||
'start_date': fields.DateTime(dt_format='iso8601'),
|
||||
'stop_date': fields.DateTime(dt_format='iso8601'),
|
||||
'day': fields.Integer,
|
||||
'frequency': fields.Integer,
|
||||
'label': fields.String,
|
||||
'value': fields.Fixed(decimals=2),
|
||||
'category': fields.String,
|
||||
'account_id': fields.Integer,
|
||||
}
|
||||
|
||||
|
||||
parser = reqparse.RequestParser()
|
||||
parser.add_argument('start_date', type=lambda a: dateutil.parser.parse(a))
|
||||
parser.add_argument('stop_date', type=lambda a: dateutil.parser.parse(a))
|
||||
parser.add_argument('day', type=int)
|
||||
parser.add_argument('frequency', type=int)
|
||||
parser.add_argument('label', type=str)
|
||||
parser.add_argument('value', type=float)
|
||||
parser.add_argument('category', type=str)
|
||||
parser.add_argument('account_id', type=int)
|
||||
|
||||
|
||||
class ScheduledOperationListResource(Resource):
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def put(self, session=None):
|
||||
"""
|
||||
Add a new scheduled operation.
|
||||
"""
|
||||
kwargs = parser.parse_args()
|
||||
|
||||
scheduledOperation = ScheduledOperation(**kwargs)
|
||||
|
||||
session.add(scheduledOperation)
|
||||
|
||||
return json.dumps("Scheduled operation added.")
|
||||
return scheduledOperation, 201
|
||||
|
||||
|
||||
@api.route("/scheduled_operations/<scheduled_operation_id>", methods=["PUT"])
|
||||
def update_scheduled_operation(scheduled_operation_id):
|
||||
with session_scope() as session:
|
||||
query = session.query(ScheduledOperation)
|
||||
query = query.filter(ScheduledOperation.id == scheduled_operation_id)
|
||||
class ScheduledOperationResource(Resource):
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def get(self, scheduled_operation_id, session=None):
|
||||
"""
|
||||
Get scheduled operation.
|
||||
"""
|
||||
try:
|
||||
return ScheduledOperation.get(session, scheduled_operation_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
scheduledOperation = query.first()
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def delete(self, scheduled_operation_id, session=None):
|
||||
try:
|
||||
scheduled_operation = ScheduledOperation.get(
|
||||
session, scheduled_operation_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
scheduledOperation.id = scheduled_operation_id
|
||||
scheduledOperation.start_date = request.json['start_date'],
|
||||
scheduledOperation.stop_date = request.json['stop_date'],
|
||||
scheduledOperation.day = request.json['day'],
|
||||
scheduledOperation.frequency = request.json['frequency'],
|
||||
scheduledOperation.label = request.json['label']
|
||||
scheduledOperation.value = request.json['value']
|
||||
scheduledOperation.category = request.json['category']
|
||||
scheduledOperation.account_id = request.json['account_id']
|
||||
session.delete(scheduled_operation)
|
||||
|
||||
session.merge(scheduledOperation)
|
||||
return scheduled_operation
|
||||
|
||||
return json.dumps(
|
||||
"Scheduled operation #%s updated." % scheduled_operation_id)
|
||||
@session_aware
|
||||
@marshal_with_field(Object(resource_fields))
|
||||
def put(self, scheduled_operation_id, session=None):
|
||||
kwargs = parser.parse_args()
|
||||
|
||||
assert (id not in kwargs or kwargs.id is None
|
||||
or kwargs.id == scheduled_operation_id)
|
||||
|
||||
try:
|
||||
scheduled_operation = ScheduledOperation.get(
|
||||
session, scheduled_operation_id)
|
||||
except NoResultFound:
|
||||
return None, 404
|
||||
|
||||
# SQLAlchemy objects ignore __dict__.update() with merge.
|
||||
for k, v in kwargs.items():
|
||||
setattr(scheduled_operation, k, v)
|
||||
|
||||
session.merge(scheduled_operation)
|
||||
|
||||
return scheduled_operation
|
||||
|
||||
|
||||
@api.route("/scheduled_operations/<scheduled_operation_id>", methods=["DELETE"])
|
||||
def delete_scheduled_operation(scheduled_operation_id):
|
||||
with session_scope() as session:
|
||||
query = session.query(ScheduledOperation)
|
||||
query = query.filter(ScheduledOperation.id == scheduled_operation_id)
|
||||
scheduledOperation = query.first()
|
||||
|
||||
session.delete(scheduledOperation)
|
||||
|
||||
return json.dumps(
|
||||
"Scheduled operation #%s deleted." % scheduled_operation_id)
|
||||
api_api.add_resource(ScheduledOperationListResource, "/scheduled_operations")
|
||||
api_api.add_resource(ScheduledOperationResource,
|
||||
"/scheduled_operations/<int:scheduled_operation_id>")
|
||||
|
Loading…
Reference in New Issue
Block a user