diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py b/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py
index c9fa97f..4419bf1 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py
@@ -12,3 +12,4 @@ from .training_plan import TrainingPlanAdmin, TrainingPlanDetailAdmin
from .faq import FaqAdmin
from .split_tests import SplitTestAdmin
from .training_plan_day import TrainingPlanDayAdmin
+from .controlling import ControllingAdmin
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html b/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html
index ce0328d..176e0d8 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html
@@ -1,6 +1,9 @@
{% extends "admin/base_site.html" %}
-
{% block extrahead %}
{{ block.super }}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
+
+{% block content %}
+
Controlling
+{% endblock %}
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py b/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py
new file mode 100644
index 0000000..c5b30c9
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py
@@ -0,0 +1,29 @@
+from django.contrib import admin
+from django.db import models
+from django.urls import path
+from django.http import HttpResponse
+
+
+class Controlling(models.Model):
+ class Meta:
+ verbose_name_plural = 'Controlling'
+ app_label = 'aitrainer_backoffice'
+
+
+def my_custom_view(request):
+ return HttpResponse('Admin Custom View')
+
+
+class ControllingAdmin(admin.ModelAdmin):
+ model = Controlling
+
+ def get_urls(self):
+ view_name = '{}_{}_changelist'.format(
+ self.model._meta.app_label, self.model._meta.model_name)
+ return [
+ path('my_admin_path/', my_custom_view, name=view_name),
+ ]
+
+
+admin.site.register(Controlling, ControllingAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/aitrainer_backoffice/db_router.py b/aitrainer_backoffice/aitrainer_backoffice/db_router.py
new file mode 100644
index 0000000..28dc4d8
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/db_router.py
@@ -0,0 +1,22 @@
+class TestRouter:
+ """
+ A router to control all database operations on models
+ """
+ live_app_labels = {'controlling'}
+
+ def db_for_read(self, model, **hints):
+ if model._meta.app_label == 'controlling':
+ return 'live'
+ else:
+ return 'default'
+
+ def db_for_write(self, model, **hints):
+ if model._meta.app_label == 'controlling':
+ raise Exception("This table cannot be changed!")
+ return 'default'
+
+ def allow_relation(self, obj1, obj2, **hints):
+ return True
+
+ def allow_migrate(self, db, app_label, model_name=None, **hints):
+ return False
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py b/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py
index 963112a..32b3136 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py
@@ -15,3 +15,4 @@ from .training_plan import TrainingPlan, TrainingPlanDetail
from .faq import Faq, FaqTranslation
from .split_tests import SplitTests
from .training_plan_day import TrainingPlanDay, TrainingPlanDayTranslation
+from .controlling import Controlling
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/controlling.py b/aitrainer_backoffice/aitrainer_backoffice/models/controlling.py
new file mode 100644
index 0000000..decaa99
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/controlling.py
@@ -0,0 +1,9 @@
+from django.db import models
+
+
+class Controlling(models.Model):
+ sort = models.IntegerField(blank=True)
+
+ class Meta:
+ verbose_name_plural = 'Controlling'
+ app_label = 'controlling'
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/multi_db.py b/aitrainer_backoffice/aitrainer_backoffice/models/multi_db.py
new file mode 100644
index 0000000..16b14b7
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/multi_db.py
@@ -0,0 +1,28 @@
+from django.contrib import admin
+
+
+class MultiDBModelAdmin(admin.ModelAdmin):
+ # A handy constant for the name of the alternate database.
+ using = 'default'
+
+ def save_model(self, request, obj, form, change):
+ # Tell Django to save objects to the 'other' database.
+ obj.save(using=self.using)
+
+ def delete_model(self, request, obj):
+ # Tell Django to delete objects from the 'other' database
+ obj.delete(using=self.using)
+
+ def get_queryset(self, request):
+ # Tell Django to look for objects on the 'other' database.
+ return super().get_queryset(request).using(self.using)
+
+ def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ # Tell Django to populate ForeignKey widgets using a query
+ # on the 'other' database.
+ return super().formfield_for_foreignkey(db_field, request, using=self.using, **kwargs)
+
+ def formfield_for_manytomany(self, db_field, request, **kwargs):
+ # Tell Django to populate ManyToMany widgets using a query
+ # on the 'other' database.
+ return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs)
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py b/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py
index 4e64134..2c69017 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py
+++ b/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py
@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
import os
-BACKOFFICE_VERSION = 1.22
+BACKOFFICE_VERSION = 1.23
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -38,6 +38,7 @@ ALLOWED_HOSTS = ['localhost']
INSTALLED_APPS = [
'aitrainer_backoffice',
+ 'controlling.apps.ControllingConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -47,6 +48,8 @@ INSTALLED_APPS = [
'ckeditor',
'ckeditor_uploader',
'django_admin_json_editor',
+ 'rangefilter',
+ 'django_crontab'
]
MIDDLEWARE = [
@@ -93,7 +96,7 @@ DATABASES = {
},
'live': {
'ENGINE': 'django.db.backends.mysql',
- 'NAME': 'aitrainer2',
+ 'NAME': 'aitrainer',
'USER': 'aitrainer',
'PASSWORD': 'andio2009',
'HOST': '127.0.0.1',
@@ -101,6 +104,8 @@ DATABASES = {
}
}
+DATABASE_ROUTERS = ['aitrainer_backoffice.db_router.TestRouter']
+
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
@@ -166,3 +171,7 @@ LOGGING = {
},
},
}
+
+CRONJOBS = [
+ ('4 */1 * * *', 'controlling.cron.sync_customers')
+]
diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py
index 00d60ea..f7b49f9 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py
+++ b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py
@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
import os
-BACKOFFICE_VERSION = 1.22
+BACKOFFICE_VERSION = 1.23
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -34,6 +34,7 @@ ALLOWED_HOSTS = ['62.171.188.119', 'localhost', 'andio.eu', 'aitrainer.info','ai
INSTALLED_APPS = [
'aitrainer_backoffice.aitrainer_backoffice',
+ 'controlling.apps.ControllingConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -43,6 +44,8 @@ INSTALLED_APPS = [
'ckeditor',
'ckeditor_uploader',
'django_admin_json_editor',
+ 'rangefilter',
+ 'django_crontab'
]
MIDDLEWARE = [
@@ -89,6 +92,8 @@ DATABASES = {
}
}
+DATABASE_ROUTERS = ['aitrainer_backoffice.db_router.TestRouter']
+
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
@@ -170,3 +175,7 @@ CACHES = {
}
}
+CRONJOBS = [
+ ('4 */1 * * *', 'controlling.cron.sync_customers')
+]
+
diff --git a/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html b/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html
new file mode 100644
index 0000000..4a7e824
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html
@@ -0,0 +1,12 @@
+{% extends 'admin/change_list.html' %}
+
+{% block object-tools %}
+
+
+
+
+ {{ block.super }}
+{% endblock %}
\ No newline at end of file
diff --git a/aitrainer_backoffice/controlling/__init__.py b/aitrainer_backoffice/controlling/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/aitrainer_backoffice/controlling/admin/__init__.py b/aitrainer_backoffice/controlling/admin/__init__.py
new file mode 100644
index 0000000..18b00eb
--- /dev/null
+++ b/aitrainer_backoffice/controlling/admin/__init__.py
@@ -0,0 +1,3 @@
+from .customer import CustomerAdmin
+from .frequent_customers import FrequentCustomersAdmin
+from .frequent_exercises import FrequentExerciseTypeAdmin
diff --git a/aitrainer_backoffice/controlling/admin/customer.py b/aitrainer_backoffice/controlling/admin/customer.py
new file mode 100644
index 0000000..992165e
--- /dev/null
+++ b/aitrainer_backoffice/controlling/admin/customer.py
@@ -0,0 +1,83 @@
+from abc import ABC
+from datetime import datetime
+
+from django.contrib.admin import SimpleListFilter
+from django.http import HttpResponseRedirect
+from django.utils.translation import ugettext_lazy as _
+from django.contrib import admin
+from rangefilter.filters import DateRangeFilter, DateTimeRangeFilter
+from django.urls import path
+
+from ..models.customer import Customer
+from ..models.customer import Sport
+from ..mautic import MauticHelper
+from ..cron import cron
+
+
+class SportFilter(SimpleListFilter, ABC):
+ title = "Sport"
+ parameter_name = 'sport_id'
+
+ def lookups(self, request, model_admin):
+ data = []
+ for s in Sport.objects.filter():
+ data.append([s.sport_id, s.sport_name])
+ return data
+
+ def queryset(self, request, queryset):
+ if self.value():
+ return Customer.objects.filter(sport__sport_id=self.value())
+ else:
+ return queryset
+
+
+class CustomerAdmin(admin.ModelAdmin):
+ change_list_template = "controlling/mautic.html"
+ list_display = ('customer_id', 'name','firstname', 'email', 'date_add', 'get_sport')
+ list_filter = (
+ ('date_add', DateRangeFilter),
+ SportFilter
+ )
+
+ def get_sport(self, obj):
+ return obj.sport.sport_name
+
+ get_sport.short_description = 'Sport'
+ get_sport.admin_order_field = 'sport__sport_name'
+
+
+ # If you would like to add a default range filter
+ # method pattern "get_rangefilter_{field_name}_default"
+ def get_rangefilter_date_add_default(self, request):
+ return (datetime.today(), datetime.today())
+
+ # If you would like to change a title range filter
+ # method pattern "get_rangefilter_{field_name}_title"
+ def get_rangefilter_date_add_title(self, request, field_path):
+ return _('Registered')
+
+ def changelist_view(self, request, extra_context=None):
+ if not request.GET.__contains__('date_add__range__gte'):
+ q = request.GET.copy()
+ q['date_add__range__gte'] = datetime.today()
+ q['date_add__range__lte'] = datetime.today()
+ request.GET = q
+ request.META['QUERY_STRING'] = request.GET.urlencode()
+ return super(CustomerAdmin, self).changelist_view(
+ request, extra_context=extra_context)
+
+ def get_urls(self):
+ urls = super().get_urls()
+ my_urls = [
+ path('mautic/', self.set_mautic),
+ ]
+ return my_urls + urls
+
+ def set_mautic(self, request):
+ cron.sync_customers()
+ self.message_user(request, "All heroes are now synced")
+ return HttpResponseRedirect("../")
+
+
+admin.site.register(Customer, CustomerAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/controlling/admin/frequent_customers.py b/aitrainer_backoffice/controlling/admin/frequent_customers.py
new file mode 100644
index 0000000..51e7e60
--- /dev/null
+++ b/aitrainer_backoffice/controlling/admin/frequent_customers.py
@@ -0,0 +1,24 @@
+from django.contrib import admin
+
+from ..models.frequent_customers import FrequentCustomers
+
+
+
+class FrequentCustomersAdmin(admin.ModelAdmin):
+ list_display = ('customer_id', 'name', 'firstname', 'email', 'exercise_count')
+
+ #def get_queryset(self, request):
+ # qs = super(FrequentCustomersAdmin, self).get_queryset(request)
+ # return FrequentCustomers.objects.extra(
+ # select=["customer_id, name, firstname, email, ( select count(exercise_id) from exercises where exercises.customer_id = customer_customer.id) as exercise_count "],
+ #group_by=["customer_id"],
+ #having=["exercise_count > 10"],
+ # order_by=["-exercise_count"]
+ #)
+ #return qs.values("exercises").annotate(exercise_count=Count('exercises')).order_by('-exercise_count')
+ #return Exercises.objects.annotate(count=Count("customer__customer_id"))
+ #return qs.values('user').annotate(visit_sum=Count('visit_count')).order_by('-visit_sum')
+
+
+admin.site.register(FrequentCustomers, FrequentCustomersAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/controlling/admin/frequent_exercises.py b/aitrainer_backoffice/controlling/admin/frequent_exercises.py
new file mode 100644
index 0000000..67d95bc
--- /dev/null
+++ b/aitrainer_backoffice/controlling/admin/frequent_exercises.py
@@ -0,0 +1,15 @@
+from django.contrib import admin
+
+from ..models import ExerciseType
+
+
+class FrequentExerciseTypeAdmin(admin.ModelAdmin):
+ list_display = ('exercise_type_id', 'name', 'exercise_count')
+
+ def get_queryset(self, request):
+ qs = super(FrequentExerciseTypeAdmin, self).get_queryset(request)
+ return qs.filter(active=True)
+
+
+admin.site.register(ExerciseType, FrequentExerciseTypeAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/controlling/apps.py b/aitrainer_backoffice/controlling/apps.py
new file mode 100644
index 0000000..50e6d1e
--- /dev/null
+++ b/aitrainer_backoffice/controlling/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class ControllingConfig(AppConfig):
+ app_label = 'controlling'
+ name = 'controlling'
diff --git a/aitrainer_backoffice/controlling/cron/__init__.py b/aitrainer_backoffice/controlling/cron/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/aitrainer_backoffice/controlling/cron/cron.py b/aitrainer_backoffice/controlling/cron/cron.py
new file mode 100644
index 0000000..b43f190
--- /dev/null
+++ b/aitrainer_backoffice/controlling/cron/cron.py
@@ -0,0 +1,6 @@
+from ..mautic import MauticHelper
+
+
+def sync_customers():
+ helper = MauticHelper()
+ helper.sync()
\ No newline at end of file
diff --git a/aitrainer_backoffice/controlling/mautic/__init__.py b/aitrainer_backoffice/controlling/mautic/__init__.py
new file mode 100644
index 0000000..4f7a733
--- /dev/null
+++ b/aitrainer_backoffice/controlling/mautic/__init__.py
@@ -0,0 +1 @@
+from .helper import MauticHelper
diff --git a/aitrainer_backoffice/controlling/mautic/helper.py b/aitrainer_backoffice/controlling/mautic/helper.py
new file mode 100644
index 0000000..4230ec0
--- /dev/null
+++ b/aitrainer_backoffice/controlling/mautic/helper.py
@@ -0,0 +1,71 @@
+import requests
+import logging
+from django.db import connections
+
+from ..models.customer import Customer
+
+
+class MauticHelper:
+
+
+ def sync(self):
+ logger = logging.getLogger(__name__)
+ logger.info("Syncronising...")
+
+ last_synced_date = self.get_last_synced_date()
+
+ if len(last_synced_date) != 0:
+ qs = Customer.objects.raw(
+ 'SELECT * from customer WHERE date_add > "' + last_synced_date + '" and synced_date is null')
+ else:
+ qs = Customer.objects.raw(
+ 'SELECT * from customer WHERE synced_date is null')
+
+ headers = {
+ 'content-type': "application/x-www-form-urlencoded",
+ 'cache-control': "no-cache"
+ }
+ index = 0
+ for customer in qs:
+ goal = customer.goal if customer.goal is not None else ""
+ fitness_level = customer.fitness_level if customer.fitness_level is not None else ""
+ data = "mauticform[email]=" + customer.email + \
+ "&mauticform[f_name]=" + customer.name + \
+ "&mauticform[firstname]=" + customer.firstname + \
+ "&mauticform[goal]=" + goal + \
+ "&mauticform[fitness_level]=" + fitness_level + \
+ "&mauticform[subscribed]=" + str(customer.date_add) + \
+ "&mauticform[database_id]=" + str(customer.customer_id) + \
+ "&mauticform[formId]=1" + \
+ "&mauticform[formName]=appsync"
+
+ print(data)
+
+ form_url = 'https://mautic.aitrainer.app/form/submit?formId=1'
+ response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
+ print(str(response.status_code))
+
+ if response.status_code == 200:
+ with connections["live"].cursor() as cursor:
+ cursor.execute("UPDATE customer SET synced_date = NOW() WHERE customer_id="
+ + str(customer.customer_id))
+ #if index == 0:
+ # break
+ index = index + 1
+
+ logger.info("Syncronised customer count: " + str(index))
+
+ return True
+
+ def get_last_synced_date(self):
+ qs = Customer.objects.raw('SELECT customer_id, max(synced_date) as synced_date from customer')
+ for c in qs:
+ if c.synced_date is None:
+ return ""
+ synced_date = c.synced_date.strftime('%Y-%m-%d')
+ print(synced_date)
+ return synced_date
+
+ def sync_frequent_users(self):
+ print("SYNC FREQ USERS")
+ return True
diff --git a/aitrainer_backoffice/controlling/models/__init__.py b/aitrainer_backoffice/controlling/models/__init__.py
new file mode 100644
index 0000000..f681e50
--- /dev/null
+++ b/aitrainer_backoffice/controlling/models/__init__.py
@@ -0,0 +1,4 @@
+from .customer import Customer
+from .exercises import Exercises
+from .exercise_type import ExerciseType
+from .frequent_customers import FrequentCustomers
diff --git a/aitrainer_backoffice/controlling/models/customer.py b/aitrainer_backoffice/controlling/models/customer.py
new file mode 100644
index 0000000..abf5334
--- /dev/null
+++ b/aitrainer_backoffice/controlling/models/customer.py
@@ -0,0 +1,38 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+
+class Sport(models.Model):
+ sport_id = models.AutoField(primary_key = True)
+ language_code = models.CharField(max_length=2,default="hu")
+ sport_name = models.CharField(max_length=100)
+
+ class Meta:
+ db_table = 'sport_translation'
+
+
+class Customer(models.Model):
+ customer_id = models.BigAutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='Last name', verbose_name=_("name"))
+ firstname = models.CharField(max_length=100, help_text='First name', verbose_name=_("firstname"))
+ email = models.CharField(max_length=100)
+ sport = models.ForeignKey(Sport, on_delete=models.CASCADE)
+ goal = models.CharField(max_length=20)
+ fitness_level = models.CharField(max_length=20)
+ date_add = models.DateField()
+ synced_date = models.DateTimeField(blank=True,null=True)
+
+ def has_add_permission(self, request):
+ return False
+
+ def has_delete_permission(self, request, obj=None):
+ return False
+
+ class Meta:
+ db_table = 'customer'
+ verbose_name = _("Customer")
+ verbose_name_plural = _("Customers")
+ app_label = 'controlling'
+
+ def __str__(self):
+ return self.name
diff --git a/aitrainer_backoffice/controlling/models/exercise_type.py b/aitrainer_backoffice/controlling/models/exercise_type.py
new file mode 100644
index 0000000..2958a32
--- /dev/null
+++ b/aitrainer_backoffice/controlling/models/exercise_type.py
@@ -0,0 +1,28 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from ..models.exercises import Exercises
+
+
+class ExerciseType(models.Model):
+ exercise_type_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=50)
+ active = models.BooleanField()
+
+
+ def has_add_permission(self, request):
+ return False
+
+ def has_delete_permission(self, request, obj=None):
+ return False
+
+ @property
+ def exercise_count(self):
+ count = Exercises.objects.filter(exercise_type_id=self.exercise_type_id).count()
+ return count
+
+ class Meta:
+ db_table = 'exercise_type'
+ verbose_name = _("Frequent Exercise")
+ verbose_name_plural = _("Frequent Exercises")
+
diff --git a/aitrainer_backoffice/controlling/models/exercises.py b/aitrainer_backoffice/controlling/models/exercises.py
new file mode 100644
index 0000000..495ac04
--- /dev/null
+++ b/aitrainer_backoffice/controlling/models/exercises.py
@@ -0,0 +1,25 @@
+from django.db import models
+
+#from ..models.exercise_type import ExerciseType
+from ..models.customer import Customer
+
+
+class Exercises(models.Model):
+ exercise_id = models.BigAutoField(primary_key=True)
+ customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
+ exercise_type_id = models.IntegerField()
+ #exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ date_add = models.DateField()
+ quantity = models.DecimalField(decimal_places=0, max_digits=6)
+ unit = models.CharField(max_length=20)
+ unit_quantity = models.DecimalField(decimal_places=0, max_digits=6,blank=True, null=True)
+
+
+ def has_add_permission(self, request):
+ return False
+
+ def has_delete_permission(self, request, obj=None):
+ return False
+
+ class Meta:
+ db_table = 'exercises'
diff --git a/aitrainer_backoffice/controlling/models/frequent_customers.py b/aitrainer_backoffice/controlling/models/frequent_customers.py
new file mode 100644
index 0000000..0bdf9cc
--- /dev/null
+++ b/aitrainer_backoffice/controlling/models/frequent_customers.py
@@ -0,0 +1,32 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from .exercises import Exercises
+
+
+class FrequentCustomers(models.Model):
+ customer_id = models.BigAutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='Last name', verbose_name=_("name"))
+ firstname = models.CharField(max_length=100, help_text='First name', verbose_name=_("firstname"))
+ email = models.CharField(max_length=100)
+ date_add = models.DateField()
+ #exercises = models.ManyToManyField(Exercises)
+
+ #def exercises(self):
+ # exercises = Exercises.objects.filter(customer__customer_id=self.customer_id)
+ # return exercises
+
+ @property
+ def exercise_count(self):
+ count = Exercises.objects.filter(customer__customer_id=self.customer_id).count()
+ return count
+
+ class Meta:
+ db_table = 'customer'
+ verbose_name = _("Frequent Customer")
+ verbose_name_plural = _("Frequent Customers")
+ #ordering = ['exercise_count']
+ #filter(exercise_count__gt=10)
+
+ def __str__(self):
+ return self.name
diff --git a/aitrainer_backoffice/controlling/views.py b/aitrainer_backoffice/controlling/views.py
new file mode 100644
index 0000000..e69de29