diff --git a/ereuse_devicehub/billing/__init__.py b/ereuse_devicehub/billing/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/ereuse_devicehub/billing/templates/billing/home.html b/ereuse_devicehub/billing/templates/billing/home.html
new file mode 100644
index 00000000..a38b5377
--- /dev/null
+++ b/ereuse_devicehub/billing/templates/billing/home.html
@@ -0,0 +1,38 @@
+{% extends "ereuse_devicehub/base_site.html" %}
+{% block main %}
+
+
+
Billing
+
+
+
+
+ Current usage
+
+
+
+
+ | Year |
+ Month |
+ Snapshot (register) |
+ Snapshot (update) |
+ Drives Erasure (uniques) |
+
+
+
+
+ | {{ current_month_usage.year }} |
+ {{ current_month_usage.month }} |
+ {{ current_month_usage.snapshot_register }} |
+ {{ current_month_usage.snapshot_update }} |
+ {{ current_month_usage.drives_erasure }} |
+
+
+
+
+
+{% endblock main %}
diff --git a/ereuse_devicehub/billing/views.py b/ereuse_devicehub/billing/views.py
new file mode 100644
index 00000000..a3781466
--- /dev/null
+++ b/ereuse_devicehub/billing/views.py
@@ -0,0 +1,60 @@
+import logging
+
+import flask
+from flask import Blueprint
+from flask.views import View
+from flask_login import current_user, login_required
+from sqlalchemy.sql import extract
+
+from ereuse_devicehub import __version__
+from ereuse_devicehub.resources.action.models import Snapshot
+
+billing = Blueprint(
+ "billing", __name__, url_prefix="/billing", template_folder="templates"
+)
+
+logger = logging.getLogger(__name__)
+
+
+class BillingIndexView(View):
+ methods = ["GET"]
+ decorators = [login_required]
+ template_name = "billing/home.html"
+
+ def dispatch_request(self):
+ # TODO (@slamora): replace hardcoded and get current time
+ # https://dateutil.readthedocs.io/en/stable/_modules/dateutil/tz/tz.html?highlight=now()
+ # datetime.now(tzutc())
+ year = 2022
+ month = 9
+ snapshot_register, snapshot_update = self.count_snapshot(year, month)
+
+ current_month_usage = {
+ "year": year,
+ "month": month,
+ "snapshot_register": snapshot_register,
+ "snapshot_update": snapshot_update,
+ # TODO (@slamora): data erasure count
+ }
+ context = {
+ "current_month_usage": current_month_usage,
+ "page_title": "Billing",
+ "version": __version__,
+ }
+ return flask.render_template(self.template_name, **context)
+
+ def count_snapshot(self, year, month):
+ query = Snapshot.query.filter(
+ Snapshot.author_id == current_user.id,
+ extract('year', Snapshot.created) == year,
+ extract('month', Snapshot.created) == month,
+ )
+
+ all = query.count()
+ register = query.distinct(Snapshot.device_id).count()
+ update = all - register
+
+ return (register, update)
+
+
+billing.add_url_rule("/", view_func=BillingIndexView.as_view("billing_index"))
diff --git a/examples/app.py b/examples/app.py
index 623bfaef..5ef2b956 100644
--- a/examples/app.py
+++ b/examples/app.py
@@ -7,6 +7,7 @@
from decouple import config
from ereuse_devicehub.api.views import api
+from ereuse_devicehub.billing.views import billing
from ereuse_devicehub.config import DevicehubConfig
from ereuse_devicehub.devicehub import Devicehub
from ereuse_devicehub.inventory.views import devices
@@ -43,6 +44,7 @@
app.register_blueprint(labels)
app.register_blueprint(api)
app.register_blueprint(workbench)
+app.register_blueprint(billing)
# configure & enable CSRF of Flask-WTF
# NOTE: enable by blueprint to exclude API views