diff --git a/README.md b/README.md
index 272f87f..cbc73b9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,3 @@
-# aitrainer_backoffice
+# WorkoutTest
Backoffice Functions
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin.py b/aitrainer_backoffice/aitrainer_backoffice/admin.py
deleted file mode 100644
index 7ccdedc..0000000
--- a/aitrainer_backoffice/aitrainer_backoffice/admin.py
+++ /dev/null
@@ -1,314 +0,0 @@
-from django.contrib import admin, messages
-from django.utils.html import format_html
-from django.utils.translation import ugettext_lazy as _, ngettext
-# from treenode.admin import TreeNodeModelAdmin
-# from treenode.forms import TreeNodeForm
-
-from .models import ExerciseType, ExerciseTypeAlternative, ExerciseTypeParents
-from .models import Product
-from .models import Evaluation, EvaluationAttribute
-from .models import ExerciseDevice, ExerciseDeviceTranslation, ExerciseTypeDevice, ExerciseDeviceAlternative
-from .models import ExerciseTypeImage
-from .models import ExerciseTypeTranslation
-from .models import ExerciseTreeTranslation
-from .models import ExerciseTree
-from .models import ExerciseTreeParents
-from .models import ExercisePlanTranslation
-from .models import ExercisePlanTemplate, ExercisePlanTemplateTranslation, ExercisePlanTemplateDetail
-
-'''
- ExerciseTree
- ------------
-'''
-
-
-class TranslationTreeInline(admin.TabularInline):
- model = ExerciseTreeTranslation
- fields = ('language_code', 'name', 'description')
- extra = 0
-
-
-class ExerciseTreeParentsInline(admin.TabularInline):
- model = ExerciseTreeParents
- fk_name = 'exercise_tree_child'
- fields = ('exercise_tree_parent',)
- extra = 0
-
-
-'''
-
-
-class ExerciseTreeParentAdmin(TreeNodeModelAdmin):
- treenode_display_mode = TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_ACCORDION
- list_display = ('name',)
-
- # use TreeNodeForm to automatically exclude invalid parent choices
- form = TreeNodeForm
-'''
-
-
-class ExerciseTreeAdmin(admin.ModelAdmin):
- list_display = ('tree_id', 'name_colored', 'active')
- search_fields = ['name']
-
- fields = ["name", 'description', "image_url", "active", "get_image_preview"]
- readonly_fields = ("get_image_preview",)
-
- def get_image_preview(self, obj):
- image_url = '/media/' + str(obj.image_url)
- if obj.pk:
- return format_html('
'
- .format(url=image_url))
-
- get_image_preview.short_description = _("Image Preview")
-
- def name_colored(self, obj):
- if obj.active:
- if obj.image_url != "":
- color_code = '7bc863'
- else:
- color_code = 'f2cdb3'
- else:
- color_code = 'C20000'
- html = '{}˓→'.format(color_code, obj.name)
- return format_html(html)
-
- name_colored.admin_order_field = 'name'
- name_colored.short_description = 'name'
-
- inlines = [
- TranslationTreeInline,
- ExerciseTreeParentsInline
- ]
-
-
-'''
- ExerciseTYPE
- ------------
-'''
-
-
-class ExerciseTypeDeviceInline(admin.StackedInline):
- model = ExerciseTypeDevice
- extra = 0
- fields = ["exercise_type", "exercise_device"]
-
-
-class ImageInline(admin.StackedInline):
- model = ExerciseTypeImage
- extra = 0
- fields = ["name", "url", "type", "get_image_preview"]
- readonly_fields = ("get_image_preview",)
-
- def get_image_preview(self, obj):
- image_url = '/media/' + str(obj.url)
- if obj.pk:
- return format_html('
' \
- .format(url=image_url))
-
- get_image_preview.short_description = _("Image Preview")
-
-
-class TranslationInline(admin.TabularInline):
- model = ExerciseTypeTranslation
- fields = ('language_code', 'name', 'description')
- extra = 0
-
-
-class ExerciseTypeAlternativesInline(admin.TabularInline):
- model = ExerciseTypeAlternative
- fk_name = 'exercise_type_child'
- fields = ('exercise_type_parent',)
- extra = 0
-
-
-class ExerciseTypeParentsInline(admin.TabularInline):
- model = ExerciseTypeParents
- fields = ('exercise_tree',)
- extra = 0
-
-
-class ExerciseTypeAdmin(admin.ModelAdmin):
- list_display = ('exercise_type_id', 'name_colored', 'active', 'base')
- search_fields = ['name', 'exercisetypetranslation__name']
- fields = ('name', 'description', 'unit', 'unit_quantity', 'unit_quantity_unit', 'active', 'base')
-
- def name_colored(self, obj):
- if obj.active:
- if obj.base:
- color_code = '7bc863'
- else:
- color_code = '4178bc'
- else:
- color_code = 'C20000'
- html = '{}˓→'.format(color_code, obj.name)
- return format_html(html)
-
- name_colored.admin_order_field = 'name'
- name_colored.short_description = 'name'
-
- inlines = [
- ImageInline,
- TranslationInline,
- ExerciseTypeDeviceInline,
- ExerciseTypeAlternativesInline,
- ExerciseTypeParentsInline
- ]
- exclude = ('exercise_tree',)
-
-
-'''
- ExercisePlan + Template
- ------------
-'''
-
-
-class TranslationPlanTemplateInline(admin.TabularInline):
- model = ExercisePlanTemplateTranslation
- fields = ('language_code', 'name', 'description')
- extra = 0
-
-
-class TranslationPlanTemplateDetailInline(admin.TabularInline):
- model = ExercisePlanTemplateDetail
- verbose_name = 'name'
- fields = ('exercise_type','sort')
- extra = 0
- ordering = ('sort',)
-
-
-class ExercisePlanTemplateAdmin(admin.ModelAdmin):
- list_display = ('name_colored', 'template_type')
- search_fields = ['name']
-
- def name_colored(self, obj):
- color_code = 'C20000'
- html = '{}˓→'.format(color_code, obj.name)
- return format_html(html)
-
- name_colored.admin_order_field = 'name'
- name_colored.short_description = 'name'
-
- inlines = [
- TranslationPlanTemplateInline,
- TranslationPlanTemplateDetailInline
- ]
-
-
-class ExercisePlanTemplateDetailAdmin(admin.ModelAdmin):
- list_display = ('get_plan', 'get_exercise_type', 'quantity', 'quantity_unit_quantity', 'rest_time',)
- list_editable = ('serie', 'quantity', 'quantity_unit_quantity', 'rest_time')
-
- def get_plan(self, obj):
- return obj.exercise_plan_template.name
-
- def get_exercise_type(self, obj):
- return obj.exercise_type.name
-
-
-class TranslationPlanInline(admin.TabularInline):
- model = ExercisePlanTranslation
- fields = ('language_code', 'name', 'description')
- extra = 0
-
-
-class ExercisePlanAdmin(admin.ModelAdmin):
- list_display = ('name_colored',)
- search_fields = ['name']
-
- def name_colored(self, obj):
- color_code = 'C20000'
- html = '{}˓→'.format(color_code, obj.name)
- return format_html(html)
-
- name_colored.admin_order_field = 'name'
- name_colored.short_description = 'name'
-
- inlines = [
- TranslationPlanInline
- ]
-
-
-'''
-class ExercisePlanDetailAdmin(admin.ModelAdmin):
- list_display = ('get_plan', 'get_exercise_type', 'serie', 'repeats', 'weight_equation',)
- list_editable = ('serie', 'repeats', 'weight_equation',)
-
- # list_editable_link('',)
-
- def get_plan(self, obj):
- return obj.exercise_plan.name
-
- def get_exercise_type(self, obj):
- return obj.exercise_type.name
-'''
-
-
-class ProductAdmin(admin.ModelAdmin):
- list_display = ('product_id', 'name', 'type')
-
-
-class TranslationExerciseDeviceInline(admin.TabularInline):
- model = ExerciseDeviceTranslation
- fields = ('language_code', 'name')
- extra = 0
-
-
-class ExerciseDeviceAlternativesInline(admin.TabularInline):
- model = ExerciseDeviceAlternative
- fk_name = 'exercise_device_child'
- fields = ('exercise_device_parent',)
- extra = 0
-
-
-class ExerciseDeviceAdmin(admin.ModelAdmin):
- list_display = ('name',)
- fields = ('name', 'description', "image_url", "get_image_preview", "sort", "place")
- readonly_fields = ("get_image_preview",)
-
- def get_image_preview(self, obj):
- image_url = '/media/' + str(obj.image_url)
- if obj.pk:
- return format_html('
' \
- .format(url=image_url))
-
- get_image_preview.short_description = _("Image Preview")
-
- inlines = [
- TranslationExerciseDeviceInline,
- ExerciseDeviceAlternativesInline
- ]
-
-
-class EvaluationAdmin(admin.ModelAdmin):
- list_display = ('evaluation_id', 'name', 'get_exercise_type')
-
- def get_exercise_type(self, obj):
- return obj.exercise_type.name
-
-
-class EvaluationAttributeAdmin(admin.ModelAdmin):
- list_display = (
- 'evaluation_attr_id', 'name', 'sex', 'age_min', 'age_max', 'value_min', 'value_max', 'evaluation_text')
- list_editable = ('name', 'sex', 'age_min', 'age_max', 'value_min', 'value_max', 'evaluation_text')
- list_filter = ('evaluation',)
-
- def copy_attributes(self, request, queryset):
- for objectAttr in reversed(queryset):
- objectAttr.pk = None
- objectAttr.name = objectAttr.name + "_copy"
- objectAttr.save()
-
- copy_attributes.short_description = "Clone the selected attribute"
-
- actions = [copy_attributes]
-
-
-admin.site.register(ExerciseType, ExerciseTypeAdmin)
-admin.site.register(ExerciseTree, ExerciseTreeAdmin)
-admin.site.register(ExercisePlanTemplate, ExercisePlanTemplateAdmin)
-admin.site.register(Product, ProductAdmin)
-admin.site.register(ExerciseDevice, ExerciseDeviceAdmin)
-admin.site.register(Evaluation, EvaluationAdmin)
-admin.site.register(EvaluationAttribute, EvaluationAttributeAdmin)
-admin.autodiscover()
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py b/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py
new file mode 100644
index 0000000..c37fb18
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py
@@ -0,0 +1,10 @@
+# init
+from .exercise_type import ExerciseTypeAdmin
+from .exercisetree import ExerciseTreeAdmin
+from .exercise_plan_template import ExercisePlanTemplateAdmin, ExercisePlanTemplateDetailAdmin
+from .product import ProductAdmin
+from .exercise_device import ExerciseDeviceAdmin
+from .tutorial import TutorialAdmin
+from .evaluation import EvaluationAdmin, EvaluationAttributeAdmin
+from .exercise_plan import ExercisePlanAdmin
+
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py b/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py
new file mode 100644
index 0000000..754d978
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py
@@ -0,0 +1,32 @@
+from django.contrib import admin
+
+from ..models.evaluation import EvaluationAttribute, Evaluation
+
+
+class EvaluationAdmin(admin.ModelAdmin):
+ list_display = ('evaluation_id', 'name', 'get_exercise_type')
+
+ def get_exercise_type(self, obj):
+ return obj.exercise_type.name
+
+
+class EvaluationAttributeAdmin(admin.ModelAdmin):
+ list_display = (
+ 'evaluation_attr_id', 'name', 'sex', 'age_min', 'age_max', 'value_min', 'value_max', 'evaluation_text')
+ list_editable = ('name', 'sex', 'age_min', 'age_max', 'value_min', 'value_max', 'evaluation_text')
+ list_filter = ('evaluation',)
+
+ def copy_attributes(self, request, queryset):
+ for objectAttr in reversed(queryset):
+ objectAttr.pk = None
+ objectAttr.name = objectAttr.name + "_copy"
+ objectAttr.save()
+
+ copy_attributes.short_description = "Clone the selected attribute"
+
+ actions = [copy_attributes]
+
+
+admin.site.register(Evaluation, EvaluationAdmin)
+admin.site.register(EvaluationAttribute, EvaluationAttributeAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_device.py b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_device.py
new file mode 100644
index 0000000..357275a
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_device.py
@@ -0,0 +1,41 @@
+from django.contrib import admin
+from django.utils.html import format_html
+from django.utils.translation import ugettext_lazy as _
+
+from ..models.exercise_device import ExerciseDeviceTranslation, ExerciseDeviceAlternative, ExerciseDevice
+
+
+class TranslationExerciseDeviceInline(admin.TabularInline):
+ model = ExerciseDeviceTranslation
+ fields = ('language_code', 'name')
+ extra = 0
+
+
+class ExerciseDeviceAlternativesInline(admin.TabularInline):
+ model = ExerciseDeviceAlternative
+ fk_name = 'exercise_device_child'
+ fields = ('exercise_device_parent',)
+ extra = 0
+
+
+class ExerciseDeviceAdmin(admin.ModelAdmin):
+ list_display = ('name',)
+ fields = ('name', 'description', "image_url", "get_image_preview", "sort", "place")
+ readonly_fields = ("get_image_preview",)
+
+ def get_image_preview(self, obj):
+ image_url = '/media/' + str(obj.image_url)
+ if obj.pk:
+ return format_html('
' \
+ .format(url=image_url))
+
+ get_image_preview.short_description = _("Image Preview")
+
+ inlines = [
+ TranslationExerciseDeviceInline,
+ ExerciseDeviceAlternativesInline
+ ]
+
+
+admin.site.register(ExerciseDevice, ExerciseDeviceAdmin)
+admin.autodiscover()
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan.py b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan.py
new file mode 100644
index 0000000..571aec5
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan.py
@@ -0,0 +1,42 @@
+from django.contrib import admin
+from django.utils.html import format_html
+
+from ..models.exercise_plan import ExercisePlanTranslation
+
+
+class TranslationPlanInline(admin.TabularInline):
+ model = ExercisePlanTranslation
+ fields = ('language_code', 'name', 'description')
+ extra = 0
+
+
+class ExercisePlanAdmin(admin.ModelAdmin):
+ list_display = ('name_colored',)
+ search_fields = ['name']
+
+ def name_colored(self, obj):
+ color_code = 'C20000'
+ html = '{}˓→'.format(color_code, obj.name)
+ return format_html(html)
+
+ name_colored.admin_order_field = 'name'
+ name_colored.short_description = 'name'
+
+ inlines = [
+ TranslationPlanInline
+ ]
+
+
+'''
+class ExercisePlanDetailAdmin(admin.ModelAdmin):
+ list_display = ('get_plan', 'get_exercise_type', 'serie', 'repeats', 'weight_equation',)
+ list_editable = ('serie', 'repeats', 'weight_equation',)
+
+ # list_editable_link('',)
+
+ def get_plan(self, obj):
+ return obj.exercise_plan.name
+
+ def get_exercise_type(self, obj):
+ return obj.exercise_type.name
+'''
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan_template.py b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan_template.py
new file mode 100644
index 0000000..573abc1
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan_template.py
@@ -0,0 +1,51 @@
+from django.contrib import admin
+from django.utils.html import format_html
+
+from ..models.exercise_plan_template import ExercisePlanTemplateTranslation, ExercisePlanTemplateDetail, ExercisePlanTemplate
+
+
+class TranslationPlanTemplateInline(admin.TabularInline):
+ model = ExercisePlanTemplateTranslation
+ fields = ('language_code', 'name', 'description')
+ extra = 0
+
+
+class TranslationPlanTemplateDetailInline(admin.TabularInline):
+ model = ExercisePlanTemplateDetail
+ verbose_name = 'name'
+ fields = ('exercise_type','sort')
+ extra = 0
+ ordering = ('sort',)
+
+
+class ExercisePlanTemplateAdmin(admin.ModelAdmin):
+ list_display = ('name_colored', 'template_type')
+ search_fields = ['name']
+
+ def name_colored(self, obj):
+ color_code = 'C20000'
+ html = '{}˓→'.format(color_code, obj.name)
+ return format_html(html)
+
+ name_colored.admin_order_field = 'name'
+ name_colored.short_description = 'name'
+
+ inlines = [
+ TranslationPlanTemplateInline,
+ TranslationPlanTemplateDetailInline
+ ]
+
+
+class ExercisePlanTemplateDetailAdmin(admin.ModelAdmin):
+ list_display = ('get_plan', 'get_exercise_type', 'quantity', 'quantity_unit_quantity', 'rest_time',)
+ list_editable = ('serie', 'quantity', 'quantity_unit_quantity', 'rest_time')
+
+ def get_plan(self, obj):
+ return obj.exercise_plan_template.name
+
+ def get_exercise_type(self, obj):
+ return obj.exercise_type.name
+
+
+admin.site.register(ExercisePlanTemplate, ExercisePlanTemplateAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py
new file mode 100644
index 0000000..1b32de6
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py
@@ -0,0 +1,79 @@
+from django.contrib import admin
+from django.utils.html import format_html
+from django.utils.translation import ugettext_lazy as _
+
+from ..models.exercise_type import ExerciseType, ExerciseTypeImage, ExerciseTypeTranslation, ExerciseTypeAlternative, \
+ ExerciseTypeParents, ExerciseTypeDevice
+
+
+class ExerciseTypeDeviceInline(admin.StackedInline):
+ model = ExerciseTypeDevice
+ extra = 0
+ fields = ["exercise_type", "exercise_device"]
+
+
+class ImageInline(admin.StackedInline):
+ model = ExerciseTypeImage
+ extra = 0
+ fields = ["name", "url", "type", "get_image_preview"]
+ readonly_fields = ("get_image_preview",)
+
+ def get_image_preview(self, obj):
+ image_url = '/media/' + str(obj.url)
+ if obj.pk:
+ return format_html('
' \
+ .format(url=image_url))
+
+ get_image_preview.short_description = _("Image Preview")
+
+
+class TranslationInline(admin.TabularInline):
+ model = ExerciseTypeTranslation
+ fields = ('language_code', 'name', 'description')
+ extra = 0
+
+
+class ExerciseTypeAlternativesInline(admin.TabularInline):
+ model = ExerciseTypeAlternative
+ fk_name = 'exercise_type_child'
+ fields = ('exercise_type_parent',)
+ extra = 0
+
+
+class ExerciseTypeParentsInline(admin.TabularInline):
+ model = ExerciseTypeParents
+ fields = ('exercise_tree',)
+ extra = 0
+
+
+class ExerciseTypeAdmin(admin.ModelAdmin):
+ list_display = ('exercise_type_id', 'name_colored', 'active', 'base')
+ search_fields = ['name', 'exercisetypetranslation__name']
+ fields = ('name', 'description', 'unit', 'unit_quantity', 'unit_quantity_unit', 'active', 'base')
+
+ def name_colored(self, obj):
+ if obj.active:
+ if obj.base:
+ color_code = '7bc863'
+ else:
+ color_code = '4178bc'
+ else:
+ color_code = 'C20000'
+ html = '{}˓→'.format(color_code, obj.name)
+ return format_html(html)
+
+ name_colored.admin_order_field = 'name'
+ name_colored.short_description = 'name'
+
+ inlines = [
+ ImageInline,
+ TranslationInline,
+ ExerciseTypeDeviceInline,
+ ExerciseTypeAlternativesInline,
+ ExerciseTypeParentsInline
+ ]
+ exclude = ('exercise_tree',)
+
+
+admin.site.register(ExerciseType, ExerciseTypeAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/exercisetree.py b/aitrainer_backoffice/aitrainer_backoffice/admin/exercisetree.py
new file mode 100644
index 0000000..d0b39ba
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/exercisetree.py
@@ -0,0 +1,63 @@
+from django.contrib import admin
+from django.utils.html import format_html
+from django.utils.translation import ugettext_lazy as _
+
+from ..models.exercisetree import ExerciseTree, ExerciseTreeTranslation, \
+ ExerciseTreeParents
+
+'''
+ ExerciseTree
+ ------------
+'''
+
+
+class TranslationTreeInline(admin.TabularInline):
+ model = ExerciseTreeTranslation
+ fields = ('language_code', 'name', 'description')
+ extra = 0
+
+
+class ExerciseTreeParentsInline(admin.TabularInline):
+ model = ExerciseTreeParents
+ fk_name = 'exercise_tree_child'
+ fields = ('exercise_tree_parent',)
+ extra = 0
+
+
+class ExerciseTreeAdmin(admin.ModelAdmin):
+ list_display = ('tree_id', 'name_colored', 'active')
+ search_fields = ['name']
+
+ fields = ["name", 'description', "image_url", "active", "get_image_preview"]
+ readonly_fields = ("get_image_preview",)
+
+ def get_image_preview(self, obj):
+ image_url = '/media/' + str(obj.image_url)
+ if obj.pk:
+ return format_html('
'
+ .format(url=image_url))
+
+ get_image_preview.short_description = _("Image Preview")
+
+ def name_colored(self, obj):
+ if obj.active:
+ if obj.image_url != "":
+ color_code = '7bc863'
+ else:
+ color_code = 'f2cdb3'
+ else:
+ color_code = 'C20000'
+ html = '{}˓→'.format(color_code, obj.name)
+ return format_html(html)
+
+ name_colored.admin_order_field = 'name'
+ name_colored.short_description = 'name'
+
+ inlines = [
+ TranslationTreeInline,
+ ExerciseTreeParentsInline
+ ]
+
+
+admin.site.register(ExerciseTree, ExerciseTreeAdmin)
+admin.autodiscover()
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/product.py b/aitrainer_backoffice/aitrainer_backoffice/admin/product.py
new file mode 100644
index 0000000..5f83c23
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/product.py
@@ -0,0 +1,11 @@
+from django.contrib import admin
+
+from ..models.product import Product
+
+
+class ProductAdmin(admin.ModelAdmin):
+ list_display = ('product_id', 'name', 'type')
+
+
+admin.site.register(Product, ProductAdmin)
+admin.autodiscover()
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py b/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py
new file mode 100644
index 0000000..a8a64c3
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py
@@ -0,0 +1,29 @@
+from django.contrib import admin
+
+from ..models.tutorial import TutorialTranslation, Tutorial, TutorialSteps
+
+
+class TranslationTutorialInline(admin.TabularInline):
+ model = TutorialTranslation
+ fields = ('language_code', 'tutorial_text', 'error_text')
+ extra = 0
+
+
+class TutorialStepsAdmin(admin.ModelAdmin):
+ list_display = ('tutorial', 'step',)
+ list_filter = ('tutorial',)
+ fields = ('tutorial', 'step', "tutorial_text", "error_text", "check_text",)
+
+ inlines = [
+ TranslationTutorialInline,
+ ]
+
+
+class TutorialAdmin(admin.ModelAdmin):
+ list_display = ('name',)
+ fields = ('name',)
+
+
+admin.site.register(Tutorial, TutorialAdmin)
+admin.site.register(TutorialSteps, TutorialStepsAdmin)
+admin.autodiscover()
diff --git a/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.mo b/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.mo
index cfc8bc8..3d7475f 100644
Binary files a/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.mo and b/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.mo differ
diff --git a/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po b/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po
index cf1c008..610aa8b 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po
+++ b/aitrainer_backoffice/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-04-03 14:27+0200\n"
+"POT-Creation-Date: 2021-04-24 11:26+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -18,219 +18,243 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: .\aitrainer_backoffice\admin.py:63 .\aitrainer_backoffice\admin.py:109
-#: .\aitrainer_backoffice\admin.py:275
+#: .\aitrainer_backoffice\admin\exercise_device.py:32
+#: .\aitrainer_backoffice\admin\exercise_type.py:27
+#: .\aitrainer_backoffice\admin\exercisetree.py:40
msgid "Image Preview"
msgstr "Kép előnézet"
-#: .\aitrainer_backoffice\models.py:30 .\aitrainer_backoffice\models.py:211
-msgid "Exercise Device"
-msgstr "Edzés eszköz"
-
-#: .\aitrainer_backoffice\models.py:31 .\aitrainer_backoffice\models.py:212
-msgid "Exercise Devices"
-msgstr "Edzés eszközök"
-
-#: .\aitrainer_backoffice\models.py:46
-msgid "exercise_device_parent"
-msgstr "Gyakorlat Eszköz szülő"
-
-#: .\aitrainer_backoffice\models.py:48
-msgid "exercise_device_child"
-msgstr "Gyakorlat eszköz"
-
-#: .\aitrainer_backoffice\models.py:52
-msgid "Device Alternative"
-msgstr "Eszköz alternatíva"
-
-#: .\aitrainer_backoffice\models.py:53
-msgid "Device Alternatives"
-msgstr "Eszköz alternatívák"
-
-#: .\aitrainer_backoffice\models.py:65 .\aitrainer_backoffice\models.py:106
-#: .\aitrainer_backoffice\models.py:197 .\aitrainer_backoffice\models.py:271
-#: .\aitrainer_backoffice\models.py:317 .\aitrainer_backoffice\models.py:400
-msgid "Translation"
-msgstr "Fordítás"
-
-#: .\aitrainer_backoffice\models.py:66 .\aitrainer_backoffice\models.py:107
-#: .\aitrainer_backoffice\models.py:198 .\aitrainer_backoffice\models.py:272
-#: .\aitrainer_backoffice\models.py:318 .\aitrainer_backoffice\models.py:401
-msgid "Translations"
-msgstr "Fordítások"
-
-#: .\aitrainer_backoffice\models.py:89
-msgid "Exercise Tree"
-msgstr "Gyakorlat Menü"
-
-#: .\aitrainer_backoffice\models.py:90
-msgid "Exercise Tree Items"
-msgstr "Gyakorlat Menü elemek"
-
-#: .\aitrainer_backoffice\models.py:117
-msgid "exercise_tree_parent"
-msgstr "Gyakorlat Menü szülő"
-
-#: .\aitrainer_backoffice\models.py:118
-msgid "Parent menu"
-msgstr "Szülő menüpont"
-
-#: .\aitrainer_backoffice\models.py:123 .\aitrainer_backoffice\models.py:124
-msgid "Menu Tree Representation"
-msgstr ""
-
-#: .\aitrainer_backoffice\models.py:159
-msgid "Exercise"
-msgstr "Gyakorlat"
-
-#: .\aitrainer_backoffice\models.py:160
-msgid "Exercises"
-msgstr "Gyakorlatok"
-
-#: .\aitrainer_backoffice\models.py:181
-msgid "Image"
-msgstr "Kép"
-
-#: .\aitrainer_backoffice\models.py:182
-msgid "Images"
-msgstr "Képek"
-
-#: .\aitrainer_backoffice\models.py:218
-msgid "exercise_type_parent"
-msgstr "Gyakorlat szülő"
-
-#: .\aitrainer_backoffice\models.py:220
-msgid "exercise_type_child"
-msgstr "Aktuális gyakorlat"
-
-#: .\aitrainer_backoffice\models.py:224
-msgid "Exercise Alternative"
-msgstr "Gyakorlat alternatíva"
-
-#: .\aitrainer_backoffice\models.py:225
-msgid "Exercise Alternatives"
-msgstr "Gyakorlat alternatívák"
-
-#: .\aitrainer_backoffice\models.py:236
-msgid "Exercise Parent"
-msgstr "Gyakorlat szülő"
-
-#: .\aitrainer_backoffice\models.py:237
-msgid "Exercise Parents"
-msgstr "Gyakorlat szülők"
-
-#: .\aitrainer_backoffice\models.py:255
-msgid "Exercise Plan Template"
-msgstr "Edzésterv sablon"
-
-#: .\aitrainer_backoffice\models.py:256
-msgid "Exercise Plan Templates"
-msgstr "Edzésterv sablonok"
-
-#: .\aitrainer_backoffice\models.py:289
-msgid "Exercise Plan Template Detail"
-msgstr "Edzésterv sablon gyakorlat"
-
-#: .\aitrainer_backoffice\models.py:290
-msgid "Exercise Plan Template Details"
-msgstr "Edzésterv sablon gyakorlatok"
-
-#: .\aitrainer_backoffice\models.py:301
-msgid "Exercise Plan"
-msgstr "Edzésterv"
-
-#: .\aitrainer_backoffice\models.py:302
-msgid "Exercise Plans"
-msgstr "Edzéstervek"
-
-#: .\aitrainer_backoffice\models.py:334
-msgid "Exercise Plan Detail"
-msgstr "Edzésterv gyakorlat"
-
-#: .\aitrainer_backoffice\models.py:335
-msgid "Exercise Plan Details"
-msgstr "Edzésterv gyakorlatok"
-
-#: .\aitrainer_backoffice\models.py:357
-msgid "Product"
-msgstr "Termék"
-
-#: .\aitrainer_backoffice\models.py:358
-msgid "Products"
-msgstr "Termékek"
-
-#: .\aitrainer_backoffice\models.py:374
-msgid "Purchase"
-msgstr "Vásárlás"
-
-#: .\aitrainer_backoffice\models.py:375
-msgid "Purchases"
-msgstr "Vásárlások"
-
-#: .\aitrainer_backoffice\models.py:385
-msgid "Customer Property"
-msgstr "Ügyfél tulajdonság"
-
-#: .\aitrainer_backoffice\models.py:386
-msgid "Customer Properties"
-msgstr "Ügyfél tulajdonságok"
-
-#: .\aitrainer_backoffice\models.py:410
+#: .\aitrainer_backoffice\models\evaluation.py:10
msgid "exercise_type"
msgstr "Aktuális gyakorlat"
-#: .\aitrainer_backoffice\models.py:411
+#: .\aitrainer_backoffice\models\evaluation.py:11
msgid "unit"
msgstr "Mértékegység"
-#: .\aitrainer_backoffice\models.py:415
+#: .\aitrainer_backoffice\models\evaluation.py:15
msgid "Evaluation"
msgstr "Kiértékelés"
-#: .\aitrainer_backoffice\models.py:416
+#: .\aitrainer_backoffice\models\evaluation.py:16
msgid "Evaluations"
msgstr "Kiértékelés Csoport"
-#: .\aitrainer_backoffice\models.py:439
+#: .\aitrainer_backoffice\models\evaluation.py:39
msgid "evaluation_foreign"
msgstr "Kiértékelés Főcsoport"
-#: .\aitrainer_backoffice\models.py:440
+#: .\aitrainer_backoffice\models\evaluation.py:40
+#: .\aitrainer_backoffice\models\tutorial.py:11
msgid "name"
msgstr "Név"
-#: .\aitrainer_backoffice\models.py:441
+#: .\aitrainer_backoffice\models\evaluation.py:41
msgid "sex"
msgstr "Nem"
-#: .\aitrainer_backoffice\models.py:442
+#: .\aitrainer_backoffice\models\evaluation.py:42
msgid "age_min"
msgstr "Kortól"
-#: .\aitrainer_backoffice\models.py:443
+#: .\aitrainer_backoffice\models\evaluation.py:43
msgid "age_max"
msgstr "Korig"
-#: .\aitrainer_backoffice\models.py:444
+#: .\aitrainer_backoffice\models\evaluation.py:44
msgid "value_min"
msgstr "Min érték"
-#: .\aitrainer_backoffice\models.py:445
+#: .\aitrainer_backoffice\models\evaluation.py:45
msgid "value_max"
msgstr "Max érték"
-#: .\aitrainer_backoffice\models.py:447
+#: .\aitrainer_backoffice\models\evaluation.py:47
msgid "evaluation_text"
msgstr "Osztályozás"
-#: .\aitrainer_backoffice\models.py:449
+#: .\aitrainer_backoffice\models\evaluation.py:49
msgid "suggestion"
msgstr "Javaslat"
-#: .\aitrainer_backoffice\models.py:453
+#: .\aitrainer_backoffice\models\evaluation.py:53
msgid "Evaluation Table"
msgstr "Kiértékelés tábla"
-#: .\aitrainer_backoffice\models.py:454
+#: .\aitrainer_backoffice\models\evaluation.py:54
msgid "Evaluation Tables"
msgstr "Kiértékelés táblák"
+
+#: .\aitrainer_backoffice\models\exercise_device.py:18
+#: .\aitrainer_backoffice\models\exercise_type.py:88
+msgid "Exercise Device"
+msgstr "Edzés eszköz"
+
+#: .\aitrainer_backoffice\models\exercise_device.py:19
+#: .\aitrainer_backoffice\models\exercise_type.py:89
+msgid "Exercise Devices"
+msgstr "Edzés eszközök"
+
+#: .\aitrainer_backoffice\models\exercise_device.py:40
+msgid "Device Alternative"
+msgstr "Eszköz alternatíva"
+
+#: .\aitrainer_backoffice\models\exercise_device.py:41
+msgid "Device Alternatives"
+msgstr "Eszköz alternatívák"
+
+#: .\aitrainer_backoffice\models\exercise_device.py:53
+#: .\aitrainer_backoffice\models\exercise_plan.py:32
+#: .\aitrainer_backoffice\models\exercise_plan_template.py:40
+#: .\aitrainer_backoffice\models\exercise_type.py:74
+#: .\aitrainer_backoffice\models\exercisetree.py:33
+#: .\aitrainer_backoffice\models\property.py:29
+#: .\aitrainer_backoffice\models\tutorial.py:45
+msgid "Translation"
+msgstr "Fordítás"
+
+#: .\aitrainer_backoffice\models\exercise_device.py:54
+#: .\aitrainer_backoffice\models\exercise_plan.py:33
+#: .\aitrainer_backoffice\models\exercise_plan_template.py:41
+#: .\aitrainer_backoffice\models\exercise_type.py:75
+#: .\aitrainer_backoffice\models\exercisetree.py:34
+#: .\aitrainer_backoffice\models\property.py:30
+#: .\aitrainer_backoffice\models\tutorial.py:46
+msgid "Translations"
+msgstr "Fordítások"
+
+#: .\aitrainer_backoffice\models\exercise_plan.py:16
+msgid "Exercise Plan"
+msgstr "Edzésterv"
+
+#: .\aitrainer_backoffice\models\exercise_plan.py:17
+msgid "Exercise Plans"
+msgstr "Edzéstervek"
+
+#: .\aitrainer_backoffice\models\exercise_plan.py:49
+msgid "Exercise Plan Detail"
+msgstr "Edzésterv gyakorlat"
+
+#: .\aitrainer_backoffice\models\exercise_plan.py:50
+msgid "Exercise Plan Details"
+msgstr "Edzésterv gyakorlatok"
+
+#: .\aitrainer_backoffice\models\exercise_plan_template.py:23
+msgid "Exercise Plan Template"
+msgstr "Edzésterv sablon"
+
+#: .\aitrainer_backoffice\models\exercise_plan_template.py:24
+msgid "Exercise Plan Templates"
+msgstr "Edzésterv sablonok"
+
+#: .\aitrainer_backoffice\models\exercise_plan_template.py:59
+msgid "Exercise Plan Template Detail"
+msgstr "Edzésterv sablon gyakorlat"
+
+#: .\aitrainer_backoffice\models\exercise_plan_template.py:60
+msgid "Exercise Plan Template Details"
+msgstr "Edzésterv sablon gyakorlatok"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:35
+msgid "Exercise"
+msgstr "Gyakorlat"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:36
+msgid "Exercises"
+msgstr "Gyakorlatok"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:57
+msgid "Image"
+msgstr "Kép"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:58
+msgid "Images"
+msgstr "Képek"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:101
+msgid "Exercise Alternative"
+msgstr "Gyakorlat alternatíva"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:102
+msgid "Exercise Alternatives"
+msgstr "Gyakorlat alternatívák"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:113
+msgid "Exercise Parent"
+msgstr "Gyakorlat szülő"
+
+#: .\aitrainer_backoffice\models\exercise_type.py:114
+msgid "Exercise Parents"
+msgstr "Gyakorlat szülők"
+
+#: .\aitrainer_backoffice\models\exercisetree.py:16
+msgid "Exercise Tree"
+msgstr "Gyakorlat Menü"
+
+#: .\aitrainer_backoffice\models\exercisetree.py:17
+msgid "Exercise Tree Items"
+msgstr "Gyakorlat Menü elemek"
+
+#: .\aitrainer_backoffice\models\exercisetree.py:45
+msgid "Parent menu"
+msgstr "Szülő menüpont"
+
+#: .\aitrainer_backoffice\models\exercisetree.py:50
+#: .\aitrainer_backoffice\models\exercisetree.py:51
+msgid "Menu Tree Representation"
+msgstr ""
+
+#: .\aitrainer_backoffice\models\product.py:24
+msgid "Product"
+msgstr "Termék"
+
+#: .\aitrainer_backoffice\models\product.py:25
+msgid "Products"
+msgstr "Termékek"
+
+#: .\aitrainer_backoffice\models\product.py:41
+msgid "Purchase"
+msgstr "Vásárlás"
+
+#: .\aitrainer_backoffice\models\product.py:42
+msgid "Purchases"
+msgstr "Vásárlások"
+
+#: .\aitrainer_backoffice\models\property.py:14
+msgid "Customer Property"
+msgstr "Ügyfél tulajdonság"
+
+#: .\aitrainer_backoffice\models\property.py:15
+msgid "Customer Properties"
+msgstr "Ügyfél tulajdonságok"
+
+#: .\aitrainer_backoffice\models\tutorial.py:15
+msgid "Tutorial"
+msgstr "Tutorial"
+
+#: .\aitrainer_backoffice\models\tutorial.py:16
+msgid "Tutorials"
+msgstr "Tutoriálok"
+
+#: .\aitrainer_backoffice\models\tutorial.py:32
+msgid "Tutorial Step"
+msgstr "Tutorial lépés"
+
+#: .\aitrainer_backoffice\models\tutorial.py:33
+msgid "Tutorial Steps"
+msgstr "Tutorial lépések"
+
+#~ msgid "exercise_device_parent"
+#~ msgstr "Gyakorlat Eszköz szülő"
+
+#~ msgid "exercise_device_child"
+#~ msgstr "Gyakorlat eszköz"
+
+#~ msgid "exercise_tree_parent"
+#~ msgstr "Gyakorlat Menü szülő"
+
+#~ msgid "exercise_type_parent"
+#~ msgstr "Gyakorlat szülő"
+
+#~ msgid "exercise_type_child"
+#~ msgstr "Aktuális gyakorlat"
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models.py b/aitrainer_backoffice/aitrainer_backoffice/models.py
deleted file mode 100644
index a678d96..0000000
--- a/aitrainer_backoffice/aitrainer_backoffice/models.py
+++ /dev/null
@@ -1,458 +0,0 @@
-from django.db import models
-from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
-
-
-# from treenode.models import TreeNodeModel
-
-
-class LanguageTypes(models.TextChoices):
- EN = "en"
- HU = "hu"
-
-
-'''
- ExerciseDevice
- ------------
-'''
-
-
-class ExerciseDevice(models.Model):
- exercise_device_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100)
- image_url = models.ImageField(upload_to='images/', help_text='The image size is 1366x768')
- description = models.TextField(max_length=1000, blank=True, null=True, help_text="English description here")
- sort = models.IntegerField(blank=True, null=True)
- place = models.BooleanField()
-
- class Meta:
- db_table = 'exercise_device'
- verbose_name = _("Exercise Device")
- verbose_name_plural = _("Exercise Devices")
- ordering = ['name']
-
- def image_tag(self):
- return mark_safe('
' % self.image_url)
-
- image_tag.short_description = 'Image'
-
- def __str__(self):
- return self.name
-
-
-class ExerciseDeviceAlternative(models.Model):
- exercise_device_alternative_id = models.AutoField(primary_key=True)
- exercise_device_parent = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE,
- related_name='exercise_device_parent')
- exercise_device_child = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE,
- related_name='exercise_device_child')
-
- class Meta:
- db_table = 'exercise_device_alternative'
- verbose_name = _("Device Alternative")
- verbose_name_plural = _("Device Alternatives")
- unique_together = ['exercise_device_parent', 'exercise_device_child']
-
-
-class ExerciseDeviceTranslation(models.Model):
- translation_id = models.AutoField(primary_key=True)
- exercise_device = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE)
- name = models.CharField(max_length=100)
- language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
-
- class Meta:
- db_table = 'exercise_device_translation'
- verbose_name = _("Translation")
- verbose_name_plural = _("Translations")
-
- def __str__(self):
- return self.name
-
-
-'''
- ------------
- ExerciseTree
- ------------
-'''
-
-
-class ExerciseTree(models.Model):
- tree_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100, help_text='The name should be in English here')
- description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in '
- 'English here')
- image_url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768')
- active = models.BooleanField(default=0, blank=True, null=True)
-
- class Meta:
- db_table = 'exercise_tree'
- verbose_name = _("Exercise Tree")
- verbose_name_plural = _("Exercise Tree Items")
- ordering = ['name']
-
- def __str__(self):
- return self.name
-
-
-class ExerciseTreeTranslation(models.Model):
- translation_id = models.AutoField(primary_key=True)
- tree = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
- language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
- name = models.CharField(max_length=100)
- description = models.TextField(max_length=1000, blank=True, null=True)
-
- class Meta:
- db_table = 'exercise_tree_translation'
- verbose_name = _("Translation")
- verbose_name_plural = _("Translations")
-
- def __str__(self):
- return self.name
-
-
-class ExerciseTreeParents(models.Model):
- # treenode_display_field = 'name'
- exercise_tree_parents_id = models.AutoField(primary_key=True)
- exercise_tree_parent = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE,
- related_name='exercise_tree_parent',
- help_text=_('Parent menu'), blank=True)
- exercise_tree_child = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
-
- class Meta:
- db_table = 'exercise_tree_parents'
- verbose_name = _("Menu Tree Representation")
- verbose_name_plural = _("Menu Tree Representation")
- unique_together = [['exercise_tree_parent', 'exercise_tree_child']]
-
-
-'''
- ExerciseTYPE
- ------------
-'''
-
-
-class ExerciseType(models.Model):
- class UnitTypes(models.TextChoices):
- REPEAT = 'repeat'
- SECOND = 'second'
- MINUTE = 'minute'
- METER = 'meter'
- CM = 'centimeter'
- PERCENT = 'percent'
- CALORIES = 'calories'
- KG = 'kilogram'
-
- exercise_type_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100, help_text='The name should be in English here')
- description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in '
- 'English here')
- unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.REPEAT, max_length=50, blank=True, null=True)
- unit_quantity = models.BooleanField(default=0, blank=True, null=True)
- unit_quantity_unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.KG, max_length=50, blank=True,
- null=True)
- active = models.BooleanField(default=0, blank=True, null=True)
- base = models.BooleanField(default=0, blank=True, null=True)
- parents = models.ManyToManyField(ExerciseTree, through='ExerciseTypeParents', related_name='ExerciseTree')
-
- class Meta:
- db_table = 'exercise_type'
- verbose_name = _("Exercise")
- verbose_name_plural = _("Exercises")
- ordering = ['name']
-
- def __str__(self):
- return self.name
-
-
-class ExerciseTypeImage(models.Model):
- class ImageTypes(models.TextChoices):
- IMAGE = 'image'
- VIDEO = 'video'
- MENU = 'menu'
-
- image_id = models.AutoField(primary_key=True)
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
- name = models.CharField(max_length=50, blank=True, null=True)
- type = models.CharField(choices=ImageTypes.choices, default=ImageTypes.IMAGE, max_length=50, blank=True, null=True)
- url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768')
-
- class Meta:
- db_table = 'exercise_type_image'
- verbose_name = _("Image")
- verbose_name_plural = _("Images")
-
- def __str__(self):
- return self.name
-
-
-class ExerciseTypeTranslation(models.Model):
- translation_id = models.AutoField(primary_key=True)
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
- language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
- name = models.CharField(max_length=100)
- description = models.TextField(max_length=1000, blank=True, null=True)
-
- class Meta:
- db_table = 'exercise_type_translation'
- verbose_name = _("Translation")
- verbose_name_plural = _("Translations")
-
- def __str__(self):
- return self.name
-
-
-class ExerciseTypeDevice(models.Model):
- exercise_type_device_id = models.AutoField(primary_key=True)
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
- exercise_device = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE)
-
- class Meta:
- db_table = 'exercise_type_device'
- verbose_name = _("Exercise Device")
- verbose_name_plural = _("Exercise Devices")
-
-
-class ExerciseTypeAlternative(models.Model):
- exercise_type_alternative_id = models.AutoField(primary_key=True)
- exercise_type_parent = models.ForeignKey(ExerciseType, on_delete=models.CASCADE,
- related_name='exercise_type_parent')
- exercise_type_child = models.ForeignKey(ExerciseType, on_delete=models.CASCADE,
- related_name='exercise_type_child')
-
- class Meta:
- db_table = 'exercise_type_alternative'
- verbose_name = _("Exercise Alternative")
- verbose_name_plural = _("Exercise Alternatives")
- unique_together = [['exercise_type_parent', 'exercise_type_child']]
-
-
-class ExerciseTypeParents(models.Model):
- exercise_type_parents_id = models.AutoField(primary_key=True)
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
- exercise_tree = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
-
- class Meta:
- db_table = 'exercise_type_parents'
- verbose_name = _("Exercise Parent")
- verbose_name_plural = _("Exercise Parents")
- unique_together = [['exercise_type', 'exercise_tree']]
-
-
-class TemplateTypes(models.TextChoices):
- MINI_SET = "mini_test_set"
- SPECIAL = "special"
-
-
-class ExercisePlanTemplate(models.Model):
- exercise_plan_template_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100, help_text='The name should be in English here')
- description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in '
- 'English here')
- template_type = models.CharField(max_length=20, choices=TemplateTypes.choices, default=TemplateTypes.SPECIAL)
-
- class Meta:
- db_table = 'exercise_plan_template'
- verbose_name = _("Exercise Plan Template")
- verbose_name_plural = _("Exercise Plan Templates")
-
- def __str__(self):
- return self.name
-
-
-class ExercisePlanTemplateTranslation(models.Model):
- translation_id = models.AutoField(primary_key=True)
- exercise_plan_template = models.ForeignKey(ExercisePlanTemplate, on_delete=models.CASCADE)
- language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
- name = models.CharField(max_length=100)
- description = models.TextField(max_length=1000, blank=True, null=True)
-
- class Meta:
- db_table = 'exercise_plan_template_translation'
- verbose_name = _("Translation")
- verbose_name_plural = _("Translations")
-
- def __str__(self):
- return self.name
-
-
-class ExercisePlanTemplateDetail(models.Model):
- exercise_plan_template_detail_id = models.AutoField(primary_key=True)
- exercise_plan_template = models.ForeignKey(ExercisePlanTemplate, on_delete=models.CASCADE)
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
- serie = models.IntegerField()
- quantity = models.FloatField()
- quantity_unit_quantity = models.FloatField()
- resting_time = models.TimeField()
- sort = models.IntegerField()
-
- class Meta:
- db_table = 'exercise_plan_template_detail'
- verbose_name = _("Exercise Plan Template Detail")
- verbose_name_plural = _("Exercise Plan Template Details")
-
-
-class ExercisePlan(models.Model):
- exercise_plan_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100, help_text='The name should be in English here')
- description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in '
- 'English here')
-
- class Meta:
- db_table = 'exercise_plan'
- verbose_name = _("Exercise Plan")
- verbose_name_plural = _("Exercise Plans")
-
- def __str__(self):
- return self.name
-
-
-class ExercisePlanTranslation(models.Model):
- translation_id = models.AutoField(primary_key=True)
- exercise_plan = models.ForeignKey(ExercisePlan, on_delete=models.CASCADE)
- language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
- name = models.CharField(max_length=100)
- description = models.TextField(max_length=1000, blank=True, null=True)
-
- class Meta:
- db_table = 'exercise_plan_translation'
- verbose_name = _("Translation")
- verbose_name_plural = _("Translations")
-
- def __str__(self):
- return self.name
-
-
-class ExercisePlanDetail(models.Model):
- exercise_plan_detail_id = models.AutoField(primary_key=True)
- exercise_plan = models.ForeignKey(ExercisePlan, on_delete=models.CASCADE)
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
- serie = models.IntegerField()
- repeats = models.IntegerField()
- weight_equation = models.CharField(max_length=100)
-
- class Meta:
- db_table = 'exercise_plan_detail'
- verbose_name = _("Exercise Plan Detail")
- verbose_name_plural = _("Exercise Plan Details")
-
-
-class ProductTypes(models.TextChoices):
- SUBS = "subscription"
- IN_APP_CURR = "in-app-currency"
-
-
-class Product(models.Model):
- product_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=50)
- description = models.TextField(max_length=1000, blank=True, null=True)
- type = models.CharField(max_length=15, choices=ProductTypes.choices, default=ProductTypes.SUBS)
- valid_from = models.DateField(blank=True, null=True)
- valid_to = models.DateField(blank=True, null=True)
- product_id_ios = models.CharField(max_length=50, blank=True, null=True)
- product_id_android = models.CharField(max_length=50, blank=True, null=True)
- price_ios = models.DecimalField(max_length=12, decimal_places=2, max_digits=12, blank=True)
- price_android = models.DecimalField(max_length=12, decimal_places=2, max_digits=12, blank=True)
-
- class Meta:
- db_table = 'product'
- verbose_name = _("Product")
- verbose_name_plural = _("Products")
-
- def __str__(self):
- return self.name
-
-
-class Purchase(models.Model):
- purchase_id = models.AutoField(primary_key=True)
- product = models.ForeignKey(Product, on_delete=models.CASCADE)
- customer_id = models.IntegerField()
- date_add = models.DateField(blank=True, null=True)
- purchase_sum = models.DecimalField(decimal_places=2, max_digits=7)
- currency = models.CharField(max_length=3)
-
- class Meta:
- db_table = 'purchase'
- verbose_name = _("Purchase")
- verbose_name_plural = _("Purchases")
-
-
-class Property(models.Model):
- property_id = models.AutoField(primary_key=True)
- property_name = models.CharField(max_length=100, help_text='The name should be in English here')
- property_unit = models.CharField(max_length=10)
-
- class Meta:
- db_table = 'property'
- verbose_name = _("Customer Property")
- verbose_name_plural = _("Customer Properties")
-
- def __str__(self):
- return self.property_name
-
-
-class PropertyTranslation(models.Model):
- translation_id = models.AutoField(primary_key=True)
- property = models.ForeignKey(Property, on_delete=models.CASCADE)
- language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
- property_name = models.CharField(max_length=100)
-
- class Meta:
- db_table = 'property_translation'
- verbose_name = _("Translation")
- verbose_name_plural = _("Translations")
-
- def __str__(self):
- return self.property_name
-
-
-class Evaluation(models.Model):
- evaluation_id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100, help_text='The name should be in English here')
- exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE, verbose_name=_("exercise_type"))
- unit = models.CharField(max_length=50, verbose_name=_("unit"))
-
- class Meta:
- db_table = 'evaluation'
- verbose_name = _("Evaluation")
- verbose_name_plural = _("Evaluations")
-
- def __str__(self):
- return self.name
-
-
-class EvaluationAttribute(models.Model):
- class SexTypes(models.TextChoices):
- MAN = 'm'
- WOMAN = 'w'
-
- class EvaluationTypes(models.TextChoices):
- ELITE = "elite"
- EXCELLENT = "excellent"
- GOOD = "good"
- ABOVE_AVERAGE = "above_average"
- AVERAGE = "average"
- BELOW_AVERAGE = "below_average"
- FAIR = "fair"
- POOR = "poor"
- VERY_POOR = "very_poor"
-
- evaluation_attr_id = models.AutoField(primary_key=True)
- evaluation = models.ForeignKey(Evaluation, on_delete=models.CASCADE, verbose_name=_("evaluation_foreign"))
- name = models.CharField(max_length=100, help_text='The name should be in English here', verbose_name=_("name"))
- sex = models.CharField(max_length=1, choices=SexTypes.choices, default=SexTypes.MAN, verbose_name=_("sex"))
- age_min = models.IntegerField(verbose_name=_("age_min"))
- age_max = models.IntegerField(verbose_name=_("age_max"))
- value_min = models.FloatField(verbose_name=_("value_min"))
- value_max = models.FloatField(verbose_name=_("value_max"))
- evaluation_text = models.CharField(max_length=50, choices=EvaluationTypes.choices, default=EvaluationTypes.AVERAGE,
- verbose_name=_("evaluation_text"))
- suggestion = models.TextField(max_length=1000, blank=True, null=True, help_text="English suggestion here",
- verbose_name=_("suggestion"))
-
- class Meta:
- db_table = 'evaluation_attribute'
- verbose_name = _("Evaluation Table")
- verbose_name_plural = _("Evaluation Tables")
-
- def __str__(self):
- return self.name
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py b/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py
new file mode 100644
index 0000000..ea08a41
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/__init__.py
@@ -0,0 +1,12 @@
+from .exercisetree import ExerciseTree
+from .exercise_type import ExerciseType, ExerciseTypeAlternative, ExerciseTypeParents, ExerciseTypeDevice, \
+ ExerciseTypeTranslation, ExerciseTypeImage
+from .exercise_device import ExerciseDevice, ExerciseDeviceAlternative, ExerciseDeviceTranslation
+from .exercise_plan import ExercisePlan, ExercisePlanDetail, ExercisePlanTranslation
+from .exercise_plan_template import ExercisePlanTemplate, ExercisePlanTemplateDetail, ExercisePlanTemplateTranslation
+from .exercise_type import ExerciseType, ExerciseTypeAlternative, ExerciseTypeParents, ExerciseTypeDevice, \
+ ExerciseTypeTranslation, ExerciseTypeImage
+from .product import Product, Purchase
+from .property import Property, PropertyTranslation
+from .tutorial import Tutorial, TutorialSteps, TutorialTranslation
+from .evaluation import Evaluation, EvaluationAttribute
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/enums.py b/aitrainer_backoffice/aitrainer_backoffice/models/enums.py
new file mode 100644
index 0000000..0546f0f
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/enums.py
@@ -0,0 +1,7 @@
+from django.db import models
+
+
+class LanguageTypes(models.TextChoices):
+ EN = "en"
+ HU = "hu"
+
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py b/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py
new file mode 100644
index 0000000..e6af962
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py
@@ -0,0 +1,57 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from .exercise_type import ExerciseType
+
+
+class Evaluation(models.Model):
+ evaluation_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='The name should be in English here')
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE, verbose_name=_("exercise_type"))
+ unit = models.CharField(max_length=50, verbose_name=_("unit"))
+
+ class Meta:
+ db_table = 'evaluation'
+ verbose_name = _("Evaluation")
+ verbose_name_plural = _("Evaluations")
+
+ def __str__(self):
+ return self.name
+
+
+class EvaluationAttribute(models.Model):
+ class SexTypes(models.TextChoices):
+ MAN = 'm'
+ WOMAN = 'w'
+
+ class EvaluationTypes(models.TextChoices):
+ ELITE = "elite"
+ EXCELLENT = "excellent"
+ GOOD = "good"
+ ABOVE_AVERAGE = "above_average"
+ AVERAGE = "average"
+ BELOW_AVERAGE = "below_average"
+ FAIR = "fair"
+ POOR = "poor"
+ VERY_POOR = "very_poor"
+
+ evaluation_attr_id = models.AutoField(primary_key=True)
+ evaluation = models.ForeignKey(Evaluation, on_delete=models.CASCADE, verbose_name=_("evaluation_foreign"))
+ name = models.CharField(max_length=100, help_text='The name should be in English here', verbose_name=_("name"))
+ sex = models.CharField(max_length=1, choices=SexTypes.choices, default=SexTypes.MAN, verbose_name=_("sex"))
+ age_min = models.IntegerField(verbose_name=_("age_min"))
+ age_max = models.IntegerField(verbose_name=_("age_max"))
+ value_min = models.FloatField(verbose_name=_("value_min"))
+ value_max = models.FloatField(verbose_name=_("value_max"))
+ evaluation_text = models.CharField(max_length=50, choices=EvaluationTypes.choices, default=EvaluationTypes.AVERAGE,
+ verbose_name=_("evaluation_text"))
+ suggestion = models.TextField(max_length=1000, blank=True, null=True, help_text="English suggestion here",
+ verbose_name=_("suggestion"))
+
+ class Meta:
+ db_table = 'evaluation_attribute'
+ verbose_name = _("Evaluation Table")
+ verbose_name_plural = _("Evaluation Tables")
+
+ def __str__(self):
+ return self.name
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/exercise_device.py b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_device.py
new file mode 100644
index 0000000..4bc986a
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_device.py
@@ -0,0 +1,57 @@
+from django.db import models
+from django.utils.safestring import mark_safe
+from django.utils.translation import ugettext_lazy as _
+
+from .enums import LanguageTypes
+
+
+class ExerciseDevice(models.Model):
+ exercise_device_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100)
+ image_url = models.ImageField(upload_to='images/', help_text='The image size is 1366x768')
+ description = models.TextField(max_length=1000, blank=True, null=True, help_text="English description here")
+ sort = models.IntegerField(blank=True, null=True)
+ place = models.BooleanField()
+
+ class Meta:
+ db_table = 'exercise_device'
+ verbose_name = _("Exercise Device")
+ verbose_name_plural = _("Exercise Devices")
+ ordering = ['name']
+
+ def image_tag(self):
+ return mark_safe('
' % self.image_url)
+
+ image_tag.short_description = 'Image'
+
+ def __str__(self):
+ return self.name
+
+
+class ExerciseDeviceAlternative(models.Model):
+ exercise_device_alternative_id = models.AutoField(primary_key=True)
+ exercise_device_parent = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE,
+ related_name='exercise_device_parent')
+ exercise_device_child = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE,
+ related_name='exercise_device_child')
+
+ class Meta:
+ db_table = 'exercise_device_alternative'
+ verbose_name = _("Device Alternative")
+ verbose_name_plural = _("Device Alternatives")
+ unique_together = ['exercise_device_parent', 'exercise_device_child']
+
+
+class ExerciseDeviceTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ exercise_device = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE)
+ name = models.CharField(max_length=100)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+
+ class Meta:
+ db_table = 'exercise_device_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.name
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan.py b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan.py
new file mode 100644
index 0000000..5a7b084
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan.py
@@ -0,0 +1,50 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from .enums import LanguageTypes
+from .exercise_type import ExerciseType
+
+
+class ExercisePlan(models.Model):
+ exercise_plan_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='The name should be in English here')
+ description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in '
+ 'English here')
+
+ class Meta:
+ db_table = 'exercise_plan'
+ verbose_name = _("Exercise Plan")
+ verbose_name_plural = _("Exercise Plans")
+
+ def __str__(self):
+ return self.name
+
+
+class ExercisePlanTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ exercise_plan = models.ForeignKey(ExercisePlan, on_delete=models.CASCADE)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+ name = models.CharField(max_length=100)
+ description = models.TextField(max_length=1000, blank=True, null=True)
+
+ class Meta:
+ db_table = 'exercise_plan_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.name
+
+
+class ExercisePlanDetail(models.Model):
+ exercise_plan_detail_id = models.AutoField(primary_key=True)
+ exercise_plan = models.ForeignKey(ExercisePlan, on_delete=models.CASCADE)
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ serie = models.IntegerField()
+ repeats = models.IntegerField()
+ weight_equation = models.CharField(max_length=100)
+
+ class Meta:
+ db_table = 'exercise_plan_detail'
+ verbose_name = _("Exercise Plan Detail")
+ verbose_name_plural = _("Exercise Plan Details")
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan_template.py b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan_template.py
new file mode 100644
index 0000000..03b3f32
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan_template.py
@@ -0,0 +1,60 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from froala_editor.fields import FroalaField
+
+from .enums import LanguageTypes
+from .exercise_type import ExerciseType
+
+
+class TemplateTypes(models.TextChoices):
+ MINI_SET = "mini_test_set"
+ SPECIAL = "special"
+
+
+class ExercisePlanTemplate(models.Model):
+ exercise_plan_template_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='The name should be in English here')
+ #description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in English here')
+ description = FroalaField()
+ template_type = models.CharField(max_length=20, choices=TemplateTypes.choices, default=TemplateTypes.SPECIAL)
+
+ class Meta:
+ db_table = 'exercise_plan_template'
+ verbose_name = _("Exercise Plan Template")
+ verbose_name_plural = _("Exercise Plan Templates")
+
+ def __str__(self):
+ return self.name
+
+
+class ExercisePlanTemplateTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ exercise_plan_template = models.ForeignKey(ExercisePlanTemplate, on_delete=models.CASCADE)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+ name = models.CharField(max_length=100)
+ #description = models.TextField(max_length=1000, blank=True, null=True)
+ description = FroalaField(blank=True, null=True)
+
+ class Meta:
+ db_table = 'exercise_plan_template_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.name
+
+
+class ExercisePlanTemplateDetail(models.Model):
+ exercise_plan_template_detail_id = models.AutoField(primary_key=True)
+ exercise_plan_template = models.ForeignKey(ExercisePlanTemplate, on_delete=models.CASCADE)
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ serie = models.IntegerField()
+ quantity = models.FloatField()
+ quantity_unit_quantity = models.FloatField()
+ resting_time = models.TimeField()
+ sort = models.IntegerField()
+
+ class Meta:
+ db_table = 'exercise_plan_template_detail'
+ verbose_name = _("Exercise Plan Template Detail")
+ verbose_name_plural = _("Exercise Plan Template Details")
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/exercise_type.py b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_type.py
new file mode 100644
index 0000000..00a9b5c
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/exercise_type.py
@@ -0,0 +1,115 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from froala_editor.fields import FroalaField
+
+from .enums import LanguageTypes
+from .exercise_device import ExerciseDevice
+from .exercisetree import ExerciseTree
+
+
+class ExerciseType(models.Model):
+ class UnitTypes(models.TextChoices):
+ REPEAT = 'repeat'
+ SECOND = 'second'
+ MINUTE = 'minute'
+ METER = 'meter'
+ CM = 'centimeter'
+ PERCENT = 'percent'
+ CALORIES = 'calories'
+ KG = 'kilogram'
+
+ exercise_type_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='The name should be in English here')
+ #description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in English here')
+ description = FroalaField()
+ unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.REPEAT, max_length=50, blank=True, null=True)
+ unit_quantity = models.BooleanField(default=0, blank=True, null=True)
+ unit_quantity_unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.KG, max_length=50, blank=True,
+ null=True)
+ active = models.BooleanField(default=0, blank=True, null=True)
+ base = models.BooleanField(default=0, blank=True, null=True)
+ parents = models.ManyToManyField(ExerciseTree, through='ExerciseTypeParents', related_name='ExerciseTree')
+
+ class Meta:
+ db_table = 'exercise_type'
+ verbose_name = _("Exercise")
+ verbose_name_plural = _("Exercises")
+ ordering = ['name']
+
+ def __str__(self):
+ return self.name
+
+
+class ExerciseTypeImage(models.Model):
+ class ImageTypes(models.TextChoices):
+ IMAGE = 'image'
+ VIDEO = 'video'
+ MENU = 'menu'
+
+ image_id = models.AutoField(primary_key=True)
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ name = models.CharField(max_length=50, blank=True, null=True)
+ type = models.CharField(choices=ImageTypes.choices, default=ImageTypes.IMAGE, max_length=50, blank=True, null=True)
+ url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768')
+
+ class Meta:
+ db_table = 'exercise_type_image'
+ verbose_name = _("Image")
+ verbose_name_plural = _("Images")
+
+ def __str__(self):
+ return self.name
+
+
+class ExerciseTypeTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+ name = models.CharField(max_length=100)
+ #description = models.TextField(max_length=1000, blank=True, null=True)
+ description = FroalaField(blank=True, null=True)
+
+ class Meta:
+ db_table = 'exercise_type_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.name
+
+
+class ExerciseTypeDevice(models.Model):
+ exercise_type_device_id = models.AutoField(primary_key=True)
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ exercise_device = models.ForeignKey(ExerciseDevice, on_delete=models.CASCADE)
+
+ class Meta:
+ db_table = 'exercise_type_device'
+ verbose_name = _("Exercise Device")
+ verbose_name_plural = _("Exercise Devices")
+
+
+class ExerciseTypeAlternative(models.Model):
+ exercise_type_alternative_id = models.AutoField(primary_key=True)
+ exercise_type_parent = models.ForeignKey(ExerciseType, on_delete=models.CASCADE,
+ related_name='exercise_type_parent')
+ exercise_type_child = models.ForeignKey(ExerciseType, on_delete=models.CASCADE,
+ related_name='exercise_type_child')
+
+ class Meta:
+ db_table = 'exercise_type_alternative'
+ verbose_name = _("Exercise Alternative")
+ verbose_name_plural = _("Exercise Alternatives")
+ unique_together = [['exercise_type_parent', 'exercise_type_child']]
+
+
+class ExerciseTypeParents(models.Model):
+ exercise_type_parents_id = models.AutoField(primary_key=True)
+ exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
+ exercise_tree = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
+
+ class Meta:
+ db_table = 'exercise_type_parents'
+ verbose_name = _("Exercise Parent")
+ verbose_name_plural = _("Exercise Parents")
+ unique_together = [['exercise_type', 'exercise_tree']]
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/exercisetree.py b/aitrainer_backoffice/aitrainer_backoffice/models/exercisetree.py
new file mode 100644
index 0000000..a7fb7e3
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/exercisetree.py
@@ -0,0 +1,53 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from .enums import LanguageTypes
+
+
+class ExerciseTree(models.Model):
+ tree_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='The name should be in English here')
+ description = models.TextField(max_length=1000, blank=True, null=True, help_text='The description should be in '
+ 'English here')
+ image_url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768')
+ active = models.BooleanField(default=0, blank=True, null=True)
+
+ class Meta:
+ db_table = 'exercise_tree'
+ verbose_name = _("Exercise Tree")
+ verbose_name_plural = _("Exercise Tree Items")
+ ordering = ['name']
+
+ def __str__(self):
+ return self.name
+
+
+class ExerciseTreeTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ tree = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+ name = models.CharField(max_length=100)
+ description = models.TextField(max_length=1000, blank=True, null=True)
+
+ class Meta:
+ db_table = 'exercise_tree_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.name
+
+
+class ExerciseTreeParents(models.Model):
+ # treenode_display_field = 'name'
+ exercise_tree_parents_id = models.AutoField(primary_key=True)
+ exercise_tree_parent = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE,
+ related_name='exercise_tree_parent',
+ help_text=_('Parent menu'), blank=True)
+ exercise_tree_child = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
+
+ class Meta:
+ db_table = 'exercise_tree_parents'
+ verbose_name = _("Menu Tree Representation")
+ verbose_name_plural = _("Menu Tree Representation")
+ unique_together = [['exercise_tree_parent', 'exercise_tree_child']]
+ app_label = 'aitrainer_backoffice.aitrainer_backoffice'
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/product.py b/aitrainer_backoffice/aitrainer_backoffice/models/product.py
new file mode 100644
index 0000000..cfb1138
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/product.py
@@ -0,0 +1,42 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+
+class ProductTypes(models.TextChoices):
+ SUBS = "subscription"
+ IN_APP_CURR = "in-app-currency"
+
+
+class Product(models.Model):
+ product_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=50)
+ description = models.TextField(max_length=1000, blank=True, null=True)
+ type = models.CharField(max_length=15, choices=ProductTypes.choices, default=ProductTypes.SUBS)
+ valid_from = models.DateField(blank=True, null=True)
+ valid_to = models.DateField(blank=True, null=True)
+ product_id_ios = models.CharField(max_length=50, blank=True, null=True)
+ product_id_android = models.CharField(max_length=50, blank=True, null=True)
+ price_ios = models.DecimalField(max_length=12, decimal_places=2, max_digits=12, blank=True)
+ price_android = models.DecimalField(max_length=12, decimal_places=2, max_digits=12, blank=True)
+
+ class Meta:
+ db_table = 'product'
+ verbose_name = _("Product")
+ verbose_name_plural = _("Products")
+
+ def __str__(self):
+ return self.name
+
+
+class Purchase(models.Model):
+ purchase_id = models.AutoField(primary_key=True)
+ product = models.ForeignKey(Product, on_delete=models.CASCADE)
+ customer_id = models.IntegerField()
+ date_add = models.DateField(blank=True, null=True)
+ purchase_sum = models.DecimalField(decimal_places=2, max_digits=7)
+ currency = models.CharField(max_length=3)
+
+ class Meta:
+ db_table = 'purchase'
+ verbose_name = _("Purchase")
+ verbose_name_plural = _("Purchases")
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/property.py b/aitrainer_backoffice/aitrainer_backoffice/models/property.py
new file mode 100644
index 0000000..ec775cf
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/property.py
@@ -0,0 +1,33 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from .enums import LanguageTypes
+
+
+class Property(models.Model):
+ property_id = models.AutoField(primary_key=True)
+ property_name = models.CharField(max_length=100, help_text='The name should be in English here')
+ property_unit = models.CharField(max_length=10)
+
+ class Meta:
+ db_table = 'property'
+ verbose_name = _("Customer Property")
+ verbose_name_plural = _("Customer Properties")
+
+ def __str__(self):
+ return self.property_name
+
+
+class PropertyTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ property = models.ForeignKey(Property, on_delete=models.CASCADE)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+ property_name = models.CharField(max_length=100)
+
+ class Meta:
+ db_table = 'property_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.property_name
\ No newline at end of file
diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/tutorial.py b/aitrainer_backoffice/aitrainer_backoffice/models/tutorial.py
new file mode 100644
index 0000000..f58464d
--- /dev/null
+++ b/aitrainer_backoffice/aitrainer_backoffice/models/tutorial.py
@@ -0,0 +1,49 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from froala_editor.fields import FroalaField
+
+from .enums import LanguageTypes
+
+
+class Tutorial(models.Model):
+ tutorial_id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, help_text='The name should be in English here',
+ verbose_name=_("name"))
+
+ class Meta:
+ db_table = 'tutorial'
+ verbose_name = _("Tutorial")
+ verbose_name_plural = _("Tutorials")
+
+ def __str__(self):
+ return self.name
+
+
+class TutorialSteps(models.Model):
+ tutorial_step_id = models.AutoField(primary_key=True)
+ tutorial = models.ForeignKey(Tutorial, on_delete=models.CASCADE)
+ step = models.IntegerField(help_text="Tutorial Step")
+ tutorial_text = FroalaField()
+ error_text = FroalaField(blank=True, null=True)
+ check_text = models.TextField(max_length=50, blank=True, null=True, help_text="Only for programmers!")
+
+ class Meta:
+ db_table = 'tutorial_steps'
+ verbose_name = _("Tutorial Step")
+ verbose_name_plural = _("Tutorial Steps")
+
+
+class TutorialTranslation(models.Model):
+ translation_id = models.AutoField(primary_key=True)
+ tutorial_step = models.ForeignKey(TutorialSteps, on_delete=models.CASCADE)
+ language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
+ tutorial_text = FroalaField()
+ error_text = FroalaField(blank=True, null=True)
+
+ class Meta:
+ db_table = 'tutorial_translation'
+ verbose_name = _("Translation")
+ verbose_name_plural = _("Translations")
+
+ def __str__(self):
+ return self.tutorial_text
\ 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 4a165da..5ac26bd 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.7
+BACKOFFICE_VERSION = 1.9
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -44,6 +44,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'froala_editor'
]
MIDDLEWARE = [
@@ -126,6 +127,7 @@ USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
+STATIC_JS_DIR = os.path.join(STATIC_URL, "js")
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py
index fa98f42..ba61f02 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py
+++ b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py
@@ -40,6 +40,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'tinymce'
]
MIDDLEWARE = [
diff --git a/aitrainer_backoffice/aitrainer_backoffice/urls.py b/aitrainer_backoffice/aitrainer_backoffice/urls.py
index e5f0a3c..779c3d3 100644
--- a/aitrainer_backoffice/aitrainer_backoffice/urls.py
+++ b/aitrainer_backoffice/aitrainer_backoffice/urls.py
@@ -16,13 +16,15 @@ Including another URLconf
path('admin/', admin.site.urls),
"""
+from django.conf import settings #
+from django.conf.urls.static import static # n
from django.contrib import admin
from django.urls import path, include
-from django.conf import settings #
-from django.conf.urls.static import static # n
+from froala_editor import views
urlpatterns = [
path('admin/', admin.site.urls),
+ path('froala_editor/',include('froala_editor.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
diff --git a/requirements.txt b/requirements.txt
index a311f8d..e6c0b97 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
-django==3.1.7
-asgiref==3.2.10
+django==3.2
+django-froala-editor=3.2.6-1
+asgiref==3.3.4
certifi==2020.6.20
chardet==3.0.4
idna==2.10