2015-08-19 15:51:04 +02:00

155 lines
4.1 KiB
Python

"""
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/>.
"""
import dateutil.parser
from flask.ext.restful import Resource, fields, reqparse, marshal_with_field
from sqlalchemy.orm.exc import NoResultFound
from accountant import session_aware
from .. import api_api
from ..models.accounts import Account
from ..fields import Object
resource_fields = {
'id': fields.Integer(default=None),
'name': fields.String,
'authorized_overdraft': fields.Float,
'current': fields.Float,
'pointed': fields.Float,
'future': fields.Float,
'expenses': fields.Float,
'revenues': fields.Float,
'balance': fields.Float,
}
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True)
parser.add_argument('authorized_overdraft', type=float, required=True)
date_parser = reqparse.RequestParser()
date_parser.add_argument('begin',
type=lambda a: dateutil.parser.parse(a) if a else None)
date_parser.add_argument('end',
type=lambda a: dateutil.parser.parse(a) if a else None)
class AccountListResource(Resource):
@session_aware
@marshal_with_field(fields.List(Object(resource_fields)))
def get(self, session):
"""
Returns accounts with their balances.
"""
return Account.query(session).all(), 200
@session_aware
@marshal_with_field(Object(resource_fields))
def post(self, session):
"""
Create a new account.
"""
kwargs = parser.parse_args()
account = Account(**kwargs)
session.add(account)
# Flush session to have id in account.
session.flush()
# Return account with solds.
return Account.query(
session
).filter(
Account.id == account.id
).one(), 201
def delete(self):
"""
Batch delete, not implemented.
"""
raise NotImplementedError()
class AccountResource(Resource):
@session_aware
@marshal_with_field(Object(resource_fields))
def get(self, account_id, session):
"""
Get account.
"""
kwargs = date_parser.parse_args()
try:
return Account.query(
session, **kwargs
).filter(
Account.id == account_id
).one()
except NoResultFound:
return None, 404
@session_aware
@marshal_with_field(Object(resource_fields))
def delete(self, account_id, session):
# Need to get the object to update it.
account = session.query(Account).get(account_id)
if not account:
return None, 404
session.delete(account)
return None, 204
@session_aware
@marshal_with_field(Object(resource_fields))
def post(self, account_id, session):
kwargs = parser.parse_args()
assert (id not in kwargs or kwargs.id is None
or kwargs.id == account_id)
# Need to get the object to update it.
account = session.query(Account).get(account_id)
if not account:
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 with solds.
return Account.query(
session
).filter(
Account.id == account_id
).one()
api_api.add_resource(AccountListResource, '/accounts')
api_api.add_resource(AccountResource, '/accounts/<int:account_id>')