diff --git a/accountant/views/accounts.py b/accountant/views/accounts.py
index a855e4f..efe1225 100644
--- a/accountant/views/accounts.py
+++ b/accountant/views/accounts.py
@@ -14,6 +14,8 @@
You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see .
"""
+import dateutil.parser
+
from flask_restplus import Resource, fields, marshal_with_field
from accountant import db
@@ -25,14 +27,113 @@ from ..models.operations import Operation
from ..fields import Object
-from .models import (account_model, solds_model, balance_model,
- category_model, ohlc_model)
-from .parsers import range_parser
from .users import requires_auth
ns = api.namespace('account', description='Account management')
+# Account model.
+account_model = ns.model('Account', {
+ 'id': fields.Integer(
+ default=None,
+ readonly=True,
+ description='Id of the account'),
+ 'name': fields.String(
+ required=True,
+ description='Name of the account'),
+ 'authorized_overdraft': fields.Float(
+ required=True,
+ description='Authorized overdraft')
+})
+
+# Account status model.
+solds_model = ns.model('Solds', {
+ 'current': fields.Float(
+ readonly=True,
+ description='Current sold of the account'),
+ 'pointed': fields.Float(
+ readonly=True,
+ description='Pointed sold of the account'),
+ 'future': fields.Float(
+ readonly=True,
+ description='Future sold of the account')
+})
+
+# Account balance model.
+balance_model = ns.model('Balance', {
+ 'expenses': fields.Float(
+ readonly=True,
+ description='Total amount of expenses'),
+ 'revenues': fields.Float(
+ readonly=True,
+ description='Total amount of revenues'),
+ 'balance': fields.Float(
+ readonly=True,
+ description='Balance'),
+})
+
+# Category with expenses and revenues.
+category_model = ns.model('Category', {
+ 'category': fields.String(
+ readonly=True,
+ description='Category name'),
+ 'expenses': fields.Float(
+ readonly=True,
+ description='Total amount of expenses for the category'),
+ 'revenues': fields.Float(
+ readonly=True,
+ description='Total amount of revenues for the category')
+})
+
+# OHLC model.
+ohlc_model = ns.model('OHLC', {
+ 'operation_date': fields.DateTime(
+ dt_format='iso8601',
+ readonly=True,
+ required=True,
+ description='Date of the OHLC object'
+ ),
+ 'open': fields.Float(
+ readonly=True,
+ required=True,
+ description='Open value'
+ ),
+ 'high': fields.Float(
+ readonly=True,
+ required=True,
+ description='High value'
+ ),
+ 'low': fields.Float(
+ readonly=True,
+ required=True,
+ description='Low value'
+ ),
+ 'close': fields.Float(
+ readonly=True,
+ required=True,
+ description='Close value'
+ )
+})
+
+# Parser for a date range.
+range_parser = ns.parser()
+range_parser.add_argument(
+ 'begin',
+ type=lambda a: dateutil.parser.parse(a) if a else None,
+ required=False,
+ default=None,
+ location='args',
+ help='Begin date of the time period'
+)
+range_parser.add_argument(
+ 'end',
+ type=lambda a: dateutil.parser.parse(a) if a else None,
+ required=False,
+ default=None,
+ location='args',
+ help='End date of the time period'
+)
+
@ns.route('/')
@api.doc(
diff --git a/accountant/views/models.py b/accountant/views/models.py
deleted file mode 100644
index 7ceed60..0000000
--- a/accountant/views/models.py
+++ /dev/null
@@ -1,230 +0,0 @@
-"""
- 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 .
-"""
-from flask_restplus import fields
-
-from .. import api
-
-# Account model.
-account_model = api.model('Account', {
- 'id': fields.Integer(
- default=None,
- readonly=True,
- description='Id of the account'),
- 'name': fields.String(
- required=True,
- description='Name of the account'),
- 'authorized_overdraft': fields.Float(
- required=True,
- description='Authorized overdraft')
-})
-
-# Account status model.
-solds_model = api.model('Solds', {
- 'current': fields.Float(
- readonly=True,
- description='Current sold of the account'),
- 'pointed': fields.Float(
- readonly=True,
- description='Pointed sold of the account'),
- 'future': fields.Float(
- readonly=True,
- description='Future sold of the account')
-})
-
-# Account balance model.
-balance_model = api.model('Balance', {
- 'expenses': fields.Float(
- readonly=True,
- description='Total amount of expenses'),
- 'revenues': fields.Float(
- readonly=True,
- description='Total amount of revenues'),
- 'balance': fields.Float(
- readonly=True,
- description='Balance'),
-})
-
-# Category with expenses and revenues.
-category_model = api.model('Category', {
- 'category': fields.String(
- readonly=True,
- description='Category name'),
- 'expenses': fields.Float(
- readonly=True,
- description='Total amount of expenses for the category'),
- 'revenues': fields.Float(
- readonly=True,
- description='Total amount of revenues for the category')
-})
-
-# OHLC model.
-ohlc_model = api.model('OHLC', {
- 'operation_date': fields.DateTime(
- dt_format='iso8601',
- readonly=True,
- required=True,
- description='Date of the OHLC object'
- ),
- 'open': fields.Float(
- readonly=True,
- required=True,
- description='Open value'
- ),
- 'high': fields.Float(
- readonly=True,
- required=True,
- description='High value'
- ),
- 'low': fields.Float(
- readonly=True,
- required=True,
- description='Low value'
- ),
- 'close': fields.Float(
- readonly=True,
- required=True,
- description='Close value'
- )
-})
-
-# Operation with sold model.
-operation_model = api.model('Operation', {
- 'id': fields.Integer(
- default=None,
- readonly=True,
- description='Id of the operation'),
- 'operation_date': fields.DateTime(
- dt_format='iso8601',
- required=True,
- description='Date of the operation'),
- 'label': fields.String(
- required=True,
- description='Label of the operation'),
- 'value': fields.Float(
- required=True,
- description='Value of the operation'),
- 'pointed': fields.Boolean(
- required=True,
- description='Pointed status of the operation'),
- 'category': fields.String(
- required=False,
- default=None,
- description='Category of the operation'),
- 'account_id': fields.Integer(
- required=True,
- readonly=True,
- description='Account id of the operation'),
- 'scheduled_operation_id': fields.Integer(
- default=None,
- readonly=True,
- description='Scheduled operation ID of the operation'),
- 'confirmed': fields.Boolean(
- description='Confirmed status of the operation'),
- 'canceled': fields.Boolean(
- description='Canceled status of the operation (for a scheduled one)')
-})
-
-operation_with_sold_model = api.clone(
- 'OperationWithSold', operation_model, {
- 'sold': fields.Float(
- readonly=True,
- description='Cumulated sold'
- ),
- }
-)
-
-# Scheduled operation model.
-scheduled_operation_model = api.model('ScheduledOperation', {
- 'id': fields.Integer(
- description='Id of the scheduled operation',
- readonly=True,
- default=None),
- 'start_date': fields.DateTime(
- dt_format='iso8601',
- required=True,
- description='Start date of the scheduled operation'),
- 'stop_date': fields.DateTime(
- dt_format='iso8601',
- required=True,
- description='End date of the scheduled operation'),
- 'day': fields.Integer(
- required=True,
- description='Day of month for the scheduled operation'),
- 'frequency': fields.Integer(
- required=True,
- description='Frequency of the scheduling in months'),
- 'label': fields.String(
- required=True,
- description='Label of the generated operations'),
- 'value': fields.Float(
- required=True,
- description='Value of the generated operations'),
- 'category': fields.String(
- required=False,
- description='Category of the generated operations'),
- 'account_id': fields.Integer(
- default=None,
- readonly=True,
- required=True,
- description='Account id of the scheduled operation'),
-})
-
-# Token with expiration time and type.
-token_model = api.model('Token', {
- 'token': fields.String(
- required=True,
- readonly=True,
- description='Token value'),
- 'expiration': fields.DateTime(
- dt_format='iso8601',
- required=True,
- readonly=True,
- description='Expiration time of the token'),
- 'token_type': fields.String(
- required=True,
- readonly=True,
- description='Token type')
-})
-
-# User model.
-user_model = api.model('User', {
- 'id': fields.Integer(
- default=None,
- required=True,
- readonly=True,
- description='Id of the user'),
- 'email': fields.String(
- required=True,
- readonly=True,
- decription='Email address of the user'),
- 'active': fields.Boolean(
- required=True,
- readonly=True,
- description='Active state of the user')
-})
-
-# Login model.
-login_model = api.model('Login', {
- 'email': fields.String(
- required=True,
- description='Email to use for login'
- ),
- 'password': fields.String(
- required=True,
- description='Plain text password to use for login'
- )
-})
diff --git a/accountant/views/operations.py b/accountant/views/operations.py
index 9a82aff..87c95c3 100644
--- a/accountant/views/operations.py
+++ b/accountant/views/operations.py
@@ -14,6 +14,8 @@
You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see .
"""
+import dateutil.parser
+
from flask_restplus import Resource, fields, marshal_with_field
from accountant import db
@@ -23,8 +25,6 @@ from .. import api
from ..models.accounts import Account
from ..models.operations import Operation
-from .models import operation_model, operation_with_sold_model
-from .parsers import account_range_parser
from .users import requires_auth
from ..fields import Object
@@ -32,6 +32,78 @@ from ..fields import Object
ns = api.namespace('operation', description='Operation management')
+# Operation with sold model.
+operation_model = ns.model('Operation', {
+ 'id': fields.Integer(
+ default=None,
+ readonly=True,
+ description='Id of the operation'),
+ 'operation_date': fields.DateTime(
+ dt_format='iso8601',
+ required=True,
+ description='Date of the operation'),
+ 'label': fields.String(
+ required=True,
+ description='Label of the operation'),
+ 'value': fields.Float(
+ required=True,
+ description='Value of the operation'),
+ 'pointed': fields.Boolean(
+ required=True,
+ description='Pointed status of the operation'),
+ 'category': fields.String(
+ required=False,
+ default=None,
+ description='Category of the operation'),
+ 'account_id': fields.Integer(
+ required=True,
+ readonly=True,
+ description='Account id of the operation'),
+ 'scheduled_operation_id': fields.Integer(
+ default=None,
+ readonly=True,
+ description='Scheduled operation ID of the operation'),
+ 'confirmed': fields.Boolean(
+ description='Confirmed status of the operation'),
+ 'canceled': fields.Boolean(
+ description='Canceled status of the operation (for a scheduled one)')
+})
+
+operation_with_sold_model = ns.clone(
+ 'OperationWithSold', operation_model, {
+ 'sold': fields.Float(
+ readonly=True,
+ description='Cumulated sold'
+ ),
+ }
+)
+
+# Parser for a date range and an account id.
+account_range_parser = ns.parser()
+account_range_parser.add_argument(
+ 'begin',
+ type=lambda a: dateutil.parser.parse(a) if a else None,
+ required=False,
+ default=None,
+ location='args',
+ help='Begin date of the time period'
+)
+account_range_parser.add_argument(
+ 'end',
+ type=lambda a: dateutil.parser.parse(a) if a else None,
+ required=False,
+ default=None,
+ location='args',
+ help='End date of the time period'
+)
+account_range_parser.add_argument(
+ 'account_id',
+ type=int,
+ required=True,
+ location='args',
+ help='Id of the account'
+)
+
@ns.route('/')
@api.doc(
diff --git a/accountant/views/parsers.py b/accountant/views/parsers.py
deleted file mode 100644
index 1c6e929..0000000
--- a/accountant/views/parsers.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""
- 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 .
-"""
-import dateutil.parser
-
-from flask_restplus import reqparse
-
-from .. import api
-
-# Parser for a date range.
-range_parser = api.parser()
-range_parser.add_argument(
- 'begin',
- type=lambda a: dateutil.parser.parse(a) if a else None,
- required=False,
- default=None,
- location='args',
- help='Begin date of the time period'
-)
-range_parser.add_argument(
- 'end',
- type=lambda a: dateutil.parser.parse(a) if a else None,
- required=False,
- default=None,
- location='args',
- help='End date of the time period'
-)
-
-# Parser for an account id.
-account_id_parser = reqparse.RequestParser()
-account_id_parser.add_argument(
- 'account_id',
- type=int,
- required=True,
- location='args',
- help='Id of the account'
-)
-
-# Parser for a date range and an account id.
-account_range_parser = range_parser.copy()
-account_range_parser.add_argument(
- 'account_id',
- type=int,
- required=True,
- location='args',
- help='Id of the account'
-)
diff --git a/accountant/views/scheduled_operations.py b/accountant/views/scheduled_operations.py
index 217fb64..a6fd85d 100644
--- a/accountant/views/scheduled_operations.py
+++ b/accountant/views/scheduled_operations.py
@@ -26,8 +26,6 @@ from ..models.accounts import Account
from ..models.operations import Operation
from ..models.scheduled_operations import ScheduledOperation
-from .models import scheduled_operation_model
-from .parsers import account_id_parser
from .users import requires_auth
from ..fields import Object
@@ -38,6 +36,52 @@ ns = api.namespace(
description='Scheduled operation management'
)
+# Scheduled operation model.
+scheduled_operation_model = ns.model('ScheduledOperation', {
+ 'id': fields.Integer(
+ description='Id of the scheduled operation',
+ readonly=True,
+ default=None),
+ 'start_date': fields.DateTime(
+ dt_format='iso8601',
+ required=True,
+ description='Start date of the scheduled operation'),
+ 'stop_date': fields.DateTime(
+ dt_format='iso8601',
+ required=True,
+ description='End date of the scheduled operation'),
+ 'day': fields.Integer(
+ required=True,
+ description='Day of month for the scheduled operation'),
+ 'frequency': fields.Integer(
+ required=True,
+ description='Frequency of the scheduling in months'),
+ 'label': fields.String(
+ required=True,
+ description='Label of the generated operations'),
+ 'value': fields.Float(
+ required=True,
+ description='Value of the generated operations'),
+ 'category': fields.String(
+ required=False,
+ description='Category of the generated operations'),
+ 'account_id': fields.Integer(
+ default=None,
+ readonly=True,
+ required=True,
+ description='Account id of the scheduled operation'),
+})
+
+# Parser for an account id.
+account_id_parser = ns.parser()
+account_id_parser.add_argument(
+ 'account_id',
+ type=int,
+ required=True,
+ location='args',
+ help='Id of the account'
+)
+
@ns.route('/')
@api.doc(
diff --git a/accountant/views/users.py b/accountant/views/users.py
index da4caef..adb140b 100644
--- a/accountant/views/users.py
+++ b/accountant/views/users.py
@@ -22,7 +22,7 @@ import arrow
from functools import wraps
from flask import request, g
-from flask_restplus import Resource, marshal_with_field
+from flask_restplus import Resource, fields, marshal_with_field
from .. import app, api
@@ -85,6 +85,52 @@ def requires_auth(f):
ns = api.namespace('user', description='User management')
+# Token with expiration time and type.
+token_model = ns.model('Token', {
+ 'token': fields.String(
+ required=True,
+ readonly=True,
+ description='Token value'),
+ 'expiration': fields.DateTime(
+ dt_format='iso8601',
+ required=True,
+ readonly=True,
+ description='Expiration time of the token'),
+ 'token_type': fields.String(
+ required=True,
+ readonly=True,
+ description='Token type')
+})
+
+# User model.
+user_model = ns.model('User', {
+ 'id': fields.Integer(
+ default=None,
+ required=True,
+ readonly=True,
+ description='Id of the user'),
+ 'email': fields.String(
+ required=True,
+ readonly=True,
+ decription='Email address of the user'),
+ 'active': fields.Boolean(
+ required=True,
+ readonly=True,
+ description='Active state of the user')
+})
+
+# Login model.
+login_model = ns.model('Login', {
+ 'email': fields.String(
+ required=True,
+ description='Email to use for login'
+ ),
+ 'password': fields.String(
+ required=True,
+ description='Plain text password to use for login'
+ )
+})
+
@ns.route('/login')
class LoginResource(Resource):