Djoser opé, API et envoie de mail lors d'une nouvelle inscription via l'api OK
This commit is contained in:
parent
58e1500991
commit
52b413b3a6
|
|
@ -1,7 +1,16 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
|
||||||
from django.contrib.admin import AdminSite
|
from django.contrib.admin import AdminSite
|
||||||
|
from django.contrib.auth.admin import UserAdmin, GroupAdmin
|
||||||
|
|
||||||
from Customers.models import Client, Domain
|
from Customers.models import Client, Domain
|
||||||
# Register your models here.
|
from AuthBillet.models import TibilletUser, HumanUser, TermUser, SuperHumanUser
|
||||||
|
from django.utils.translation import gettext, gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
# from boutique.models import Category, Product, Tag, VAT, Event, LandingPageContent, Billet
|
||||||
|
# from solo.admin import SingletonModelAdmin
|
||||||
|
|
||||||
class PublicAdminSite(AdminSite):
|
class PublicAdminSite(AdminSite):
|
||||||
site_header = "TiBillet Public Admin"
|
site_header = "TiBillet Public Admin"
|
||||||
|
|
@ -15,9 +24,99 @@ class PublicAdminSite(AdminSite):
|
||||||
public_admin_site = PublicAdminSite(name='public_admin')
|
public_admin_site = PublicAdminSite(name='public_admin')
|
||||||
|
|
||||||
|
|
||||||
|
# USER
|
||||||
|
# -------------------------------------/
|
||||||
|
|
||||||
|
class UserAdminTibillet(UserAdmin):
|
||||||
|
list_display = (
|
||||||
|
'email',
|
||||||
|
'is_active',
|
||||||
|
'is_staff',
|
||||||
|
'is_superuser',
|
||||||
|
'client_source',
|
||||||
|
'achat',
|
||||||
|
'administre',
|
||||||
|
'espece',
|
||||||
|
)
|
||||||
|
|
||||||
|
list_filter = (
|
||||||
|
'email',
|
||||||
|
'is_active',
|
||||||
|
'client_source',
|
||||||
|
'espece',
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
(None, {'fields': ('username', 'password')}),
|
||||||
|
(_('Personal info'), {
|
||||||
|
'fields': (
|
||||||
|
'first_name',
|
||||||
|
'last_name',
|
||||||
|
'email',
|
||||||
|
'client_source',
|
||||||
|
'client_admin',
|
||||||
|
'client_achat',
|
||||||
|
'offre',
|
||||||
|
)}),
|
||||||
|
(_('Permissions'), {
|
||||||
|
'fields': (
|
||||||
|
'is_active',
|
||||||
|
'is_staff',
|
||||||
|
'is_superuser',
|
||||||
|
'groups',
|
||||||
|
'user_permissions',
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
|
||||||
|
)
|
||||||
|
#
|
||||||
|
add_fieldsets = (
|
||||||
|
(None, {
|
||||||
|
'classes': ('wide',),
|
||||||
|
'fields': (
|
||||||
|
'email',
|
||||||
|
'password1',
|
||||||
|
'password2',
|
||||||
|
'is_active',
|
||||||
|
'client_source',
|
||||||
|
'client_achat',
|
||||||
|
'espece',
|
||||||
|
)}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
search_fields = ('email',)
|
||||||
|
ordering = ('email',)
|
||||||
|
|
||||||
|
# def save_model(self, request, obj, form, change):
|
||||||
|
# obj.client_source = request.tenant
|
||||||
|
# obj.save()
|
||||||
|
#
|
||||||
|
# staff_group = Group.objects.get_or_create(name="staff")[0]
|
||||||
|
# obj.groups.add(staff_group)
|
||||||
|
# obj.client_achat.add(request.tenant)
|
||||||
|
#
|
||||||
|
# super(UserAdminTibillet, self).save_model(request, obj, form, change)
|
||||||
|
|
||||||
|
|
||||||
|
public_admin_site.register(TibilletUser, UserAdminTibillet)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomGroupAdmin(GroupAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
public_admin_site.register(Group, CustomGroupAdmin)
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------/
|
||||||
|
# USER
|
||||||
|
# -------------------------------------/
|
||||||
|
|
||||||
class DomainInline(admin.TabularInline):
|
class DomainInline(admin.TabularInline):
|
||||||
model = Domain
|
model = Domain
|
||||||
|
|
||||||
|
|
||||||
class ClientAdmin(admin.ModelAdmin):
|
class ClientAdmin(admin.ModelAdmin):
|
||||||
inlines = [DomainInline]
|
inlines = [DomainInline]
|
||||||
list_display = (
|
list_display = (
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.admin import AdminSite
|
from django.contrib.admin import AdminSite
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
from solo.admin import SingletonModelAdmin
|
from solo.admin import SingletonModelAdmin
|
||||||
|
|
||||||
|
from AuthBillet.models import HumanUser, SuperHumanUser, TermUser
|
||||||
from BaseBillet.models import Configuration, Event, OptionGenerale
|
from BaseBillet.models import Configuration, Event, OptionGenerale
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
|
||||||
|
from Customers.models import Client
|
||||||
|
|
||||||
|
|
||||||
class StaffAdminSite(AdminSite):
|
class StaffAdminSite(AdminSite):
|
||||||
|
|
@ -11,12 +16,86 @@ class StaffAdminSite(AdminSite):
|
||||||
site_url = '/'
|
site_url = '/'
|
||||||
|
|
||||||
def has_permission(self, request):
|
def has_permission(self, request):
|
||||||
return request.user.is_superuser
|
"""
|
||||||
|
Removed check for is_staff.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if request.tenant in request.user.client_admin.all():
|
||||||
|
return request.user.is_staff
|
||||||
|
elif request.user.client_source == Client.objects.get(schema_name="public"):
|
||||||
|
return request.user.is_superuser
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except AttributeError:
|
||||||
|
# AttributeError: 'AnonymousUser' object has no attribute 'client_source'
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
staff_admin_site = StaffAdminSite(name='staff_admin')
|
staff_admin_site = StaffAdminSite(name='staff_admin')
|
||||||
|
|
||||||
|
|
||||||
|
# USER
|
||||||
|
# -------------------------------------/
|
||||||
|
class UserAdminTibillet(UserAdmin):
|
||||||
|
# list_display = ('email', 'client_source', 'achat')
|
||||||
|
list_display = ('email', 'is_active')
|
||||||
|
list_filter = ('email', 'is_active',)
|
||||||
|
fieldsets = (
|
||||||
|
(None, {'fields': ('email', 'password')}),
|
||||||
|
# ('Permissions', {'fields': ('is_staff', 'is_active')}),
|
||||||
|
)
|
||||||
|
|
||||||
|
add_fieldsets = (
|
||||||
|
(None, {
|
||||||
|
'classes': ('wide',),
|
||||||
|
'fields': ('email', 'password1', 'password2', 'is_active')}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
search_fields = ('email',)
|
||||||
|
ordering = ('email',)
|
||||||
|
|
||||||
|
def save_model(self, request, obj, form, change):
|
||||||
|
if not obj.client_source:
|
||||||
|
obj.client_source = request.tenant
|
||||||
|
obj.username = obj.email
|
||||||
|
obj.save()
|
||||||
|
obj.client_achat.add(request.tenant)
|
||||||
|
|
||||||
|
|
||||||
|
class HumanUserAdmin(UserAdminTibillet):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
staff_admin_site.register(HumanUser, HumanUserAdmin)
|
||||||
|
|
||||||
|
|
||||||
|
class SuperHumanUserAdmin(UserAdminTibillet):
|
||||||
|
def save_model(self, request, obj, form, change):
|
||||||
|
|
||||||
|
super(SuperHumanUserAdmin, self).save_model(request, obj, form, change)
|
||||||
|
|
||||||
|
staff_group = Group.objects.get_or_create(name="staff")[0]
|
||||||
|
obj.groups.add(staff_group)
|
||||||
|
obj.client_achat.add(request.tenant)
|
||||||
|
obj.client_admin.add(request.tenant)
|
||||||
|
|
||||||
|
# execution du save de la classe orginale user admin ( heritage de l'hérité )
|
||||||
|
super(UserAdminTibillet, self).save_model(request, obj, form, change)
|
||||||
|
|
||||||
|
|
||||||
|
staff_admin_site.register(SuperHumanUser, SuperHumanUserAdmin)
|
||||||
|
|
||||||
|
|
||||||
|
class TermUserAdmin(UserAdminTibillet):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
staff_admin_site.register(TermUser, TermUserAdmin)
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
from django.contrib.auth.tokens import default_token_generator
|
||||||
|
from rest_framework import serializers
|
||||||
|
from templated_mail.mail import BaseEmailMessage
|
||||||
|
|
||||||
|
from djoser import utils
|
||||||
|
from djoser.conf import settings
|
||||||
|
|
||||||
|
from BaseBillet.models import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
class ActivationEmail(BaseEmailMessage):
|
||||||
|
template_name = "email/activation.html"
|
||||||
|
|
||||||
|
def get_context_data(self):
|
||||||
|
# ActivationEmail can be deleted
|
||||||
|
print("activation !")
|
||||||
|
context = super().get_context_data()
|
||||||
|
# print(f"context : {context}")
|
||||||
|
# import ipdb; ipdb.set_trace()
|
||||||
|
|
||||||
|
user = context.get("user")
|
||||||
|
context["site_name"] = self.request.tenant.name
|
||||||
|
context["domain"] = self.request.tenant.domain_url
|
||||||
|
context["uid"] = utils.encode_uid(user.pk)
|
||||||
|
context["token"] = default_token_generator.make_token(user)
|
||||||
|
context["url"] = settings.ACTIVATION_URL.format(**context)
|
||||||
|
print(f"context : {context}")
|
||||||
|
return context
|
||||||
|
|
||||||
|
def send(self, to, *args, **kwargs):
|
||||||
|
configuration = Configuration.get_solo()
|
||||||
|
if not configuration.email :
|
||||||
|
return serializers.ValidationError(_(f"Manque l'email de la structure. Merci de configurer votre instance."))
|
||||||
|
|
||||||
|
self.render()
|
||||||
|
|
||||||
|
self.to = to
|
||||||
|
self.cc = kwargs.pop('cc', [])
|
||||||
|
self.bcc = kwargs.pop('bcc', [])
|
||||||
|
self.reply_to = kwargs.pop('reply_to', [])
|
||||||
|
self.from_email = kwargs.pop(
|
||||||
|
'from_email', configuration.email
|
||||||
|
)
|
||||||
|
|
||||||
|
# import ipdb; ipdb.set_trace()
|
||||||
|
mail_send = super(BaseEmailMessage, self).send(*args, **kwargs)
|
||||||
|
print(f'mail_send to {self.to} from {self.from_email} : {mail_send}')
|
||||||
|
|
||||||
|
|
||||||
|
class ConfirmationEmail(BaseEmailMessage):
|
||||||
|
template_name = "email/confirmation.html"
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordResetEmail(BaseEmailMessage):
|
||||||
|
template_name = "email/password_reset.html"
|
||||||
|
|
||||||
|
def get_context_data(self):
|
||||||
|
# PasswordResetEmail can be deleted
|
||||||
|
context = super().get_context_data()
|
||||||
|
|
||||||
|
user = context.get("user")
|
||||||
|
context["site_name"] = self.request.tenant.name
|
||||||
|
context["domain"] = self.request.tenant.domain_url
|
||||||
|
context["uid"] = utils.encode_uid(user.pk)
|
||||||
|
context["token"] = default_token_generator.make_token(user)
|
||||||
|
context["url"] = settings.PASSWORD_RESET_CONFIRM_URL.format(**context)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordChangedConfirmationEmail(BaseEmailMessage):
|
||||||
|
template_name = "email/password_changed_confirmation.html"
|
||||||
|
|
||||||
|
|
||||||
|
class UsernameChangedConfirmationEmail(BaseEmailMessage):
|
||||||
|
template_name = "email/username_changed_confirmation.html"
|
||||||
|
|
||||||
|
|
||||||
|
class UsernameResetEmail(BaseEmailMessage):
|
||||||
|
template_name = "email/username_reset.html"
|
||||||
|
|
||||||
|
def get_context_data(self):
|
||||||
|
context = super().get_context_data()
|
||||||
|
|
||||||
|
user = context.get("user")
|
||||||
|
context["site_name"] = self.request.tenant.name
|
||||||
|
context["domain"] = self.request.tenant.domain_url
|
||||||
|
context["uid"] = utils.encode_uid(user.pk)
|
||||||
|
context["token"] = default_token_generator.make_token(user)
|
||||||
|
context["url"] = settings.USERNAME_RESET_CONFIRM_URL.format(**context)
|
||||||
|
return context
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
# Generated by Django 2.2 on 2021-06-23 09:09
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('auth', '0011_update_proxy_permissions'),
|
||||||
|
('Customers', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TibilletUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||||
|
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||||
|
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||||
|
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
|
||||||
|
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||||
|
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||||
|
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||||
|
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||||
|
('email', models.EmailField(max_length=254, unique=True, verbose_name='email')),
|
||||||
|
('username', models.CharField(blank=True, max_length=200, null=True)),
|
||||||
|
('espece', models.CharField(choices=[('TE', 'Terminal'), ('AN', 'Android'), ('HU', 'Humain')], default='HU', max_length=2)),
|
||||||
|
('offre', models.CharField(choices=[('PU', 'Public'), ('FR', 'Gratuit'), ('PR', 'Premium'), ('EN', 'Entreprise'), ('CU', 'Custom')], default='PU', max_length=2)),
|
||||||
|
('client_achat', models.ManyToManyField(blank=True, related_name='user_achats', to='Customers.Client')),
|
||||||
|
('client_admin', models.ManyToManyField(blank=True, related_name='user_admin', to='Customers.Client')),
|
||||||
|
('client_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='user_principal', to='Customers.Client', verbose_name='Inscription depuis')),
|
||||||
|
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
|
||||||
|
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'user',
|
||||||
|
'verbose_name_plural': 'users',
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='HumanUser',
|
||||||
|
fields=[
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Utilisateur',
|
||||||
|
'proxy': True,
|
||||||
|
'indexes': [],
|
||||||
|
'constraints': [],
|
||||||
|
},
|
||||||
|
bases=('AuthBillet.tibilletuser',),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SuperHumanUser',
|
||||||
|
fields=[
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Administrateur',
|
||||||
|
'proxy': True,
|
||||||
|
'indexes': [],
|
||||||
|
'constraints': [],
|
||||||
|
},
|
||||||
|
bases=('AuthBillet.tibilletuser',),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TermUser',
|
||||||
|
fields=[
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Terminal',
|
||||||
|
'verbose_name_plural': 'Terminaux',
|
||||||
|
'proxy': True,
|
||||||
|
'indexes': [],
|
||||||
|
'constraints': [],
|
||||||
|
},
|
||||||
|
bases=('AuthBillet.tibilletuser',),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -1,3 +1,222 @@
|
||||||
|
from django.contrib.auth.base_user import BaseUserManager, AbstractBaseUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
import uuid
|
||||||
|
from django.contrib.auth.models import AbstractUser, Group, Permission
|
||||||
|
from Customers.models import Client
|
||||||
|
from django.db import connection
|
||||||
|
|
||||||
# Create your models here.
|
|
||||||
|
class TibilletManager(BaseUserManager):
|
||||||
|
def _create_user(self, email, password, **extra_fields):
|
||||||
|
# import ipdb; ipdb.set_trace()
|
||||||
|
if not email:
|
||||||
|
raise ValueError(_("email obligatoire"))
|
||||||
|
|
||||||
|
email = self.normalize_email(email)
|
||||||
|
user = self.model(username=email, email=email, **extra_fields)
|
||||||
|
user.set_password(password)
|
||||||
|
|
||||||
|
user.client_source = connection.tenant
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
user.client_achat.add(connection.tenant)
|
||||||
|
return user
|
||||||
|
|
||||||
|
def create_user(self, email, password, **extra_fields):
|
||||||
|
extra_fields.setdefault('is_staff', False)
|
||||||
|
extra_fields.setdefault('is_superuser', False)
|
||||||
|
return self._create_user(email, password, **extra_fields)
|
||||||
|
|
||||||
|
def create_staffuser(self, email, password, **extra_fields):
|
||||||
|
extra_fields.setdefault('is_staff', True)
|
||||||
|
extra_fields.setdefault('is_superuser', False)
|
||||||
|
return self.set_permission_staff(self._create_user(email, password, **extra_fields))
|
||||||
|
|
||||||
|
def create_superuser(self, email, password, **extra_fields):
|
||||||
|
extra_fields.setdefault('is_staff', True)
|
||||||
|
extra_fields.setdefault('is_superuser', True)
|
||||||
|
return self._create_user(email, password, **extra_fields)
|
||||||
|
|
||||||
|
def set_permission_staff(self, user):
|
||||||
|
staff_group = Group.objects.get_or_create(name="staff")[0]
|
||||||
|
user.groups.add(staff_group)
|
||||||
|
|
||||||
|
|
||||||
|
class TibilletUser(AbstractUser):
|
||||||
|
|
||||||
|
#TODO regarder du coté du dashboard de jet, ça plante avec uuid !
|
||||||
|
# uuid_user = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
|
||||||
|
|
||||||
|
USERNAME_FIELD = 'email'
|
||||||
|
REQUIRED_FIELDS = [] # removes email from REQUIRED_FIELDS
|
||||||
|
|
||||||
|
email = models.EmailField(_('email'), unique=True) # changes email to unique and blank to false
|
||||||
|
username = models.CharField(max_length=200, null=True, blank=True)
|
||||||
|
|
||||||
|
TYPE_TERM, TYPE_HUM, TYPE_ANDR = 'TE', 'HU', 'AN'
|
||||||
|
ESPECE_CHOICES = (
|
||||||
|
(TYPE_TERM, 'Terminal'),
|
||||||
|
(TYPE_ANDR, 'Android'),
|
||||||
|
(TYPE_HUM, 'Humain'),
|
||||||
|
)
|
||||||
|
|
||||||
|
espece = models.CharField(max_length=2,
|
||||||
|
choices=ESPECE_CHOICES,
|
||||||
|
default=TYPE_HUM)
|
||||||
|
|
||||||
|
PUBLIC, FREE, PREMIUM, ENTREPRISE, CUSTOM = 'PU', 'FR', 'PR', 'EN', 'CU'
|
||||||
|
OFFRE_CHOICES = (
|
||||||
|
(PUBLIC, 'Public'),
|
||||||
|
(FREE, 'Gratuit'),
|
||||||
|
(PREMIUM, 'Premium'),
|
||||||
|
(ENTREPRISE, 'Entreprise'),
|
||||||
|
(CUSTOM, 'Custom'),
|
||||||
|
)
|
||||||
|
|
||||||
|
offre = models.CharField(max_length=2,
|
||||||
|
choices=OFFRE_CHOICES,
|
||||||
|
default=PUBLIC)
|
||||||
|
|
||||||
|
# Inscription depuis :
|
||||||
|
client_source = models.ForeignKey(Client,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("Inscription depuis"),
|
||||||
|
related_name="user_principal",
|
||||||
|
)
|
||||||
|
|
||||||
|
# ou as t il acheté ?
|
||||||
|
client_achat = models.ManyToManyField(Client,
|
||||||
|
related_name="user_achats", blank=True)
|
||||||
|
|
||||||
|
# sur quelle interface d'admin peut il aller ?
|
||||||
|
client_admin = models.ManyToManyField(Client,
|
||||||
|
related_name="user_admin", blank=True)
|
||||||
|
|
||||||
|
objects = TibilletManager()
|
||||||
|
|
||||||
|
def achat(self):
|
||||||
|
return " ".join([achat["schema_name"] for achat in self.client_achat.values("schema_name")])
|
||||||
|
|
||||||
|
def administre(self):
|
||||||
|
return " ".join([admin["schema_name"] for admin in self.client_admin.values("schema_name")])
|
||||||
|
|
||||||
|
def new_tenant_authorised(self):
|
||||||
|
|
||||||
|
# si l'user est déja staff ou root, c'est qu'il a déja une billetterie.
|
||||||
|
if self.offre in [self.PUBLIC, self.FREE, self.PREMIUM]:
|
||||||
|
if len(self.client_admin.all()) > 0:
|
||||||
|
# superuser peut toujours.
|
||||||
|
return self.is_superuser
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif self.offre == self.ENTREPRISE:
|
||||||
|
if len(self.client_admin.all()) > 4:
|
||||||
|
# superuser peut toujours.
|
||||||
|
return self.is_superuser
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif self.offre == self.CUSTOM:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def set_staff(self, tenant):
|
||||||
|
self.client_admin.add(tenant)
|
||||||
|
self.is_staff = True
|
||||||
|
self.groups.add(Group.objects.get(name="staff"))
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class TermUserManager(TibilletManager):
|
||||||
|
def get_queryset(self):
|
||||||
|
return super().get_queryset().filter(espece=TibilletUser.TYPE_TERM,
|
||||||
|
client_source=connection.tenant,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TermUser(TibilletUser):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
verbose_name = "Terminal"
|
||||||
|
verbose_name_plural = "Terminaux"
|
||||||
|
|
||||||
|
objects = TermUserManager()
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
# Si création :
|
||||||
|
if not self.pk:
|
||||||
|
self.espece = TibilletUser.TYPE_TERM
|
||||||
|
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class HumanUserManager(TibilletManager):
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return super().get_queryset().filter(espece=TibilletUser.TYPE_HUM,
|
||||||
|
is_staff=False,
|
||||||
|
is_superuser=False,
|
||||||
|
client_achat__id__in=[connection.tenant.id, ],
|
||||||
|
)
|
||||||
|
# .distinct() ???
|
||||||
|
|
||||||
|
|
||||||
|
class HumanUser(TibilletUser):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
verbose_name = "Utilisateur"
|
||||||
|
|
||||||
|
objects = HumanUserManager()
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
# Si création :
|
||||||
|
if not self.pk:
|
||||||
|
self.espece = TibilletUser.TYPE_HUM
|
||||||
|
|
||||||
|
self.is_staff = False
|
||||||
|
self.is_superuser = False
|
||||||
|
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class SuperHumanUserManager(TibilletManager):
|
||||||
|
def get_queryset(self):
|
||||||
|
return super().get_queryset().filter(
|
||||||
|
espece=TibilletUser.TYPE_HUM,
|
||||||
|
is_staff=True,
|
||||||
|
is_superuser=False,
|
||||||
|
client_admin__id__in=[connection.tenant.id, ],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SuperHumanUser(TibilletUser):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
verbose_name = "Administrateur"
|
||||||
|
|
||||||
|
objects = SuperHumanUserManager()
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
# import ipdb; ipdb.set_trace()
|
||||||
|
# Si création :
|
||||||
|
if not self.pk:
|
||||||
|
self.espece = TibilletUser.TYPE_HUM
|
||||||
|
|
||||||
|
self.is_staff = True
|
||||||
|
self.is_superuser = False
|
||||||
|
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{% blocktrans %}Account activation on {{ site_name }}{% endblocktrans %}
|
||||||
|
{% endblock subject %}
|
||||||
|
|
||||||
|
{% block text_body %}
|
||||||
|
{% blocktrans %}You're receiving this email because you need to finish activation process on {{ site_name }}.{% endblocktrans %}
|
||||||
|
|
||||||
|
{% trans "Please go to the following page to activate account:" %}
|
||||||
|
{{ protocol }}://{{ domain }}/{{ url|safe }}
|
||||||
|
|
||||||
|
{% trans "Thanks for using our site!" %}
|
||||||
|
|
||||||
|
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||||
|
{% endblock text_body %}
|
||||||
|
|
||||||
|
{% block html_body %}
|
||||||
|
<p>{% blocktrans %}You're receiving this email because you need to finish activation process on {{ site_name }}.{% endblocktrans %}</p>
|
||||||
|
|
||||||
|
<p>{% trans "Please go to the following page to activate account:" %}</p>
|
||||||
|
<p><a href="{{ protocol }}://{{ domain }}/{{ url|safe }}">{{ protocol }}://{{ domain }}/{{ url|safe }}</a></p>
|
||||||
|
|
||||||
|
<p>{% trans "Thanks for using our site!" %}</p>
|
||||||
|
|
||||||
|
<p>{% blocktrans %}The {{ site_name }} team{% endblocktrans %}</p>
|
||||||
|
|
||||||
|
{% endblock html_body %}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{% blocktrans %}{{ site_name }} - Your account has been successfully created and activated!{% endblocktrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block text_body %}
|
||||||
|
{% trans "Your account has been created and is ready to use!" %}
|
||||||
|
|
||||||
|
{% trans "Thanks for using our site!" %}
|
||||||
|
|
||||||
|
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||||
|
{% endblock text_body %}
|
||||||
|
|
||||||
|
{% block html_body %}
|
||||||
|
<p>{% trans "Your account has been created and is ready to use!" %}</p>
|
||||||
|
|
||||||
|
<p>{% trans "Thanks for using our site!" %}</p>
|
||||||
|
|
||||||
|
<p>{% blocktrans %}The {{ site_name }} team{% endblocktrans %}</p>
|
||||||
|
{% endblock html_body %}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{% blocktrans %}{{ site_name }} - Your password has been successfully changed!{% endblocktrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block text_body %}
|
||||||
|
{% trans "Your password has been changed!" %}
|
||||||
|
|
||||||
|
{% trans "Thanks for using our site!" %}
|
||||||
|
|
||||||
|
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||||
|
{% endblock text_body %}
|
||||||
|
|
||||||
|
{% block html_body %}
|
||||||
|
<p>{% trans "Your password has been changed!" %}</p>
|
||||||
|
|
||||||
|
<p>{% trans "Thanks for using our site!" %}</p>
|
||||||
|
|
||||||
|
<p>{% blocktrans %}The {{ site_name }} team{% endblocktrans %}</p>
|
||||||
|
{% endblock html_body %}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{% blocktrans %}Password reset on {{ site_name }}{% endblocktrans %}
|
||||||
|
{% endblock subject %}
|
||||||
|
|
||||||
|
{% block text_body %}
|
||||||
|
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
|
||||||
|
|
||||||
|
{% trans "Please go to the following page and choose a new password:" %}
|
||||||
|
{{ protocol }}://{{ domain }}/{{ url }}
|
||||||
|
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
|
||||||
|
|
||||||
|
{% trans "Thanks for using our site!" %}
|
||||||
|
|
||||||
|
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||||
|
{% endblock text_body %}
|
||||||
|
|
||||||
|
{% block html_body %}
|
||||||
|
<p>{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}</p>
|
||||||
|
|
||||||
|
<p>{% trans "Please go to the following page and choose a new password:" %}</p>
|
||||||
|
<a href="{{ protocol }}://{{ domain }}/{{ url }}">{{ protocol }}://{{ domain }}/{{ url }}</a>
|
||||||
|
<p>{% trans "Your username, in case you've forgotten:" %} <b>{{ user.get_username }}</b></p>
|
||||||
|
|
||||||
|
<p>{% trans "Thanks for using our site!" %}</p>
|
||||||
|
|
||||||
|
<p>{% blocktrans %}The {{ site_name }} team{% endblocktrans %}</p>
|
||||||
|
{% endblock html_body %}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{% blocktrans %}{{ site_name }} - Your username has been successfully changed!{% endblocktrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block text_body %}
|
||||||
|
{% trans "Your username has been changed!" %}
|
||||||
|
|
||||||
|
{% trans "Thanks for using our site!" %}
|
||||||
|
|
||||||
|
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||||
|
{% endblock text_body %}
|
||||||
|
|
||||||
|
{% block html_body %}
|
||||||
|
<p>{% trans "Your username has been changed!" %}</p>
|
||||||
|
|
||||||
|
<p>{% trans "Thanks for using our site!" %}</p>
|
||||||
|
|
||||||
|
<p>{% blocktrans %}The {{ site_name }} team{% endblocktrans %}</p>
|
||||||
|
{% endblock html_body %}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{% blocktrans %}Username reset on {{ site_name }}{% endblocktrans %}
|
||||||
|
{% endblock subject %}
|
||||||
|
|
||||||
|
{% block text_body %}
|
||||||
|
{% blocktrans %}You're receiving this email because you requested a username reset for your user account at {{ site_name }}.{% endblocktrans %}
|
||||||
|
|
||||||
|
{% trans "Please go to the following page and choose a new username:" %}
|
||||||
|
{{ protocol }}://{{ domain }}/{{ url }}
|
||||||
|
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
|
||||||
|
|
||||||
|
{% trans "Thanks for using our site!" %}
|
||||||
|
|
||||||
|
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||||
|
{% endblock text_body %}
|
||||||
|
|
||||||
|
{% block html_body %}
|
||||||
|
<p>{% blocktrans %}You're receiving this email because you requested a username reset for your user account at {{ site_name }}.{% endblocktrans %}</p>
|
||||||
|
|
||||||
|
<p>{% trans "Please go to the following page and choose a new username:" %}</p>
|
||||||
|
<a href="{{ protocol }}://{{ domain }}/{{ url }}">{{ protocol }}://{{ domain }}/{{ url }}</a>
|
||||||
|
<p>{% trans "Your username, in case you've forgotten:" %} <b>{{ user.get_username }}</b></p>
|
||||||
|
|
||||||
|
<p>{% trans "Thanks for using our site!" %}</p>
|
||||||
|
|
||||||
|
<p>{% blocktrans %}The {{ site_name }} team{% endblocktrans %}</p>
|
||||||
|
{% endblock html_body %}
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
# Generated by Django 2.2 on 2021-06-21 14:58
|
# Generated by Django 2.2 on 2021-06-23 09:09
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import stdimage.models
|
||||||
|
import stdimage.validators
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
@ -11,12 +14,63 @@ class Migration(migrations.Migration):
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Event',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
('short_description', models.CharField(max_length=250)),
|
||||||
|
('long_description', models.TextField(blank=True, null=True)),
|
||||||
|
('datetime', models.DateTimeField()),
|
||||||
|
('img', stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)])),
|
||||||
|
('reservations', models.PositiveSmallIntegerField(default=0)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Evenement',
|
||||||
|
'verbose_name_plural': 'Evenements',
|
||||||
|
'ordering': ('datetime',),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='OptionGenerale',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=30)),
|
||||||
|
('poids', models.PositiveSmallIntegerField(default=0, verbose_name='Poids')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Options Generales',
|
||||||
|
'verbose_name_plural': 'Options Generales',
|
||||||
|
'ordering': ('poids',),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='reservation',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('status', models.CharField(choices=[('NAN', 'Annulée'), ('NOV', 'Email non validé'), ('VAL', 'Validée'), ('PAY', 'Payée')], default='NOV', max_length=3, verbose_name='Status de la réservation')),
|
||||||
|
('qty', models.IntegerField()),
|
||||||
|
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservation', to='BaseBillet.Event')),
|
||||||
|
],
|
||||||
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Configuration',
|
name='Configuration',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('organisation', models.CharField(max_length=50)),
|
('organisation', models.CharField(max_length=50)),
|
||||||
('short_description', models.CharField(max_length=250)),
|
('short_description', models.CharField(max_length=250)),
|
||||||
|
('adresse', models.CharField(max_length=250)),
|
||||||
|
('phone', models.CharField(max_length=20)),
|
||||||
|
('email', models.EmailField(max_length=254)),
|
||||||
|
('twitter', models.URLField(blank=True, null=True)),
|
||||||
|
('facebook', models.URLField(blank=True, null=True)),
|
||||||
|
('instagram', models.URLField(blank=True, null=True)),
|
||||||
|
('img', stdimage.models.StdImageField(blank=True, null=True, upload_to='images/')),
|
||||||
|
('mollie_api_key', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('reservation_par_user_max', models.PositiveSmallIntegerField(default=6)),
|
||||||
|
('jauge_max', models.PositiveSmallIntegerField(default=50)),
|
||||||
|
('option_generale_checkbox', models.ManyToManyField(blank=True, related_name='checkbox', to='BaseBillet.OptionGenerale')),
|
||||||
|
('option_generale_radio', models.ManyToManyField(blank=True, related_name='radiobutton', to='BaseBillet.OptionGenerale')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-21 15:26
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='facebook',
|
|
||||||
field=models.URLField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='instagram',
|
|
||||||
field=models.URLField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='twitter',
|
|
||||||
field=models.URLField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-21 15:36
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0002_auto_20210621_1926'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Event',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(max_length=200)),
|
|
||||||
('short_description', models.CharField(max_length=250)),
|
|
||||||
('long_description', models.TextField(blank=True, null=True)),
|
|
||||||
('datetime', models.DateTimeField()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-21 16:59
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0003_event'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterModelOptions(
|
|
||||||
name='event',
|
|
||||||
options={'ordering': ('datetime',), 'verbose_name': 'Evenement', 'verbose_name_plural': 'Evenements'},
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='adresse',
|
|
||||||
field=models.CharField(default='route de la joie', max_length=250),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='email',
|
|
||||||
field=models.EmailField(default='demo@demo.demo', max_length=254),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='phone',
|
|
||||||
field=models.CharField(default='-262 6 121212', max_length=20),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-21 17:19
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
import stdimage.models
|
|
||||||
import stdimage.validators
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0004_auto_20210621_2059'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='img',
|
|
||||||
field=stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)]),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='event',
|
|
||||||
name='img',
|
|
||||||
field=stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)]),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-22 06:53
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0005_auto_20210621_2119'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='mollie_api_key',
|
|
||||||
field=models.CharField(blank=True, max_length=50, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='reservation_max',
|
|
||||||
field=models.PositiveSmallIntegerField(default=6),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-22 07:03
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0006_auto_20210622_1053'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='configuration',
|
|
||||||
old_name='reservation_max',
|
|
||||||
new_name='reservation_par_user_max',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='jauge_max',
|
|
||||||
field=models.PositiveSmallIntegerField(default=50),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-22 07:05
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0007_auto_20210622_1103'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='event',
|
|
||||||
name='reservations',
|
|
||||||
field=models.PositiveSmallIntegerField(default=6),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-22 07:39
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0008_event_reservations'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='OptionGenerale',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(max_length=30)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='event',
|
|
||||||
name='reservations',
|
|
||||||
field=models.PositiveSmallIntegerField(default=0),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='option_generale_checkbox',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='checkbox', to='BaseBillet.OptionGenerale'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='option_generale_radio',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='radiobutton', to='BaseBillet.OptionGenerale'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-22 07:49
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0009_auto_20210622_1139'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterModelOptions(
|
|
||||||
name='optiongenerale',
|
|
||||||
options={'ordering': ('poids',), 'verbose_name': 'Options Generales', 'verbose_name_plural': 'Options Generales'},
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='optiongenerale',
|
|
||||||
name='poids',
|
|
||||||
field=models.PositiveSmallIntegerField(default=0, verbose_name='Poids'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-22 09:22
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0010_auto_20210622_1149'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='reservation',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('status', models.CharField(choices=[('NAN', 'Annulée'), ('NOV', 'Email non validé'), ('VAL', 'Validée'), ('PAY', 'Payée')], default='NOV', max_length=3, verbose_name='Status de la réservation')),
|
|
||||||
('qty', models.IntegerField()),
|
|
||||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservation', to='BaseBillet.Event')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-23 06:21
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0011_reservation'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='jauge_max',
|
|
||||||
field=models.PositiveSmallIntegerField(default=50),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 2.2 on 2021-06-23 06:25
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
import stdimage.models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BaseBillet', '0012_auto_20210623_1021'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='configuration',
|
|
||||||
name='img',
|
|
||||||
field=stdimage.models.StdImageField(blank=True, null=True, upload_to='images/'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -53,7 +53,8 @@ class Configuration(SingletonModel):
|
||||||
'med': (480, 480),
|
'med': (480, 480),
|
||||||
'thumbnail': (150, 90),
|
'thumbnail': (150, 90),
|
||||||
},
|
},
|
||||||
delete_orphans=True
|
delete_orphans=True,
|
||||||
|
verbose_name='Background'
|
||||||
)
|
)
|
||||||
|
|
||||||
mollie_api_key = models.CharField(max_length=50,
|
mollie_api_key = models.CharField(max_length=50,
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,12 @@
|
||||||
<!-- Post -->
|
<!-- Post -->
|
||||||
<section class="post">
|
<section class="post">
|
||||||
<header class="major">
|
<header class="major">
|
||||||
<span class="date">{{ event.datetime | date:"d F Y"}}<br/>{{ event.datetime | time }}</span>
|
<span class="date">{{ event.datetime | date:"d F Y" }}<br/>{{ event.datetime | time }}</span>
|
||||||
<h1>{{ event.name }}</h1>
|
<h1>{{ event.name }}</h1>
|
||||||
<p>{{ event.short_description }}</p>
|
<p>{{ event.short_description }}</p>
|
||||||
</header>
|
</header>
|
||||||
<div class="image main"><img src="/media/{{ event.img.fhd }}" alt=""/></div>
|
<div class="image main"><img src="/media/{{ event.img.fhd }}" alt=""/></div>
|
||||||
<p>{{ event.long_description | linebreaks}}</p>
|
<p>{{ event.long_description | linebreaks }}</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -79,7 +79,8 @@
|
||||||
<!-- Break -->
|
<!-- Break -->
|
||||||
{% for option_radio in configuration.option_generale_radio.all %}
|
{% for option_radio in configuration.option_generale_radio.all %}
|
||||||
<div class="col-4 col-12-small">
|
<div class="col-4 col-12-small">
|
||||||
<input type="radio" id="{{ option_radio.name }}" name="radio_generale" value="{{ option_radio.pk }}">
|
<input type="radio" id="{{ option_radio.name }}" name="radio_generale"
|
||||||
|
value="{{ option_radio.pk }}">
|
||||||
<label for="{{ option_radio.name }}">{{ option_radio.name }}</label>
|
<label for="{{ option_radio.name }}">{{ option_radio.name }}</label>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
@ -87,7 +88,8 @@
|
||||||
{% for option_checkbox in configuration.option_generale_checkbox.all %}
|
{% for option_checkbox in configuration.option_generale_checkbox.all %}
|
||||||
|
|
||||||
<div class="col-6 col-12-small">
|
<div class="col-6 col-12-small">
|
||||||
<input type="checkbox" id="{{ option_checkbox.name }}" name="{{ option_checkbox.name }}" value="{{ option_checkbox.pk }}">
|
<input type="checkbox" id="{{ option_checkbox.name }}" name="{{ option_checkbox.name }}"
|
||||||
|
value="{{ option_checkbox.pk }}">
|
||||||
<label for="{{ option_checkbox.name }}">{{ option_checkbox.name }}</label>
|
<label for="{{ option_checkbox.name }}">{{ option_checkbox.name }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -104,7 +106,7 @@
|
||||||
<li><input type="reset" value="Reset"/></li>
|
<li><input type="reset" value="Reset"/></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</brdiv>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2 on 2021-06-10 12:04
|
# Generated by Django 2.2 on 2021-06-23 09:09
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django_tenants.models import TenantMixin, DomainMixin
|
from django_tenants.models import TenantMixin, DomainMixin
|
||||||
|
|
||||||
class Client(TenantMixin):
|
class Client(TenantMixin):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100, unique=True, db_index=True)
|
||||||
paid_until = models.DateField()
|
paid_until = models.DateField(default=timezone.now)
|
||||||
on_trial = models.BooleanField()
|
on_trial = models.BooleanField(default=True)
|
||||||
created_on = models.DateField(auto_now_add=True)
|
created_on = models.DateField(auto_now_add=True)
|
||||||
|
|
||||||
# default true, schema will be automatically created and synced when it is saved
|
# default true, schema will be automatically created and synced when it is saved
|
||||||
auto_create_schema = True
|
auto_create_schema = True
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
class Domain(DomainMixin):
|
class Domain(DomainMixin):
|
||||||
pass
|
pass
|
||||||
|
|
@ -79,6 +79,7 @@ TENANT_DOMAIN_MODEL = "Customers.Domain" # app.Model
|
||||||
ROOT_URLCONF = 'TiBillet.urls_tenants'
|
ROOT_URLCONF = 'TiBillet.urls_tenants'
|
||||||
PUBLIC_SCHEMA_URLCONF = 'TiBillet.urls_public'
|
PUBLIC_SCHEMA_URLCONF = 'TiBillet.urls_public'
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
|
AUTH_USER_MODEL = 'AuthBillet.TibilletUser'
|
||||||
|
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|
@ -131,7 +132,6 @@ DATABASE_ROUTERS = (
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
# AUTH_USER_MODEL = 'AuthBillet.TibilletUser'
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
|
@ -158,6 +158,25 @@ REST_FRAMEWORK = {
|
||||||
SIMPLE_JWT = {
|
SIMPLE_JWT = {
|
||||||
'AUTH_HEADER_TYPES': ('JWT',),
|
'AUTH_HEADER_TYPES': ('JWT',),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DJOSER = {
|
||||||
|
"SEND_ACTIVATION_EMAIL": True,
|
||||||
|
"PASSWORD_CHANGED_EMAIL_CONFIRMATION": True,
|
||||||
|
"PASSWORD_RESET_CONFIRM_URL": "password/reset/confirm/{uid}/{token}",
|
||||||
|
"USERNAME_RESET_CONFIRM_URL": "username/reset/confirm/{uid}/{token}",
|
||||||
|
# "ACTIVATION_URL": "activate/{uid}/{token}",
|
||||||
|
"ACTIVATION_URL": "activate/{uid}/{token}",
|
||||||
|
# "SOCIAL_AUTH_ALLOWED_REDIRECT_URIS": ["http://manap.django-local.org:8002/"],
|
||||||
|
'EMAIL': {
|
||||||
|
'activation': 'AuthBillet.email.ActivationEmail',
|
||||||
|
'confirmation': 'AuthBillet.email.ConfirmationEmail',
|
||||||
|
'password_reset': 'AuthBillet.email.PasswordResetEmail',
|
||||||
|
'password_changed_confirmation': 'AuthBillet.email.PasswordChangedConfirmationEmail',
|
||||||
|
'username_changed_confirmation': 'AuthBillet.email.UsernameChangedConfirmationEmail',
|
||||||
|
'username_reset': 'AuthBillet.email.UsernameResetEmail',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ urlpatterns = [
|
||||||
|
|
||||||
re_path(r'^auth/', include('djoser.urls')),
|
re_path(r'^auth/', include('djoser.urls')),
|
||||||
re_path(r'^auth/', include('djoser.urls.authtoken')),
|
re_path(r'^auth/', include('djoser.urls.authtoken')),
|
||||||
|
re_path(r'^auth/', include('djoser.urls.jwt')),
|
||||||
|
|
||||||
path('', include('BaseBillet.urls')),
|
path('', include('BaseBillet.urls')),
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue