Compare commits

...

10 Commits

Author SHA1 Message Date
Tibor Bossanyi (Freelancer)
3d4a3ab1bb v1.38.4 2022-10-05 16:10:35 +02:00
Tibor Bossanyi (Freelancer)
7ddab1da09 v1.38.3 2022-10-05 15:47:59 +02:00
Tibor Bossanyi (Freelancer)
f7e7609bc3 v1.38.2 2022-10-05 07:33:36 +02:00
Tibor Bossanyi (Freelancer)
9c5b7f24a4 v1.38 2022-09-29 16:36:56 +02:00
Tibor Bossanyi (Freelancer)
604b636bc0 BO 1.37+2 exercisetype filter by exercise tree name 2022-04-20 16:05:18 +02:00
Tibor Bossanyi (Freelancer)
2a2844415d BO 1.37 next_training_plan 2022-04-15 14:26:50 +02:00
Tibor Bossanyi (Freelancer)
81e77e22c2 BO 1.36 mautic to workouttest.org 2022-02-16 00:18:36 +01:00
Tibor Bossanyi (Freelancer)
e696221a5b BO 1.35 webhook live db for purchase 2022-01-15 17:48:10 +01:00
Tibor Bossanyi (Freelancer)
c51106cca9 BP 1.35 webhook url fix 2022-01-15 17:25:04 +01:00
Tibor Bossanyi (Freelancer)
a7e0aecf6e BO 1.35+2 webhook payment 2022-01-15 17:08:39 +01:00
13 changed files with 305 additions and 38 deletions

View File

@ -50,7 +50,7 @@ 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')
list_filter = ('active','base', 'buddy_warning', 'exercisetypeparents__exercise_tree')
actions = ('clone',)
@admin.action(description=_('Clone exercise type'))

View File

@ -100,7 +100,7 @@ class TranslationTrainingPlanInline(admin.TabularInline):
class TrainingPlanAdmin( admin.ModelAdmin):
list_display = ('training_plan_id', 'name', 'internal_name', 'free', 'active')
fields = ('tree','training_program', 'name', 'description', 'internal_name', 'free', 'active', 'weeks')
fields = ('tree','training_program', 'name', 'description', 'internal_name', 'free', 'active', 'weeks', 'next_training_plan')
list_editable = ('name', 'internal_name', 'free', 'active')
def save_model(self, request, obj, form, change):
@ -142,8 +142,8 @@ class TrainingPlanAdmin( admin.ModelAdmin):
class TrainingPlanDetailAdmin(SortableAdminMixin, admin.ModelAdmin):
list_display = (
'sort', 'training_plan', 'exercise_type', 'set', 'repeats', 'max', 'weight', 'calc',
'resting_time', 'parallel', 'day')
'sort', 'training_plan', 'exercise_type', 'set', 'repeats', 'weight', 'max','calc',
'resting_time', 'parallel', 'day', 'ecto_repeats', 'ecto_weight', 'endo_repeats', 'endo_weight', 'round', 'round_group')
list_filter = ('training_plan__name', 'exercise_type__name')
list_editable = (
'exercise_type', 'set', 'repeats', 'weight', 'resting_time', 'parallel', 'day')

View File

@ -15,7 +15,7 @@ class TestRouter:
if self.cloning == True:
return 'live'
elif model._meta.app_label == 'controlling':
if model._meta.db_table == 'notification_history' or self.cloning == True:
if model._meta.db_table == 'notification_history' or model._meta.db_table == 'purchase' or self.cloning == True:
return 'live'
else:
raise Exception("This table cannot be changed!")

View File

@ -2,7 +2,6 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from ..models.sports import Sport
from ..models.exercises import Exercises
class Customer(models.Model):
customer_id = models.BigAutoField(primary_key=True)

View File

@ -2,12 +2,12 @@ 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):
class ProductTypes(models.TextChoices):
SUBS = "subscription"
IN_APP_CURR = "in-app-currency"
WEB = "web"
product_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
description = models.TextField(max_length=1000, blank=True, null=True)
@ -18,11 +18,13 @@ class Product(models.Model):
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)
price_web = 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")
app_label = 'controlling'
def __str__(self):
return self.name
@ -35,8 +37,13 @@ class Purchase(models.Model):
date_add = models.DateField(blank=True, null=True)
purchase_sum = models.DecimalField(decimal_places=2, max_digits=7)
currency = models.CharField(max_length=3)
expiring = models.DateField(blank=True, null=True)
class Meta:
db_table = 'purchase'
verbose_name = _("Purchase")
verbose_name_plural = _("Purchases")
verbose_name_plural = _("Purchases")
app_label = 'controlling'
def __str__(self):
return self.name

View File

@ -8,18 +8,30 @@ from ..models.training_plan_day import TrainingPlanDay
from ..models.training_program import TrainingProgram
class TrainingPlanNext(models.Model):
training_plan_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, help_text='The name of the training plan',
verbose_name=_("name"))
class Meta:
db_table = 'training_plan'
def __str__(self):
return self.name
class TrainingPlan(models.Model):
training_plan_id = models.AutoField(primary_key=True)
tree = models.ForeignKey(ExerciseTree,on_delete=models.CASCADE, limit_choices_to={'active':True})
training_program = models.ForeignKey(TrainingProgram, on_delete=models.CASCADE, blank=True,null=True)
name = models.CharField(max_length=100, help_text='The name of the training plan',
verbose_name=_("name"))
name = models.CharField(max_length=100, help_text='The name of the training plan', verbose_name=_("name"))
description = RichTextField(blank=True, null=True)
internal_name = models.CharField(max_length=50, blank=True, help_text='Only for programmers! "internal_name" format',
internal_name = models.CharField(max_length=50, blank=True, help_text='Only for programmers! "internal_name" format',
verbose_name=_("internal_name"))
free = models.BooleanField(blank=True)
active = models.BooleanField()
weeks = models.IntegerField(blank=True, null=True )
weeks = models.IntegerField(blank=True, null=True)
next_training_plan = models.ForeignKey(TrainingPlanNext, on_delete=models.CASCADE, blank=True, null=True)
class Meta:
db_table = 'training_plan'
@ -28,8 +40,8 @@ class TrainingPlan(models.Model):
def __str__(self):
return self.name
class TrainingPlanDetail(models.Model):
training_plan_detail_id = models.AutoField(primary_key=True)
training_plan = models.ForeignKey(TrainingPlan, on_delete=models.CASCADE)
@ -41,6 +53,12 @@ class TrainingPlanDetail(models.Model):
resting_time = models.IntegerField(blank=True)
parallel = models.BooleanField(blank=True)
day = models.ForeignKey(TrainingPlanDay, on_delete=models.CASCADE, blank=True,null=True)
ecto_repeats = models.IntegerField(blank=True)
ecto_weight = models.IntegerField(blank=True)
endo_repeats = models.IntegerField(blank=True)
endo_weight = models.IntegerField(blank=True)
round = models.IntegerField(blank=True)
round_group = models.CharField(max_length=2, default=LanguageTypes.HU)
class Meta:
db_table = 'training_plan_detail'

View File

@ -1,7 +1,7 @@
import os
from firebase_admin import initialize_app
BACKOFFICE_VERSION = "1.35"
BACKOFFICE_VERSION = "1.38"
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

View File

@ -1,7 +1,7 @@
import os
from firebase_admin import initialize_app
BACKOFFICE_VERSION = "1.35"
BACKOFFICE_VERSION = "1.38"
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

View File

@ -1,7 +1,7 @@
import os
from firebase_admin import initialize_app
BACKOFFICE_VERSION = "1.35"
BACKOFFICE_VERSION = "1.37"
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -14,17 +14,13 @@ SECRET_KEY = os.environ['DJANGO_KEY']
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['62.171.188.119', "admin.aitrainer.app",
'mail.aitrainer.info',
'aitrainer.info',
'www.aitrainer.info',
'aitrainer.app',
'www.aitrainer.app',
'www.workouttest.com',
ALLOWED_HOSTS = ['62.171.188.119',
'.aitrainer.info',
'.aitrainer.app',
'.workouttest.com',
'workouttest.com',
'www.workouttest.org',
'workouttest.org',
'git.aitrainer.app']
'.workouttest.org',
'andio.hu']
env = os.environ['GOOGLE_APPLICATION_CREDENTIALS']
FIREBASE_APP = initialize_app()

View File

@ -0,0 +1,194 @@
import os
from firebase_admin import initialize_app
BACKOFFICE_VERSION = "1.38.4"
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
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']
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['62.171.188.119',
'185.217.125.171',
'185.190.140.180',
'185.225.232.84',
'173.212.199.73',
'.aitrainer.info',
'.aitrainer.app',
'.workouttest.com',
'workouttest.com',
'.workouttest.org',
'andio.hu']
env = os.environ['GOOGLE_APPLICATION_CREDENTIALS']
FIREBASE_APP = initialize_app()
INSTALLED_APPS = [
'aitrainer_backoffice.aitrainer_backoffice',
'aitrainer_backoffice.controlling.apps.ControllingConfigLive',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ckeditor',
'ckeditor_uploader',
'django_admin_json_editor',
'rangefilter',
'adminsortable2',
'inline_actions',
'django_cron',
'firebase_admin',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'aitrainer_backoffice.aitrainer_backoffice.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'aitrainer_backoffice.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'aitrainer_test',
'USER': 'aitrainer',
'PASSWORD': 'andio2009',
'HOST': 'mariadb-galera.db.svc.cluster.local',
'PORT': 3307
},
'live': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'aitrainer',
'USER': 'aitrainer',
'PASSWORD': 'andio2009',
'HOST': 'mariadb-galera.db.svc.cluster.local',
'PORT': 3307
}
}
DATABASE_ROUTERS = ['aitrainer_backoffice.aitrainer_backoffice.db_router.TestRouter']
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'hu-HU'
TIME_ZONE = 'Europe/Budapest'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'aitrainer_backoffice/static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
CKEDITOR_UPLOAD_PATH = MEDIA_URL
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'ERROR',
'class': 'logging.FileHandler',
'filename': '/var/log/django_error.log',
},
'file2': {
'level': 'WARNING',
'class': 'logging.FileHandler',
'filename': '/var/log/django_error.log',
}
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 300,
'OPTIONS': {
'MAX_ENTRIES': 50000
}
}
}
# deployment settings
#SECURE_SSL_REDIRECT = False
#SESSION_COOKIE_SECURE = True
#CSRF_COOKIE_SECURE = True
CRON_CLASSES = [
'aitrainer_backoffice.controlling.cron.cron.NotificationJob',
]

View File

@ -20,7 +20,13 @@ 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 aitrainer_backoffice.views import webhook
import os
SETTING = os.environ['WORKOUTTEST_SETTING']
if SETTING == "PROD":
from aitrainer_backoffice.aitrainer_backoffice.views import webhook
else:
from aitrainer_backoffice.views import webhook
urlpatterns = [

View File

@ -1,8 +1,55 @@
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
import os
from datetime import date, timedelta, datetime
import pytz
SETTING = os.environ['WORKOUTTEST_SETTING']
if SETTING == "PROD":
from aitrainer_backoffice.aitrainer_backoffice.models.customer import Customer
from aitrainer_backoffice.aitrainer_backoffice.models.product import Product, Purchase
else:
from aitrainer_backoffice.models.customer import Customer
from aitrainer_backoffice.models.product import Product, Purchase
@csrf_exempt
def webhook(request):
if request.method == 'POST':
print("Data received from Webhook is: ", request.body)
return HttpResponse("Webhook received!")
json_object = json.loads(request.body)
if ( json_object['status'] == True ):
qs_customer = Customer.objects.filter(email = json_object['email'])
if ( qs_customer.count() > 0):
qs_product = Product.objects.filter(price_web = json_object['price'])
today = date.today()
cet = pytz.timezone('Europe/Budapest')
customer_id = qs_customer[0].customer_id
for product in qs_product:
expiring = date.today() + timedelta(days=1095)
if ( json_object['price'] == 26970):
qs_purchase = Purchase.objects.filter(customer_id = customer_id, product_id =product.pk)
if ( qs_purchase.count() < 2 ):
expiring = date.today() + timedelta(days=30)
print("insert purchase: " + product.name + " exp: " + str(expiring))
purchase = Purchase(
customer_id = qs_customer[0].customer_id,
product_id = product.pk,
date_add = datetime.now(tz=cet),
purchase_sum = product.price_web,
currency = "HUF",
expiring = expiring
)
purchase.save()
return HttpResponse("OK")

View File

@ -33,7 +33,7 @@ class Mautic:
print(data)
form_url = 'https://mautic.aitrainer.app/form/submit?formId=7'
form_url = 'https://mautic.workouttest.org/form/submit?formId=7'
response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
print(customer.email + " " +str(response.status_code))
@ -68,7 +68,7 @@ class Mautic:
print(data)
form_url = 'https://mautic.aitrainer.app/form/submit?formId=7'
form_url = 'https://mautic.workouttest.org/form/submit?formId=7'
response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
print(customer.email + " " +str(response.status_code))
@ -102,7 +102,7 @@ class Mautic:
print(data)
form_url = 'https://mautic.aitrainer.app/form/submit?formId=7'
form_url = 'https://mautic.workouttest.org/form/submit?formId=7'
response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
print(customer.email + " " +str(response.status_code))
@ -136,7 +136,7 @@ class Mautic:
print(data)
form_url = 'https://mautic.aitrainer.app/form/submit?formId=7'
form_url = 'https://mautic.workouttest.org/form/submit?formId=7'
response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
print(customer.email + " " +str(response.status_code))
@ -185,7 +185,7 @@ class Mautic:
print(data)
form_url = 'https://mautic.aitrainer.app/form/submit?formId=1'
form_url = 'https://mautic.workouttest.org/form/submit?formId=1'
response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
print(str(response.status_code))