From a764cb8f21935938ee5db1948f4eaff70672aa65 Mon Sep 17 00:00:00 2001 From: Bossanyi Tibor Date: Sat, 24 Apr 2021 14:47:53 +0200 Subject: [PATCH] BO 1.9 tutorials, model and admin.py separeted, django 3.2 --- README.md | 2 +- .../aitrainer_backoffice/admin.py | 314 ------------ .../aitrainer_backoffice/admin/__init__.py | 10 + .../aitrainer_backoffice/admin/evaluation.py | 32 ++ .../admin/exercise_device.py | 41 ++ .../admin/exercise_plan.py | 42 ++ .../admin/exercise_plan_template.py | 51 ++ .../admin/exercise_type.py | 79 +++ .../admin/exercisetree.py | 63 +++ .../aitrainer_backoffice/admin/product.py | 11 + .../aitrainer_backoffice/admin/tutorial.py | 29 ++ .../locale/hu/LC_MESSAGES/django.mo | Bin 3147 -> 3023 bytes .../locale/hu/LC_MESSAGES/django.po | 364 +++++++------- .../aitrainer_backoffice/models.py | 458 ------------------ .../aitrainer_backoffice/models/__init__.py | 12 + .../aitrainer_backoffice/models/enums.py | 7 + .../aitrainer_backoffice/models/evaluation.py | 57 +++ .../models/exercise_device.py | 57 +++ .../models/exercise_plan.py | 50 ++ .../models/exercise_plan_template.py | 60 +++ .../models/exercise_type.py | 115 +++++ .../models/exercisetree.py | 53 ++ .../aitrainer_backoffice/models/product.py | 42 ++ .../aitrainer_backoffice/models/property.py | 33 ++ .../aitrainer_backoffice/models/tutorial.py | 49 ++ .../aitrainer_backoffice/settings/dev.py | 4 +- .../aitrainer_backoffice/settings/prod.py | 1 + .../aitrainer_backoffice/urls.py | 6 +- requirements.txt | 5 +- 29 files changed, 1099 insertions(+), 948 deletions(-) delete mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/exercise_device.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/exercise_plan_template.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/exercisetree.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/product.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py delete mode 100644 aitrainer_backoffice/aitrainer_backoffice/models.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/__init__.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/enums.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/exercise_device.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/exercise_plan_template.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/exercise_type.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/exercisetree.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/product.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/property.py create mode 100644 aitrainer_backoffice/aitrainer_backoffice/models/tutorial.py 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 cfc8bc84abbbeda72ba690a84b2a8ef93367dccd..3d7475f0ee8db601bfbdb92bdcefc8f844e4bf66 100644 GIT binary patch delta 1203 zcmZA0Ur1A77{~F)cGPs5HmjLSTLk@4Tc#_DASr~1BoHeqx@Z?ebQ7oBqFu;{>as36 zNmNh?MR*ZGqk`}z29gAY5M7Ey7ZqJa-FVgar)NeT_MFdq-hbzPpZDxt#+sv z%<>kcpn*Nh6?V#dj$_xiT z>818OJEg$ShPY|PqgaXKsFh#yyn&kFHmctw*5FgG{Wa=^MbrZ3Q2iHB^L_XHiOS$2 z*71I;rBwr)k!)ETD*GL%)JDDfZq$T5o+t1K$8`p^^LwmT87iPMHjB#CJZeF|y>^F5 z)V~Sy>d;9+6CdNI=YDL&A=JPts58Ck`3SXxm#78KqF(qBHU1l_zZydjKpj;Cbrij* z%w4GF{P_rMmLVLGUQa-j2ZA9tP4F6wERA>d}zVUSptDyI5ZMyWX_N9{9PSihlGoj?{A$Ak` zQ|MH*uQ1U?bPziTB_Tp+Z=J+eqLt7Ubz@GjY+E7c^sS1V%w|T$24hJp6~g_QcC%itz$)tPEf1u%TB9o;&m<|u* PVu_KlWGv&>*Btx<{!@q& delta 1322 zcmZXTTS(MF6oXG%xlMG{;VbsUOxZpP?2rt4scmw9cdrtotX0xA#x$qN|-47Um{^iE3fVnUPOJD)4 zfoqIOnL{k(cx+x_tlJO39Q5a*97mxX@4!Mh4L879xDoz@MKG9Y%xYK-<=+66z+t!& z9*3Bk6Y295nX=$#l1z$t1ZKg@P?3*0jze8=8_I41u7Z!C?4LWnhN{pzNQUMsRN%j$ z0uN%WgsNZ;@0&&zim=rkgdx>4gHT;K4OQZl(_exLR-a52ZbEYL0#-Y>2E<*Xc{WwH;!{qc7LD(%;R>osu1cw zvlc3$3W$lRb!>!m%2Xn0doSV(*6(7c`jjJ^k%gg~H0qJ6^opCIBHQjw_-cD=SScO{=ij{lUy{dS27yMJ#>Nax)8 z!oAkS?U0ENba&hMWJA_lpVt!DeXw~r+;b`x4JXQMJlQkzAZZpgP4k+vcyeYc`t<6O clUCa|Gqs@i&ISs+kw7SK(bIW&qk+AD0RzskX#fBK 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