From 2a4731dc29b3bed62a75662ca1c5322dc6c790b1 Mon Sep 17 00:00:00 2001 From: "Tibor Bossanyi (Freelancer)" Date: Tue, 19 Oct 2021 08:23:52 +0200 Subject: [PATCH] V1.31 exercise_type clone, evaluation inline --- .../aitrainer_backoffice/admin/__init__.py | 2 +- .../aitrainer_backoffice/admin/base_site.html | 2 +- .../aitrainer_backoffice/admin/controlling.py | 4 +- .../aitrainer_backoffice/admin/description.py | 4 +- .../aitrainer_backoffice/admin/evaluation.py | 48 ++++++---- .../admin/exercise_type.py | 9 ++ .../admin/inline_select_action.py | 2 +- .../aitrainer_backoffice/admin/product.py | 4 +- .../admin/training_plan.py | 6 +- .../aitrainer_backoffice/admin/tutorial.py | 6 +- .../locale/hu/LC_MESSAGES/django.mo | Bin 4120 -> 4570 bytes .../locale/hu/LC_MESSAGES/django.po | 71 ++++++++++----- .../aitrainer_backoffice/models/app_text.py | 2 +- .../aitrainer_backoffice/models/customer.py | 1 + .../aitrainer_backoffice/models/evaluation.py | 2 + .../aitrainer_backoffice/settings/deploy.py | 8 +- .../aitrainer_backoffice/settings/dev.py | 2 +- .../aitrainer_backoffice/settings/prod.py | 2 +- .../templates/admin/edit_inline/stacked.html | 30 +++++++ .../templates/admin/edit_inline/tabular.html | 84 ++++++++++++++++++ .../templates/controlling/mautic.html | 7 ++ .../controlling/admin/customer.py | 11 ++- .../controlling/automation/fcm.py | 6 +- .../controlling/automation/mautic.py | 38 +++++++- .../locale/hu/LC_MESSAGES/django.po | 42 +++------ cron.sh | 2 +- 26 files changed, 295 insertions(+), 100 deletions(-) create mode 100644 aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/stacked.html create mode 100644 aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/tabular.html diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py b/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py index ea0d007..0ec0695 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/__init__.py @@ -5,7 +5,7 @@ from .exercise_plan_template import ExercisePlanTemplateAdmin, ExercisePlanTempl from .product import ProductAdmin from .exercise_device import ExerciseDeviceAdmin from .tutorial import TutorialAdmin -from .evaluation import EvaluationAdmin, EvaluationAttributeAdmin +from .evaluation import EvaluationAdmin from .exercise_plan import ExercisePlanAdmin from .description import DescriptionAdmin from .training_plan import TrainingPlanAdmin, TrainingPlanDetailAdmin diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html b/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html index 176e0d8..8cb71d4 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/base_site.html @@ -5,5 +5,5 @@ {% endblock %} {% block content %} -

Controlling

+

Controlling2

{% endblock %} diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py b/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py index c5b30c9..0d1d15e 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/controlling.py @@ -25,5 +25,5 @@ class ControllingAdmin(admin.ModelAdmin): ] -admin.site.register(Controlling, ControllingAdmin) -admin.autodiscover() +#admin.site.register(Controlling, ControllingAdmin) +#admin.autodiscover() diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/description.py b/aitrainer_backoffice/aitrainer_backoffice/admin/description.py index 0754f4c..e6935aa 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/description.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/description.py @@ -19,5 +19,5 @@ class DescriptionAdmin(admin.ModelAdmin): ] -admin.site.register(Description, DescriptionAdmin) -admin.autodiscover() +#admin.site.register(Description, DescriptionAdmin) +#admin.autodiscover() diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py b/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py index 754d978..0bb4ed0 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/evaluation.py @@ -1,32 +1,42 @@ +from adminsortable2.admin import SortableInlineAdminMixin from django.contrib import admin - +#from .inline_select_action import BaseInlineSelectActionsMixin +from inline_actions.admin import InlineActionsMixin, InlineActionsModelAdminMixin from ..models.evaluation import EvaluationAttribute, Evaluation +from django.utils.translation import ugettext_lazy as _ +from django.contrib import messages -class EvaluationAdmin(admin.ModelAdmin): +class EvaluationAttributeInline(InlineActionsMixin, SortableInlineAdminMixin, admin.TabularInline): + model = EvaluationAttribute + extra = 0 + list_display = ( + 'sort', 'evaluation_attr_id', 'name', 'sex', 'age_min', 'age_max', 'value_min', 'value_max', 'evaluation_text') + list_editable = ('sort', 'name', 'sex', 'age_min', 'age_max', 'value_min', 'value_max', 'evaluation_text') + list_display_links = ('sort', ) + ordering = ('sort',) + inline_actions = ('clone_eval',) + + def clone_eval(self, request, obj, parent_obj=None): + print("cloning {obj}") + obj.pk = None + obj.name = obj.name + "_copy" + obj.save() + messages.info(request, f'{obj} has been cloned') + + clone_eval.short_description = _("Clone the selected evaluation") + + +class EvaluationAdmin(InlineActionsModelAdminMixin, 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] + inlines = [ + EvaluationAttributeInline + ] admin.site.register(Evaluation, EvaluationAdmin) -admin.site.register(EvaluationAttribute, EvaluationAttributeAdmin) admin.autodiscover() diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py index cc91813..1af05c2 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/exercise_type.py @@ -50,6 +50,15 @@ class ExerciseTypeAdmin(admin.ModelAdmin): list_display = ('exercise_type_id', 'name_colored', 'active', 'base', 'buddy_warning', 'is_description', 'is_desc_hu', 'alternatives') search_fields = ['name', 'exercisetypetranslation__name'] fields = ('name', 'description', 'unit', 'unit_quantity', 'unit_quantity_unit', 'active', 'base', 'buddy_warning') + list_filter = ('active','base', 'buddy_warning') + actions = ('clone',) + + @admin.action(description=_('Clone exercise type')) + def clone(modeladmin, request, queryset): + for qs in queryset: + qs.pk = None + qs.name = qs.name + "_copy" + qs.save() def name_colored(self, obj): if obj.active: diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/inline_select_action.py b/aitrainer_backoffice/aitrainer_backoffice/admin/inline_select_action.py index 9af263b..12afd28 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/inline_select_action.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/inline_select_action.py @@ -108,7 +108,7 @@ class BaseInlineSelectActionsMixin: ) ) - print("Buttons " + str(buttons)) + #print("Buttons " + str(buttons)) return mark_safe( '
{}
'.format(''.join(buttons)) ) diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/product.py b/aitrainer_backoffice/aitrainer_backoffice/admin/product.py index 5f83c23..21ededc 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/product.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/product.py @@ -7,5 +7,5 @@ class ProductAdmin(admin.ModelAdmin): list_display = ('product_id', 'name', 'type') -admin.site.register(Product, ProductAdmin) -admin.autodiscover() \ No newline at end of file +#admin.site.register(Product, ProductAdmin) +#admin.autodiscover() \ No newline at end of file diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py b/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py index 50aed05..ceb01a1 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py @@ -18,7 +18,7 @@ class TrainingPlanDetailInline(BaseInlineSelectActionsMixin, SortableInlineAdmin list_display_links = ('sort', ) ordering = ('sort',) - inline_select_actions = ['copy_attributes',] + inline_select_actions = ['clone',] def repeat_max(self, obj): if obj.repeat_max: @@ -47,7 +47,7 @@ class TrainingPlanDetailInline(BaseInlineSelectActionsMixin, SortableInlineAdmin return actions @admin.action(description='clone') - def copy_attributes(self, request, obj, parent_obj=None): + def clone(self, request, obj, parent_obj=None): name = str(request.queryset[0].training_plan) details = TrainingPlanDetail.objects.filter(training_plan__name=name).order_by('sort') @@ -59,7 +59,7 @@ class TrainingPlanDetailInline(BaseInlineSelectActionsMixin, SortableInlineAdmin objectAttr.save() new_sort = new_sort + 1 - copy_attributes.short_description = _("Clone the selected Training Plan Detail") + clone.short_description = _("Clone the selected Training Plan Detail") def select_max_repeat(self, request, queryset): for obj in queryset: diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py b/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py index ff21057..96cec09 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/tutorial.py @@ -93,6 +93,6 @@ class TutorialAdmin(admin.ModelAdmin): fields = ('name',) -admin.site.register(Tutorial, TutorialAdmin) -admin.site.register(TutorialSteps, TutorialStepsAdmin) -admin.autodiscover() +#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 ef229986b25c7011dbb2cf6ad779d5a7cd06b76a..2a512526f1dcba4ed0a659f7c6484c35709ba1f4 100644 GIT binary patch delta 2109 zcmZYAe`wTo9LMpGb6wkR^HR6A%5C4W+$wFFR&M@kKg_mkX(dz?#JPPpue*KkxbJPa z5!@ez)j#39qHUHSNpKoQ9{nRh;g?AILy16Q(l4X}gG!1~5Yh8>`&=M>xcBGr`TqF) zdVfFD8E1ZV?wb{rZy3sB#46%=g)w8e_BtxccOhe{@O!MrD|kKrfy?l3`#j7|J+H@` zu?3f7C$?b}o6$#&H;pTe$(cDCdhrx$fKM=tpJOdv#1(iM>0lPH25T7Q25dm}UxVtm z8Tpw$s(Kv62Hb}cJb>!=O6fXh%&fgpz&akBL3KQb>i9L@h`*zDP{S%)upJw57b+9a zq56BMg}#9N%pt0!IER&Z6iJ$SN7u}6PS8-c-$xDbp?x91QYNsK`xnu{1tbZkkuhO~FHSAep%#6Lh#Oi38 zA5aUpidxuT)+%PzH*Q1++fiqvA8*2EP=|E9j{IxlL)_4}oJD2i1JnXOLp}e(I*&@- zWz?DY6E$&!O14mG;&s;TsBw0q-hUdKFpd1ot2t_|Y{q&5mBNounYn$!ZrBh{)=pl9! zj}V&({X?^kC>I^lUVEY4scazh@52t_KB8Ripz#o)&!o&gOsH%ox`+-Ux07lk@gSi; z31y&@&>2v=RJIbkO0C6ey=`x^-fz7N+X!V-hmx~e`hP{|M@0v@T=dDw^7Ex{teg7J z$01e|YYCO;BBi>ITHp5pLMOjm9;LB`7$EMnH}A3bqt1d3W<|a^)YLGPji)@{bf?qK z6GIu-_5A&*Y<^>?XE2%aTqnEVb$mDJ4rSe8XKyAJ_u}5DvnLtzoIW=jiziL*|KD>b zV#)EC1~$Fpel|7cX7YZht-5^S7iU8!E0*`gCe43Ca^dH@s=urniD&$*7aJ>vYYs1I zNDRe;V!}j&LfXxElb=o}XyuQD_io!cJQWoDbS5>LiH$jlWKi@{Q^7GmW}@++kjVyx zgq!4zYaRt}jZTgPg=GGha7T6Ng1sg3t7@Ok$7>@iU1qwbvzsWMs@+i$@nUJSI3cZ6 YBLCyEE8(b{as8>R7ZfJ)7b5-t0)X=cmH+?% delta 1692 zcmZ9MOGuPa6vwY-j*l5r^PT3HX=#rsQ}dCJ)Y9lhEg~=?g$f^J=q$?31d&7pN}qw1 z8;JyyjG9FRt{M`G7Dly5vPBZo$~J|xso!6(ARWH{{oQ-#yZ794&Yf>2cgP#~niz4{ zU`;3!oe4Ll1rA5hVBSb$qF@e;hJ|)qY{ykFgZW0709)aD=(ppWFqZLs=!T;(5e6ae z1z=?A z7=l^&H#2lLGO-9#VJhLqK_Aox)ld-~fy%%+xCXXECFv66tft3~d*NEf0jTvi?C%a- z$^^`2eiVA~Z>H$r+ss2AvtYRh2|a(Eo-{R?mdyaKb}AkN9f=I!T^%=62@;_q&45a2F4P8Fp)Oe&l;aw>37&wPp&x4f zJ*Y@Wpd5`ue3=(82fnuBd8h*ge$i1X+<1|rJQ_t@0u@0m)PasdmFg5!W-dZG=!FWP z59$E7VLBXyay$W*kx8h4rlIc8C&<15^O=rb{04cnBrs8<7{u6pbQQy0#%5Y9EqS zBNAwKXn-9+x_CuM_hQA$Y)2)mM8!y1iPHaHR*rPR_M?0x+k>)^>b4arZL6)+4pjd_ zRF4{v(yS6zAYDq?L8L6NHkGZQibfYkR)F>{^_Cmm3tckR-8i$6X^z`f>pXDf1>d?J zhdcc-Z-T9{17S|I=cMz@lk7}*(w+C7=2EXeG}7AHVh*>3#=8BXv5xbdp|PIj+0aPG a|MT@dU6;GM{lQ~#HQ~;~_&MiJLeoFa1D6c| 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 8d5860d..2796b1b 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-09-26 11:21+0200\n" +"POT-Creation-Date: 2021-10-17 10:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -22,14 +22,17 @@ msgstr "" #: .\aitrainer_backoffice\admin\exercise_device.py:32 #: .\aitrainer_backoffice\admin\exercise_type.py:27 #: .\aitrainer_backoffice\admin\exercisetree.py:41 +#: .\aitrainer_backoffice\admin\notification.py:21 msgid "Image Preview" msgstr "Kép előnézet" +#: .\aitrainer_backoffice\admin\evaluation.py:29 +msgid "Clone the selected evaluation" +msgstr "Kiértékelés klónozása" + #: .\aitrainer_backoffice\admin\inline_select_action.py:116 -#, fuzzy -#| msgid "Descriptions" msgid "Actions" -msgstr "Leírás" +msgstr "Akciók" #: .\aitrainer_backoffice\admin\training_plan.py:30 #: .\aitrainer_backoffice\admin\training_plan.py:159 @@ -43,10 +46,8 @@ msgstr "Ismétlés: -1, HA MAX ismétlés" #: .\aitrainer_backoffice\admin\training_plan.py:62 #: .\aitrainer_backoffice\admin\training_plan.py:185 -#, fuzzy -#| msgid "Training Plan Detail" msgid "Clone the selected Training Plan Detail" -msgstr "Edzésprogram részlet" +msgstr "Edzésprogram klónozása" #: .\aitrainer_backoffice\admin\training_plan.py:69 #: .\aitrainer_backoffice\admin\training_plan.py:192 @@ -63,11 +64,10 @@ msgid "text_key" msgstr "Szöveg kulcs" #: .\aitrainer_backoffice\models\app_text.py:11 -msgid "App képernyőkép" -msgstr "" +msgid "App Screenshot" +msgstr "Képernyőkép" #: .\aitrainer_backoffice\models\app_text.py:12 -#| msgid "Translations" msgid "Checked, Translation is OK" msgstr "Fordítás rendben, ellenőrizve" @@ -88,7 +88,7 @@ msgstr "App Fordítások" #: .\aitrainer_backoffice\models\exercisetree.py:36 #: .\aitrainer_backoffice\models\faq.py:34 #: .\aitrainer_backoffice\models\property.py:29 -#: .\aitrainer_backoffice\models\sports.py:31 +#: .\aitrainer_backoffice\models\sports.py:29 #: .\aitrainer_backoffice\models\training_plan.py:58 #: .\aitrainer_backoffice\models\training_plan_day.py:31 #: .\aitrainer_backoffice\models\tutorial.py:45 @@ -104,20 +104,21 @@ msgstr "Fordítás" #: .\aitrainer_backoffice\models\exercisetree.py:37 #: .\aitrainer_backoffice\models\faq.py:35 #: .\aitrainer_backoffice\models\property.py:30 -#: .\aitrainer_backoffice\models\sports.py:32 +#: .\aitrainer_backoffice\models\sports.py:30 #: .\aitrainer_backoffice\models\training_plan.py:59 #: .\aitrainer_backoffice\models\training_plan_day.py:32 #: .\aitrainer_backoffice\models\tutorial.py:46 msgid "Translations" msgstr "Fordítások" +#: .\aitrainer_backoffice\models\customer.py:9 #: .\aitrainer_backoffice\models\description.py:11 #: .\aitrainer_backoffice\models\evaluation.py:41 #: .\aitrainer_backoffice\models\faq.py:11 #: .\aitrainer_backoffice\models\faq.py:29 #: .\aitrainer_backoffice\models\split_tests.py:7 -#: .\aitrainer_backoffice\models\sports.py:11 -#: .\aitrainer_backoffice\models\sports.py:27 +#: .\aitrainer_backoffice\models\sports.py:9 +#: .\aitrainer_backoffice\models\sports.py:25 #: .\aitrainer_backoffice\models\training_plan.py:14 #: .\aitrainer_backoffice\models\training_plan_day.py:11 #: .\aitrainer_backoffice\models\training_plan_day.py:27 @@ -125,6 +126,21 @@ msgstr "Fordítások" msgid "name" msgstr "Név" +#: .\aitrainer_backoffice\models\customer.py:10 +#| msgid "name" +msgid "firstname" +msgstr "Keresztnév" + +#: .\aitrainer_backoffice\models\customer.py:28 +#| msgid "Customer Property" +msgid "Customer" +msgstr "Ügyfél" + +#: .\aitrainer_backoffice\models\customer.py:29 +#| msgid "Customer Properties" +msgid "Customers" +msgstr "Ügyfelek" + #: .\aitrainer_backoffice\models\description.py:19 msgid "Description" msgstr "Leírás" @@ -147,7 +163,7 @@ msgstr "Kiértékelés" #: .\aitrainer_backoffice\models\evaluation.py:17 msgid "Evaluations" -msgstr "Kiértékelés Csoport" +msgstr "Kiértékelések" #: .\aitrainer_backoffice\models\evaluation.py:40 msgid "evaluation_foreign" @@ -181,13 +197,13 @@ msgstr "Osztályozás" msgid "suggestion" msgstr "Javaslat" -#: .\aitrainer_backoffice\models\evaluation.py:54 -msgid "Evaluation Table" -msgstr "Kiértékelés tábla" - #: .\aitrainer_backoffice\models\evaluation.py:55 +msgid "Evaluation Table" +msgstr "Kiértékelés" + +#: .\aitrainer_backoffice\models\evaluation.py:56 msgid "Evaluation Tables" -msgstr "Kiértékelés táblák" +msgstr "Kiértékelések" #: .\aitrainer_backoffice\models\exercise_device.py:18 #: .\aitrainer_backoffice\models\exercise_type.py:87 @@ -301,6 +317,15 @@ msgstr "GYÍK" msgid "FAQs" msgstr "GYÍK" +#: .\aitrainer_backoffice\models\notification.py:20 +msgid "Notification" +msgstr "" + +#: .\aitrainer_backoffice\models\notification.py:21 +#| msgid "Descriptions" +msgid "Notifications" +msgstr "" + #: .\aitrainer_backoffice\models\product.py:24 msgid "Product" msgstr "Termék" @@ -333,11 +358,11 @@ msgstr "A/B Teszt" msgid "A/B Tests" msgstr "A/B Tesztek" -#: .\aitrainer_backoffice\models\sports.py:15 +#: .\aitrainer_backoffice\models\sports.py:13 msgid "Sport" msgstr "" -#: .\aitrainer_backoffice\models\sports.py:16 +#: .\aitrainer_backoffice\models\sports.py:14 msgid "Sports" msgstr "" @@ -358,13 +383,11 @@ msgid "Training Plan Details" msgstr "Edzésprogram részletek" #: .\aitrainer_backoffice\models\training_plan_day.py:15 -#, fuzzy #| msgid "Training Plan" msgid "Training Day" msgstr "Edzésnap" #: .\aitrainer_backoffice\models\training_plan_day.py:16 -#, fuzzy #| msgid "Training Plans" msgid "Training Days" msgstr "Edzésnapok" diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/app_text.py b/aitrainer_backoffice/aitrainer_backoffice/models/app_text.py index c06264a..ea3597c 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/models/app_text.py +++ b/aitrainer_backoffice/aitrainer_backoffice/models/app_text.py @@ -8,7 +8,7 @@ class AppText(models.Model): text_id = models.AutoField(primary_key=True) text_key = models.TextField(max_length=255, help_text='Do not edit this! It is the key in the mobile app', verbose_name=_("text_key")) - screenshot_url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768', blank=True,verbose_name=_("App képernyőkép") ) + screenshot_url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768', blank=True,verbose_name=_("App Screenshot") ) checked = models.BooleanField(blank=True, verbose_name=_("Checked, Translation is OK")) class Meta: diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/customer.py b/aitrainer_backoffice/aitrainer_backoffice/models/customer.py index 401bb7e..44887a1 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/models/customer.py +++ b/aitrainer_backoffice/aitrainer_backoffice/models/customer.py @@ -15,6 +15,7 @@ class Customer(models.Model): date_add = models.DateField() synced_date = models.DateTimeField(blank=True,null=True) firebase_reg_token = models.CharField(max_length=255, blank=True, null=True) + lang = models.CharField(max_length=5, blank=True, null=True) def has_add_permission(self, request): return False diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py b/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py index 68c26b3..4275ee6 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py +++ b/aitrainer_backoffice/aitrainer_backoffice/models/evaluation.py @@ -48,11 +48,13 @@ class EvaluationAttribute(models.Model): verbose_name=_("evaluation_text")) suggestion = models.TextField(max_length=1000, blank=True, null=True, help_text="English suggestion here", verbose_name=_("suggestion")) + sort = models.IntegerField() class Meta: db_table = 'evaluation_attribute' verbose_name = _("Evaluation Table") verbose_name_plural = _("Evaluation Tables") + ordering = ['sort'] def __str__(self): return self.name \ No newline at end of file diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/deploy.py b/aitrainer_backoffice/aitrainer_backoffice/settings/deploy.py index b06f115..0d634a8 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/settings/deploy.py +++ b/aitrainer_backoffice/aitrainer_backoffice/settings/deploy.py @@ -1,7 +1,7 @@ import os from firebase_admin import initialize_app -BACKOFFICE_VERSION = "1.30" +BACKOFFICE_VERSION = "1.31" # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -9,16 +9,18 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')] # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.environ['DJANGO_KEY'] +SECRET_KEY = "lkasdjhklj84ujn3jk4nr5j43njk" #os.environ['DJANGO_KEY'] +GOOGLE_APPLICATION_CREDENTIALS="/aitrainer_backoffice/aitrainer_backoffice/aitrainer_backoffice/asset/aitrainer-firebase-adminsdk.json" os.environ["WORKOUTTEST_SETTING"] = "DEPLOY" + # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False ALLOWED_HOSTS = ['62.171.188.119', "admin.aitrainer.app"] -env = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] +#env = os.environ['GOOGLE_APPLICATION_CREDENTIALS'] FIREBASE_APP = initialize_app() DEFAULT_AUTO_FIELD='django.db.models.AutoField' diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py b/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py index 2fe18ae..1d9addd 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py +++ b/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py @@ -1,7 +1,7 @@ import os from firebase_admin import initialize_app -BACKOFFICE_VERSION = "1.30" +BACKOFFICE_VERSION = "1.31" # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py index e7746f1..d369ac7 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py +++ b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py @@ -1,7 +1,7 @@ import os from firebase_admin import initialize_app -BACKOFFICE_VERSION = "1.30" +BACKOFFICE_VERSION = "1.31" # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) diff --git a/aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/stacked.html b/aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/stacked.html new file mode 100644 index 0000000..8f0ae56 --- /dev/null +++ b/aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/stacked.html @@ -0,0 +1,30 @@ +{% load i18n admin_urls static %} +
+
+ {% if inline_admin_formset.formset.max_num == 1 %} +

{{ inline_admin_formset.opts.verbose_name|capfirst }}

+ {% else %} +

{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}

+ {% endif %} +{{ inline_admin_formset.formset.management_form }} +{{ inline_admin_formset.formset.non_form_errors }} +

-- Actions Inline --

+ +{% for inline_admin_form in inline_admin_formset %}
+

{{ inline_admin_formset.opts.verbose_name|capfirst }}: {% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} {% if inline_admin_formset.has_change_permission %}{% translate "Change" %}{% else %}{% translate "View" %}{% endif %}{% endif %} +{% else %}#{{ forloop.counter }}{% endif %} + {% if inline_admin_form.show_url %}{% translate "View on site" %}{% endif %} + {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission and inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}{% endif %} +

+ {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %} + {% for fieldset in inline_admin_form %} + {% include "admin/includes/fieldset.html" %} + {% endfor %} + {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %} + {% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %} +
{% endfor %} +
+
diff --git a/aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/tabular.html b/aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/tabular.html new file mode 100644 index 0000000..48e155e --- /dev/null +++ b/aitrainer_backoffice/aitrainer_backoffice/templates/admin/edit_inline/tabular.html @@ -0,0 +1,84 @@ +{% load i18n admin_urls static admin_modify %} +
+ +
+ + +
diff --git a/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html b/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html index 4a7e824..b84e44a 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html +++ b/aitrainer_backoffice/aitrainer_backoffice/templates/controlling/mautic.html @@ -7,6 +7,13 @@ +
+
+ {% csrf_token %} + +
+
+
{{ block.super }} {% endblock %} \ No newline at end of file diff --git a/aitrainer_backoffice/controlling/admin/customer.py b/aitrainer_backoffice/controlling/admin/customer.py index a8aa9f9..2c08773 100644 --- a/aitrainer_backoffice/controlling/admin/customer.py +++ b/aitrainer_backoffice/controlling/admin/customer.py @@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _ from django.contrib import admin from rangefilter.filters import DateRangeFilter, DateTimeRangeFilter from django.urls import path +from ..automation.mautic import Mautic SETTING = os.environ['WORKOUTTEST_SETTING'] if SETTING == "PROD" : @@ -76,14 +77,20 @@ class CustomerAdmin(admin.ModelAdmin): def get_urls(self): urls = super().get_urls() my_urls = [ - path('mautic/', self.set_mautic), + path('mautic/', self.run_mautic), + path('notif/', self.run_notif), ] return my_urls + urls - def set_mautic(self, request): + def run_notif(self, request): self.notif.run() return HttpResponseRedirect("../") + def run_mautic(self, request): + mautic = Mautic() + mautic.syncLang() + return HttpResponseRedirect("../") + admin.site.register(Customer, CustomerAdmin) admin.autodiscover() diff --git a/aitrainer_backoffice/controlling/automation/fcm.py b/aitrainer_backoffice/controlling/automation/fcm.py index fe59c78..ba571af 100644 --- a/aitrainer_backoffice/controlling/automation/fcm.py +++ b/aitrainer_backoffice/controlling/automation/fcm.py @@ -4,6 +4,7 @@ from firebase_admin import messaging, exceptions class FCM: logo_url = 'https://workouttest.com/wp-content/uploads/2020/10/WT_long_logo.png' + image_base = 'https://admin.aitrainer.app/media/images/' # default constructor def __init__(self): @@ -53,10 +54,11 @@ class FCM: if registration_token == None: return "Registration token is null" try: - notification_image_url = image_url + if image_url == None: notification_image_url = self.logo_url - #registration_token = 'cOqNt8rzo074gbIkBSpCgW:APA91bEBuNi3iVzGKb4JhxqN2j80MoJbNptLHk2qsdeKBQz5grpHtrPPXvDqn5BJVVSaj1nwGPwgN7pi6FIApog_TTP3g1yobgmgpPN6udrYgzILlVPMvdGGFDSDh6gKlczhlTL9NEp0' + else: + notification_image_url = self.image_base + '/' + image_url print(f'image: {notification_image_url}' ) diff --git a/aitrainer_backoffice/controlling/automation/mautic.py b/aitrainer_backoffice/controlling/automation/mautic.py index d4c332c..78c22ae 100644 --- a/aitrainer_backoffice/controlling/automation/mautic.py +++ b/aitrainer_backoffice/controlling/automation/mautic.py @@ -2,8 +2,13 @@ import requests import logging from django.db import connections import datetime +import os -from ..models.customer import Customer +SETTING = os.environ['WORKOUTTEST_SETTING'] +if SETTING == "PROD": + from aitrainer_backoffice.aitrainer_backoffice.models.customer import Customer +else: + from aitrainer_backoffice.models.customer import Customer class Mautic: @@ -13,6 +18,37 @@ class Mautic: qs = Customer.objects.raw( 'SELECT * from customer WHERE trial_date < "' + tenDays + '" and trial_date is not null') + def syncLang(self): + qs = Customer.objects.raw('SELECT * from customer WHERE lang is not null') + logger = logging.getLogger(__name__) + logger.info("Syncronising lang...") + + headers = { + 'content-type': "application/x-www-form-urlencoded", + 'cache-control': "no-cache" + } + index = 0 + for customer in qs: + data = "mauticform[email]=" + customer.email + \ + "&mauticform[database_id]=" + str(customer.customer_id) + \ + "&mauticform[lang]=" + str(customer.lang) + \ + "&mauticform[formId]=3" + \ + "&mauticform[formName]=appdatachange" + + print(data) + + form_url = 'https://mautic.aitrainer.app/form/submit?formId=3' + response = requests.post(form_url, data=data.encode('utf-8'), headers=headers) + print(customer.email + " " +str(response.status_code)) + + index = index + 1 + if index == 2: + break + + logger.info("Syncronised customer count: " + str(index)) + return True + + def sync(self): logger = logging.getLogger(__name__) logger.info("Syncronising...") diff --git a/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po b/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po index dfec580..16ac1c6 100644 --- a/aitrainer_backoffice/locale/hu/LC_MESSAGES/django.po +++ b/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-09-26 11:21+0200\n" +"POT-Creation-Date: 2021-10-17 10:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,40 +18,22 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: .\controlling\admin\customer.py:58 +#: .\controlling\admin\customer.py:65 msgid "Registered" msgstr "" -#: .\controlling\models\customer.py:16 -#: .\controlling\models\frequent_customers.py:9 -msgid "name" -msgstr "" - -#: .\controlling\models\customer.py:17 -#: .\controlling\models\frequent_customers.py:10 -msgid "firstname" -msgstr "" - -#: .\controlling\models\customer.py:33 -msgid "Customer" -msgstr "" - -#: .\controlling\models\customer.py:34 -msgid "Customers" -msgstr "" - -#: .\controlling\models\exercise_type.py:26 -msgid "Frequent Exercise" -msgstr "" - -#: .\controlling\models\exercise_type.py:27 -msgid "Frequent Exercises" -msgstr "" - -#: .\controlling\models\frequent_customers.py:26 +#: .\controlling\admin\frequent_customers.py:22 msgid "Frequent Customer" msgstr "" -#: .\controlling\models\frequent_customers.py:27 +#: .\controlling\admin\frequent_customers.py:23 msgid "Frequent Customers" msgstr "" + +#: .\controlling\admin\frequent_exercises.py:22 +msgid "Frequent Exercise" +msgstr "" + +#: .\controlling\admin\frequent_exercises.py:23 +msgid "Frequent Exercises" +msgstr "" diff --git a/cron.sh b/cron.sh index 46136d7..712c79f 100644 --- a/cron.sh +++ b/cron.sh @@ -1,2 +1,2 @@ -export $(cat .env | xargs) +export $(cat /aitrainer_backoffice.env | xargs) /usr/local/bin/python /aitrainer_backoffice/aitrainer_backoffice/manage.py runcrons --settings aitrainer_backoffice.settings.deploy >> /var/log/cronjob.log 2>&1 \ No newline at end of file