refactor product, prices & event.

This commit is contained in:
Jonas 12t 2021-10-24 15:04:09 +04:00
parent 26dadfbb4f
commit cd80c74f90
16 changed files with 230 additions and 209 deletions

View File

@ -10,7 +10,7 @@ from django.utils.translation import gettext, gettext_lazy as _
from QrcodeCashless.models import Detail, CarteCashless
# from boutique.models import Category, Product, Tag, VAT, Event, LandingPageContent, TarifBillet
# from boutique.models import Category, Product, Tag, VAT, Event, LandingPageContent, Price
# from solo.admin import SingletonModelAdmin
class PublicAdminSite(AdminSite):

View File

@ -4,7 +4,7 @@ from django.contrib.auth.models import Group
from solo.admin import SingletonModelAdmin
from AuthBillet.models import HumanUser, SuperHumanUser, TermUser
from BaseBillet.models import Configuration, Event, OptionGenerale, Article, TarifBillet, Reservation, LigneArticle
from BaseBillet.models import Configuration, Event, OptionGenerale, Product, Price, Reservation, LigneArticle
from django.contrib.auth.admin import UserAdmin
from Customers.models import Client
@ -106,7 +106,7 @@ class ConfigurationAdmin(SingletonModelAdmin):
'fields': (
'organisation',
'short_description',
'adresse',
'adress',
'phone',
'email',
'site_web',
@ -186,24 +186,19 @@ class ReservationAdmin(admin.ModelAdmin):
staff_admin_site.register(Reservation, ReservationAdmin)
class ArticleAdmin(admin.ModelAdmin):
class ProductAdmin(admin.ModelAdmin):
list_display = (
'name',
'prix',
'stock',
'reservation_par_user_max',
'vat',
'publish',
'img',
'categorie_article',
'id_product_stripe',
)
list_editable = (
'prix',
'stock',
'reservation_par_user_max',
'vat',
'publish',
)
staff_admin_site.register(Article, ArticleAdmin)
staff_admin_site.register(Product, ProductAdmin)
@ -213,7 +208,7 @@ staff_admin_site.register(LigneArticle, admin.ModelAdmin)
staff_admin_site.register(OptionGenerale, OptionGeneraleAdmin)
staff_admin_site.register(TarifBillet, admin.ModelAdmin)
staff_admin_site.register(Price, admin.ModelAdmin)
class PaiementStripeAdmin(admin.ModelAdmin):
@ -223,12 +218,8 @@ class PaiementStripeAdmin(admin.ModelAdmin):
'total',
'order_date',
'status',
'articles',
)
ordering = ('-order_date',)
# readonly_fields = (
# 'reservations',
# )
staff_admin_site.register(Paiement_stripe, PaiementStripeAdmin)

View File

@ -3,47 +3,55 @@ import json
from django.utils.translation import gettext, gettext_lazy as _
from rest_framework.generics import get_object_or_404
from BaseBillet.models import Event, TarifBillet, Article
from BaseBillet.models import Event, Price, Product
class TarifsSerializer(serializers.ModelSerializer):
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = TarifBillet
model = Product
fields = [
'uuid',
"uuid",
"name",
"prix",
"reservation_par_user_max",
]
read_only_fields = ['uuid']
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = [
'uuid',
'name',
'prix',
'stock',
'reservation_par_user_max',
'vat',
'publish',
'img',
'categorie_article',
'id_product_stripe',
'id_price_stripe',
"publish",
"img",
"categorie_article",
"prices",
"id_product_stripe",
]
depth = 1
read_only_fields = [
'uuid',
'id_product_stripe',
'prices',
]
class PriceSerializer(serializers.ModelSerializer):
product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all())
class Meta:
model = Price
fields = [
'uuid',
'product',
'name',
'prix',
'vat',
'id_price_stripe',
'stock',
'max_per_user',
]
read_only_fields = [
'uuid',
'id_price_stripe',
]
depth = 1
class EventSerializer(serializers.ModelSerializer):
tarifs = TarifsSerializer(
products = ProductSerializer(
many=True,
read_only=True
)
@ -56,8 +64,7 @@ class EventSerializer(serializers.ModelSerializer):
'short_description',
'long_description',
'datetime',
'tarifs',
'articles',
'products',
'img',
'reservations',
'complet',
@ -65,37 +72,36 @@ class EventSerializer(serializers.ModelSerializer):
read_only_fields = ['uuid', 'reservations']
depth = 1
def validate(self, attrs):
tarifs = self.initial_data.get('tarifs')
if tarifs:
products = self.initial_data.get('products')
if products:
try:
tarifs_list = json.loads(tarifs)
products_list = json.loads(products)
except json.decoder.JSONDecodeError as e:
raise serializers.ValidationError(_(f'tarifs doit être un json valide : {e}'))
raise serializers.ValidationError(_(f'products doit être un json valide : {e}'))
self.tarif_to_db = []
for tarif in tarifs_list:
self.tarif_to_db.append(get_object_or_404(TarifBillet, uuid=tarif.get('uuid')))
self.products_to_db = []
for product in products_list:
self.products_to_db.append(get_object_or_404(Product, uuid=product.get('uuid')))
return super().validate(attrs)
else:
raise serializers.ValidationError(_('tarifs doit être un json valide'))
raise serializers.ValidationError(_('products doit être un json valide'))
def save(self, **kwargs):
instance = super().save(**kwargs)
instance.tarifs.clear()
for tarif in self.tarif_to_db:
instance.tarifs.add(tarif)
instance.products.clear()
for product in self.products_to_db:
instance.products.add(product)
return instance
'''
'''
[
{
"uuid": "37a1093f-565d-4b38-858d-680568269d43",
},
{
"uuid": "94d36be2-9bb9-4aa6-ab60-fc76287a1290",
}
products = [
{"uuid":"9340a9a1-1b90-488e-ab68-7b358b213dd7"},
{"uuid":"60db1531-fd0a-4d92-a785-f384e77cd213"}
]
'''
'''

View File

@ -6,8 +6,8 @@ from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'events', api_view.EventsViewSet, basename='event')
router.register(r'tarifs', api_view.TarifBilletViewSet, basename='billet')
router.register(r'articles', api_view.ArticleViewSet, basename='article')
router.register(r'products', api_view.ProductViewSet, basename='product')
router.register(r'prices', api_view.TarifBilletViewSet, basename='price')
urlpatterns = [

View File

@ -1,16 +1,16 @@
from rest_framework import serializers
import json
from BaseBillet.models import Event, TarifBillet
from BaseBillet.models import Event, Price
class BilletSerializer(serializers.ModelSerializer):
class Meta:
model = TarifBillet
model = Price
fields = [
'uuid',
"name",
"prix",
"reservation_par_user_max",
"max_per_user",
]
@ -20,7 +20,7 @@ class EventSerializer(serializers.ModelSerializer):
many=True,
read_only=True,
)
# billets = serializers.PrimaryKeyRelatedField(queryset=TarifBillet.objects.all(), many=True)
# billets = serializers.PrimaryKeyRelatedField(queryset=Price.objects.all(), many=True)
class Meta:
model = Event
@ -31,7 +31,7 @@ class EventSerializer(serializers.ModelSerializer):
'long_description',
'datetime',
'billets',
# 'articles',
# 'products',
'img',
# 'reservations',
'complet',
@ -49,6 +49,6 @@ class EventSerializer(serializers.ModelSerializer):
# billet_to_db = []
# for billet in billets_list :
# billet_to_db.append(billet.get('uuid'))
# value['billets'] = serializers.ManyRelatedField(queryset=TarifBillet.objects.filter(uuid__in=billet_to_db), many=True)
# value['billets'] = serializers.ManyRelatedField(queryset=Price.objects.filter(uuid__in=billet_to_db), many=True)
# return value

View File

@ -4,10 +4,10 @@ from django.shortcuts import render
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from ApiBillet.serializers import EventSerializer, TarifsSerializer, ArticleSerializer
from ApiBillet.serializers import EventSerializer, PriceSerializer, ProductSerializer
from AuthBillet.models import TenantAdminPermission
from Customers.models import Client, Domain
from BaseBillet.models import Event, TarifBillet, Article
from BaseBillet.models import Event, Price, Product
from rest_framework import viewsets, permissions, status
import os
@ -29,12 +29,12 @@ def new_tenants(schema_name):
class TarifBilletViewSet(viewsets.ViewSet):
def list(self, request):
queryset = TarifBillet.objects.all().order_by('prix')
serializer = TarifsSerializer(queryset, many=True, context={'request': request})
queryset = Price.objects.all().order_by('prix')
serializer = PriceSerializer(queryset, many=True, context={'request': request})
return Response(serializer.data)
def create(self, request):
serializer = TarifsSerializer(data=request.data)
serializer = PriceSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
@ -48,15 +48,15 @@ class TarifBilletViewSet(viewsets.ViewSet):
return [permission() for permission in permission_classes]
class ArticleViewSet(viewsets.ViewSet):
class ProductViewSet(viewsets.ViewSet):
def list(self, request):
serializer = ArticleSerializer(Article.objects.all(), many=True, context={'request': request})
serializer = ProductSerializer(Product.objects.all(), many=True, context={'request': request})
print(serializer.data)
return Response(serializer.data)
def create(self, request):
serializer = ArticleSerializer(data=request.data)
serializer = ProductSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)

View File

@ -1,4 +1,4 @@
# Generated by Django 2.2 on 2021-10-23 09:56
# Generated by Django 2.2 on 2021-10-24 10:22
from django.conf import settings
from django.db import migrations, models
@ -14,26 +14,11 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('PaiementStripe', '0001_initial'),
('QrcodeCashless', '0002_cartecashless_user'),
('PaiementStripe', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Article',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('name', models.CharField(blank=True, max_length=50, null=True)),
('prix', models.FloatField()),
('stock', models.SmallIntegerField(blank=True, null=True)),
('reservation_par_user_max', models.PositiveSmallIntegerField(default=10)),
('publish', models.BooleanField(default=False)),
('img', stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)], verbose_name='Image')),
('categorie_article', models.CharField(choices=[('B', 'Billet'), ('P', "Pack d'objets"), ('R', 'Recharge cashless'), ('T', 'Vetement'), ('M', 'Merchandasing'), ('A', 'Adhésion')], default='B', max_length=3, verbose_name="Type d'article")),
('id_product_stripe', models.CharField(blank=True, max_length=30, null=True)),
('id_price_stripe', models.CharField(blank=True, max_length=30, null=True)),
],
),
migrations.CreateModel(
name='Event',
fields=[
@ -45,7 +30,6 @@ class Migration(migrations.Migration):
('img', stdimage.models.StdImageField(upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)])),
('reservations', models.PositiveSmallIntegerField(default=0)),
('categorie', models.CharField(choices=[('LIV', 'Concert'), ('FES', 'Festival'), ('REU', 'Réunion'), ('CON', 'Conférence')], default='LIV', max_length=3, verbose_name="Catégorie d'évènement")),
('articles', models.ManyToManyField(blank=True, to='BaseBillet.Article')),
],
options={
'verbose_name': 'Evenement',
@ -67,25 +51,16 @@ class Migration(migrations.Migration):
},
),
migrations.CreateModel(
name='TarifBillet',
name='Product',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('name', models.CharField(blank=True, max_length=50, null=True)),
('prix', models.FloatField()),
('reservation_par_user_max', models.PositiveSmallIntegerField(default=6)),
('name', models.CharField(max_length=50)),
('publish', models.BooleanField(default=False)),
('img', stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)], verbose_name='Image')),
('categorie_article', models.CharField(choices=[('B', 'Billet'), ('P', "Pack d'objets"), ('R', 'Recharge cashless'), ('T', 'Vetement'), ('M', 'Merchandasing'), ('A', 'Adhésion')], default='B', max_length=3, verbose_name="Type d'article")),
('id_product_stripe', models.CharField(blank=True, max_length=30, null=True)),
],
),
migrations.CreateModel(
name='VAT',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('percent', models.FloatField(verbose_name='Taux de TVA (%)')),
],
options={
'verbose_name': 'TVA',
'verbose_name_plural': 'TVA',
},
),
migrations.CreateModel(
name='Reservation',
fields=[
@ -96,31 +71,48 @@ class Migration(migrations.Migration):
('user_commande', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Price',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('name', models.CharField(max_length=50)),
('prix', models.FloatField()),
('vat', models.CharField(choices=[('NA', 'Non applicable'), ('DX', '10 %'), ('VG', '20 %')], default='NA', max_length=2, verbose_name='Taux TVA')),
('id_price_stripe', models.CharField(blank=True, max_length=30, null=True)),
('stock', models.SmallIntegerField(blank=True, null=True)),
('max_per_user', models.PositiveSmallIntegerField(default=10)),
('product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='BaseBillet.Product')),
],
),
migrations.CreateModel(
name='LigneArticle',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, primary_key=True, serialize=False)),
('qty', models.SmallIntegerField()),
('datetime', models.DateTimeField(auto_now=True)),
('article', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='BaseBillet.Article')),
('billet', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='BaseBillet.TarifBillet')),
('qty', models.SmallIntegerField()),
('carte', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='QrcodeCashless.CarteCashless')),
('paiement_stripe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='PaiementStripe.Paiement_stripe')),
('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='BaseBillet.Product')),
('reservation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='BaseBillet.Reservation')),
],
),
migrations.AddField(
model_name='event',
name='products',
field=models.ManyToManyField(blank=True, to='BaseBillet.Product'),
),
migrations.AddField(
model_name='event',
name='tarifs',
field=models.ManyToManyField(to='BaseBillet.TarifBillet'),
field=models.ManyToManyField(to='BaseBillet.Price'),
),
migrations.CreateModel(
name='Configuration',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('organisation', models.CharField(max_length=50)),
('short_description', models.CharField(max_length=250)),
('adresse', models.CharField(max_length=250)),
('organisation', models.CharField(max_length=50, verbose_name="Nom de l'organisation")),
('short_description', models.CharField(max_length=250, verbose_name='Description courte')),
('adress', models.CharField(max_length=250)),
('phone', models.CharField(max_length=20)),
('email', models.EmailField(max_length=254)),
('site_web', models.URLField(blank=True, null=True)),
@ -128,15 +120,14 @@ class Migration(migrations.Migration):
('facebook', models.URLField(blank=True, null=True)),
('instagram', models.URLField(blank=True, null=True)),
('adhesion_obligatoire', models.BooleanField(default=False)),
('cadeau_adhesion', models.FloatField(default=0, help_text="Recharge cadeau a l'adhésion")),
('carte_restaurant', stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', validators=[stdimage.validators.MaxSizeValidator(1920, 1920)], verbose_name='Carte du restaurant')),
('img', stdimage.models.StdImageField(blank=True, null=True, upload_to='images/', verbose_name='Background')),
('mollie_api_key', models.CharField(blank=True, max_length=50, null=True)),
('stripe_api_key', models.CharField(blank=True, max_length=110, null=True)),
('stripe_test_api_key', models.CharField(blank=True, max_length=110, null=True)),
('stripe_mode_test', models.BooleanField(default=True)),
('activer_billetterie', models.BooleanField(default=True)),
('jauge_max', models.PositiveSmallIntegerField(default=50)),
('activer_billetterie', models.BooleanField(default=True, verbose_name='Activer la billetterie')),
('jauge_max', models.PositiveSmallIntegerField(default=50, verbose_name='Jauge maximale')),
('server_cashless', models.URLField(blank=True, max_length=300, null=True, verbose_name='Adresse du serveur Cashless')),
('key_cashless', models.CharField(blank=True, max_length=41, null=True, verbose_name="Clé d'API du serveur cashless")),
('option_generale_checkbox', models.ManyToManyField(blank=True, related_name='checkbox', to='BaseBillet.OptionGenerale')),
@ -146,9 +137,4 @@ class Migration(migrations.Migration):
'abstract': False,
},
),
migrations.AddField(
model_name='article',
name='vat',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='BaseBillet.VAT', verbose_name='TVA'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2 on 2021-10-24 10:31
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('BaseBillet', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='price',
name='product',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='prices', to='BaseBillet.Product'),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 2.2 on 2021-10-24 10:40
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('BaseBillet', '0002_auto_20211024_1431'),
]
operations = [
migrations.RemoveField(
model_name='event',
name='tarifs',
),
]

View File

@ -43,10 +43,10 @@ def poids_option_generale(sender, instance: OptionGenerale, created, **kwargs):
class Configuration(SingletonModel):
organisation = models.CharField(max_length=50)
short_description = models.CharField(max_length=250)
organisation = models.CharField(max_length=50, verbose_name=_("Nom de l'organisation"))
short_description = models.CharField(max_length=250, verbose_name=_("Description courte"))
adresse = models.CharField(max_length=250)
adress = models.CharField(max_length=250)
phone = models.CharField(max_length=20)
email = models.EmailField()
@ -57,7 +57,6 @@ class Configuration(SingletonModel):
instagram = models.URLField(blank=True, null=True)
adhesion_obligatoire = models.BooleanField(default=False)
cadeau_adhesion = models.FloatField(default=0, help_text="Recharge cadeau a l'adhésion")
carte_restaurant = StdImageField(upload_to='images/',
null=True, blank=True,
@ -69,7 +68,7 @@ class Configuration(SingletonModel):
'thumbnail': (150, 90),
},
delete_orphans=True,
verbose_name='Carte du restaurant'
verbose_name=_('Carte du restaurant')
)
img = StdImageField(upload_to='images/',
@ -92,9 +91,9 @@ class Configuration(SingletonModel):
stripe_test_api_key = models.CharField(max_length=110, blank=True, null=True)
stripe_mode_test = models.BooleanField(default=True)
activer_billetterie = models.BooleanField(default=True)
activer_billetterie = models.BooleanField(default=True, verbose_name=_("Activer la billetterie"))
jauge_max = models.PositiveSmallIntegerField(default=50)
jauge_max = models.PositiveSmallIntegerField(default=50, verbose_name=_("Jauge maximale"))
option_generale_radio = models.ManyToManyField(OptionGenerale,
blank=True,
@ -108,56 +107,22 @@ class Configuration(SingletonModel):
max_length=300,
blank=True,
null=True,
verbose_name="Adresse du serveur Cashless"
verbose_name=_("Adresse du serveur Cashless")
)
key_cashless = models.CharField(
max_length=41,
blank=True,
null=True,
verbose_name="Clé d'API du serveur cashless"
verbose_name=_("Clé d'API du serveur cashless")
)
class TarifBillet(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
name = models.CharField(max_length=50,
blank=True, null=True)
prix = models.FloatField()
reservation_par_user_max = models.PositiveSmallIntegerField(default=6)
def range_max(self):
return range(self.reservation_par_user_max + 1)
def __str__(self):
return f"{self.name}"
class VAT(models.Model):
"""
Les différents taux de TVA sont associés à des produits.
"""
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
percent = models.FloatField(verbose_name="Taux de TVA (%)")
class Meta:
verbose_name = _('TVA')
verbose_name_plural = _('TVA')
def __str__(self):
return f"{self.percent}%"
class Article(models.Model):
class Product(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
name = models.CharField(max_length=50)
prix = models.FloatField()
stock = models.SmallIntegerField(blank=True, null=True)
reservation_par_user_max = models.PositiveSmallIntegerField(default=10)
vat = models.ForeignKey(VAT, on_delete=models.PROTECT, verbose_name="TVA", null=True, blank=True)
publish = models.BooleanField(default=False)
@ -188,11 +153,11 @@ class Article(models.Model):
verbose_name=_("Type d'article"))
id_product_stripe = models.CharField(max_length=30, null=True, blank=True)
id_price_stripe = models.CharField(max_length=30, null=True, blank=True)
def range_max(self):
return range(self.reservation_par_user_max + 1)
def __str__(self):
return f"{self.name}"
'''
def get_id_product_stripe(self):
configuration = Configuration.get_solo()
if configuration.stripe_api_key and not self.id_product_stripe:
@ -204,6 +169,7 @@ class Article(models.Model):
if self.img:
# noinspection PyUnresolvedReferences
domain_url = connection.tenant.domains.all()[0].domain
# noinspection PyUnresolvedReferences
images = [f"https://{domain_url}{self.img.med.url}", ]
else:
images = []
@ -248,6 +214,37 @@ class Article(models.Model):
self.id_price_stripe = None
self.id_product_stripe = None
self.save()
'''
class Price(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
product = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="prices")
name = models.CharField(max_length=50)
prix = models.FloatField()
NA, DIX, VINGT = 'NA', 'DX', 'VG'
TVA_CHOICES = [
(NA, _('Non applicable')),
(DIX, _("10 %")),
(VINGT, _('20 %')),
]
vat = models.CharField(max_length=2,
choices=TVA_CHOICES,
default=NA,
verbose_name=_("Taux TVA"),
)
id_price_stripe = models.CharField(max_length=30, null=True, blank=True)
stock = models.SmallIntegerField(blank=True, null=True)
max_per_user = models.PositiveSmallIntegerField(default=10)
def range_max(self):
return range(self.max_per_user + 1)
def __str__(self):
return f"{self.name}"
@ -255,12 +252,14 @@ class Article(models.Model):
class Event(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
name = models.CharField(max_length=200)
datetime = models.DateTimeField()
short_description = models.CharField(max_length=250)
long_description = models.TextField(blank=True, null=True)
datetime = models.DateTimeField()
tarifs = models.ManyToManyField(TarifBillet)
articles = models.ManyToManyField(Article, blank=True)
products = models.ManyToManyField(Product, blank=True)
img = StdImageField(upload_to='images/',
validators=[MaxSizeValidator(1920, 1920)],
@ -286,7 +285,7 @@ class Event(models.Model):
]
categorie = models.CharField(max_length=3, choices=TYPE_CHOICES, default=CONCERT,
verbose_name=_("Catégorie d'évènement"))
verbose_name=_("Catégorie d'évènement"))
def complet(self):
# TODO: Benchmarker et tester si c'est pas mieux dans template
@ -343,8 +342,8 @@ class Reservation(models.Model):
def total_prix(self):
total = 0
for ligne in self.lignearticle_set.all():
if ligne.article:
total += ligne.qty * ligne.article.prix
if ligne.product:
total += ligne.qty * ligne.product.prix
if ligne.billet:
total += ligne.qty * ligne.billet.prix
@ -357,6 +356,7 @@ class Reservation(models.Model):
@receiver(post_save, sender=Reservation)
def verif_mail_valide(sender, instance: Reservation, created, **kwargs):
if created:
# noinspection PyUnresolvedReferences
if not instance.user_commande.is_active:
instance.status = instance.MAIL_NON_VALIDEE
instance.save()
@ -364,10 +364,12 @@ def verif_mail_valide(sender, instance: Reservation, created, **kwargs):
class LigneArticle(models.Model):
uuid = models.UUIDField(primary_key=True, db_index=True, default=uuid.uuid4)
reservation = models.ForeignKey(Reservation, on_delete=models.CASCADE, blank=True, null=True)
article = models.ForeignKey(Article, on_delete=models.CASCADE, blank=True, null=True)
carte = models.ForeignKey(CarteCashless, on_delete=models.PROTECT, blank=True, null=True)
billet = models.ForeignKey(TarifBillet, on_delete=models.CASCADE, blank=True, null=True)
qty = models.SmallIntegerField()
paiement_stripe = models.ForeignKey(Paiement_stripe, on_delete=models.PROTECT, blank=True, null=True)
datetime = models.DateTimeField(auto_now=True)
product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True)
qty = models.SmallIntegerField()
reservation = models.ForeignKey(Reservation, on_delete=models.CASCADE, blank=True, null=True)
carte = models.ForeignKey(CarteCashless, on_delete=models.PROTECT, blank=True, null=True)
paiement_stripe = models.ForeignKey(Paiement_stripe, on_delete=models.PROTECT, blank=True, null=True)

View File

@ -1,7 +1,7 @@
from rest_framework import serializers
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from BaseBillet.models import OptionGenerale, Configuration, Event, Article, TarifBillet
from BaseBillet.models import OptionGenerale, Configuration, Event, Product, Price
class ReservationValidator(serializers.Serializer):
@ -16,7 +16,7 @@ class ReservationValidator(serializers.Serializer):
def validate_articles(self, value):
value_dict = {}
art_obj = Article.objects.all()
art_obj = Product.objects.all()
for couple in value:
pk, qty = art_obj.get(pk=couple.split(',')[0]), int(couple.split(',')[1])
value_dict[pk] = qty
@ -25,14 +25,14 @@ class ReservationValidator(serializers.Serializer):
def validate_billets(self, value):
value_dict = {}
billet_obj = TarifBillet.objects.all()
billet_obj = Price.objects.all()
for couple in value:
pk, qty = billet_obj.get(pk=couple.split(',')[0]), int(couple.split(',')[1])
value_dict[pk] = qty
return value_dict
#
# # if value <= configuration.reservation_par_user_max :
# # if value <= configuration.max_per_user :
# return value
# else :
# raise serializers.ValidationError(_(f"Pas plus de {configuration.reservation_par_user_max} places en même temps."))
# raise serializers.ValidationError(_(f"Pas plus de {configuration.max_per_user} places en même temps."))

View File

@ -67,8 +67,8 @@ def creation_de_la_reservation(user: TibilletUser, event: Event, data):
qty = qty,
)
for article in data.get('articles'):
qty = data.get('articles')[article]
for article in data.get('products'):
qty = data.get('products')[article]
LigneArticle.objects.create(
reservation = reservation,
article = article,

View File

@ -41,7 +41,7 @@ class Paiement_stripe(models.Model):
return self.uuid_8()
def articles(self):
return " - ".join([ f"{ligne.article.name} {ligne.qty * ligne.article.prix }" for ligne in self.lignearticle_set.all() ])
return " - ".join([ f"{ligne.product.name} {ligne.qty * ligne.product.prix }" for ligne in self.lignearticle_set.all()])

View File

@ -64,7 +64,7 @@ class creation_paiement_stripe():
def _total(self):
total = 0
for ligne in self.liste_ligne_article:
total += float(ligne.qty) * float(ligne.article.prix)
total += float(ligne.qty) * float(ligne.product.prix)
return total
def _paiement_stripe_db(self):
@ -96,7 +96,7 @@ class creation_paiement_stripe():
ligne: LigneArticle
line_items.append(
{
"price": f"{ligne.article.get_id_price_stripe()}",
"price": f"{ligne.product.get_id_price_stripe()}",
"quantity": int(ligne.qty),
}
)

View File

@ -10,7 +10,7 @@ from rest_framework.generics import get_object_or_404
from django.views import View
from rest_framework import status
from BaseBillet.models import Configuration, Article, LigneArticle
from BaseBillet.models import Configuration, Product, LigneArticle
from PaiementStripe.models import Paiement_stripe
from PaiementStripe.views import creation_paiement_stripe
from QrcodeCashless.models import CarteCashless
@ -95,7 +95,7 @@ class index_scan(View):
configuration = Configuration.get_solo()
if not configuration.server_cashless:
return HttpResponse(
"L'adresse du serveur cashless n'est pas renseignée dans la configuration de la billetterie.")
"L'adress du serveur cashless n'est pas renseignée dans la configuration de la billetterie.")
if not configuration.stripe_api_key or not configuration.stripe_test_api_key:
return HttpResponse(
"Pas d'information de configuration pour paiement en ligne.")
@ -114,7 +114,7 @@ class index_scan(View):
request,
self.template_name,
{
'tarifs_adhesion': Article.objects.filter(categorie_article=Article.ADHESION).order_by('-prix'),
'tarifs_adhesion': Product.objects.filter(categorie_article=Product.ADHESION).order_by('-prix'),
'adhesion_obligatoire': configuration.adhesion_obligatoire,
'history': json_reponse.get('history'),
'carte_resto': configuration.carte_restaurant,
@ -163,10 +163,10 @@ class index_scan(View):
metadata = {}
metadata['recharge_carte_uuid'] = str(carte.uuid)
if montant_recharge:
art, created = Article.objects.get_or_create(
art, created = Product.objects.get_or_create(
name="Recharge Carte",
prix=1,
categorie_article=Article.RECHARGE_CASHLESS,
categorie_article=Product.RECHARGE_CASHLESS,
)
ligne_article_recharge = LigneArticle.objects.create(
@ -180,7 +180,7 @@ class index_scan(View):
metadata['recharge_carte_montant'] = str(montant_recharge)
if pk_adhesion:
art_adhesion = Article.objects.get(pk=data.get('pk_adhesion'))
art_adhesion = Product.objects.get(pk=data.get('pk_adhesion'))
ligne_article_recharge = LigneArticle.objects.create(
article=art_adhesion,
qty=1,
@ -265,11 +265,11 @@ def changement_paid_to_valid(sender, instance: Paiement_stripe, update_fields=No
if ligne_article.carte :
data_pour_serveur_cashless['uuid'] = ligne_article.carte.uuid
if ligne_article.article.categorie_article == Article.RECHARGE_CASHLESS :
if ligne_article.product.categorie_article == Product.RECHARGE_CASHLESS :
data_pour_serveur_cashless['recharge_qty'] = float(ligne_article.qty)
if ligne_article.article.categorie_article == Article.ADHESION :
data_pour_serveur_cashless['tarif_adhesion'] = ligne_article.article.prix
if ligne_article.product.categorie_article == Product.ADHESION :
data_pour_serveur_cashless['tarif_adhesion'] = ligne_article.product.prix
# si il y a autre chose que uuid_commande :
if len(data_pour_serveur_cashless) > 1 :

View File

@ -13,7 +13,7 @@ Pour en savoir plus : https://www.tibillet.re & https://wiki.tibillet.re
## Introduction.
TiBillet est en période d'Alpha, et en expérimentation sur plusieurs lieux sur l'ile de la Réunion. Venez nous voir au
TiBillet est en période de BETA et en expérimentation sur plusieurs lieux sur l'ile de la Réunion. Venez nous voir au
Bisik, à la Raffinerie, à Vavang'Art et au Manapany Festival !
Le présent dépot ne contient pas encore toutes les sources du projet. La billetterie est en cours de refactoring et les