155 lines
4.1 KiB
Python
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>')
|