mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2025-02-26 21:06:27 +00:00
Compare commits
No commits in common. "ca7cf5987ce94dd9830c1bd9e4bf5b3d120c831b" and "2a545dae105797406781850922f101c9193599cb" have entirely different histories.
ca7cf5987c
...
2a545dae10
@ -2,6 +2,14 @@ stages:
|
|||||||
- test
|
- test
|
||||||
- quality-assurance
|
- quality-assurance
|
||||||
|
|
||||||
|
py39:
|
||||||
|
stage: test
|
||||||
|
image: python:3.9-alpine
|
||||||
|
before_script:
|
||||||
|
- apk add --no-cache libmagic
|
||||||
|
- pip install tox --no-cache-dir
|
||||||
|
script: tox -e py39
|
||||||
|
|
||||||
py310:
|
py310:
|
||||||
stage: test
|
stage: test
|
||||||
image: python:3.10-alpine
|
image: python:3.10-alpine
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.urls import include, path
|
from django.conf.urls import include, url
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
from .viewsets import UserViewSet
|
from .viewsets import UserViewSet
|
||||||
@ -29,6 +29,6 @@ app_name = 'api'
|
|||||||
# Wire up our API using automatic URL routing.
|
# Wire up our API using automatic URL routing.
|
||||||
# Additionally, we include login URLs for the browsable API.
|
# Additionally, we include login URLs for the browsable API.
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls)),
|
url('^', include(router.urls)),
|
||||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||||
]
|
]
|
@ -34,13 +34,13 @@ def pre_save_object(sender, instance, **kwargs):
|
|||||||
instance._previous = None
|
instance._previous = None
|
||||||
|
|
||||||
|
|
||||||
def save_object(sender, instance, raw, **kwargs):
|
def save_object(sender, instance, **kwargs):
|
||||||
"""
|
"""
|
||||||
Each time a model is saved, an entry in the table `Changelog` is added in the database
|
Each time a model is saved, an entry in the table `Changelog` is added in the database
|
||||||
in order to store each modification made
|
in order to store each modification made
|
||||||
"""
|
"""
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
if instance._meta.label_lower in EXCLUDED or hasattr(instance, "_no_signal") or raw:
|
if instance._meta.label_lower in EXCLUDED or hasattr(instance, "_no_signal"):
|
||||||
return
|
return
|
||||||
|
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
64
apps/participation/admin.py
Normal file
64
apps/participation/admin.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Copyright (C) 2020 by Animath
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament, Tweak
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Team)
|
||||||
|
class TeamAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('name', 'trigram', 'valid',)
|
||||||
|
search_fields = ('name', 'trigram',)
|
||||||
|
list_filter = ('participation__valid',)
|
||||||
|
|
||||||
|
def valid(self, team):
|
||||||
|
return team.participation.valid
|
||||||
|
|
||||||
|
valid.short_description = _('valid')
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Participation)
|
||||||
|
class ParticipationAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('team', 'valid',)
|
||||||
|
search_fields = ('team__name', 'team__trigram',)
|
||||||
|
list_filter = ('valid',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Pool)
|
||||||
|
class PoolAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('participations__team__name', 'participations__team__trigram',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Passage)
|
||||||
|
class PassageAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('pool__participations__team__name', 'pool__participations__team__trigram',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Note)
|
||||||
|
class NoteAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ('jury',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Solution)
|
||||||
|
class SolutionAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('participation',)
|
||||||
|
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Synthesis)
|
||||||
|
class SynthesisAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('participation',)
|
||||||
|
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Tournament)
|
||||||
|
class TournamentAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('name',)
|
||||||
|
search_fields = ('name',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Tweak)
|
||||||
|
class TweakAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('participation', 'pool', 'diff',)
|
@ -170,7 +170,7 @@ class SolutionForm(forms.ModelForm):
|
|||||||
class PoolForm(forms.ModelForm):
|
class PoolForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Pool
|
model = Pool
|
||||||
fields = ('tournament', 'round', 'letter', 'bbb_url', 'results_available', 'juries',)
|
fields = ('tournament', 'round', 'bbb_url', 'results_available', 'juries',)
|
||||||
widgets = {
|
widgets = {
|
||||||
"juries": forms.SelectMultiple(attrs={
|
"juries": forms.SelectMultiple(attrs={
|
||||||
'class': 'selectpicker',
|
'class': 'selectpicker',
|
||||||
@ -231,8 +231,6 @@ class UploadNotesForm(forms.Form):
|
|||||||
if len(line) < 19:
|
if len(line) < 19:
|
||||||
continue
|
continue
|
||||||
name = line[0]
|
name = line[0]
|
||||||
if name in ["moyenne", "coefficient", "sous-total"]:
|
|
||||||
continue
|
|
||||||
notes = line[1:19]
|
notes = line[1:19]
|
||||||
if not all(s.isnumeric() for s in notes):
|
if not all(s.isnumeric() for s in notes):
|
||||||
continue
|
continue
|
@ -30,7 +30,7 @@ class Command(BaseCommand):
|
|||||||
else:
|
else:
|
||||||
stat_file = os.stat("tfjm/static/logo.png")
|
stat_file = os.stat("tfjm/static/logo.png")
|
||||||
with open("tfjm/static/logo.png", "rb") as f:
|
with open("tfjm/static/logo.png", "rb") as f:
|
||||||
resp = (await Matrix.upload(f, filename="../../../tfjm/static/logo.png", content_type="image/png",
|
resp = (await Matrix.upload(f, filename="logo.png", content_type="image/png",
|
||||||
filesize=stat_file.st_size))[0][0]
|
filesize=stat_file.st_size))[0][0]
|
||||||
avatar_uri = resp.content_uri
|
avatar_uri = resp.content_uri
|
||||||
with open(".matrix_avatar", "w") as f:
|
with open(".matrix_avatar", "w") as f:
|
@ -3,6 +3,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import django.core.validators
|
import django.core.validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
import django.utils.timezone
|
import django.utils.timezone
|
||||||
import participation.models
|
import participation.models
|
||||||
|
|
@ -124,7 +124,6 @@ class Team(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("team")
|
verbose_name = _("team")
|
||||||
verbose_name_plural = _("teams")
|
verbose_name_plural = _("teams")
|
||||||
ordering = ('trigram',)
|
|
||||||
indexes = [
|
indexes = [
|
||||||
Index(fields=("trigram", )),
|
Index(fields=("trigram", )),
|
||||||
]
|
]
|
||||||
@ -279,13 +278,6 @@ class Tournament(models.Model):
|
|||||||
return Synthesis.objects.filter(final_solution=True)
|
return Synthesis.objects.filter(final_solution=True)
|
||||||
return Synthesis.objects.filter(participation__tournament=self)
|
return Synthesis.objects.filter(participation__tournament=self)
|
||||||
|
|
||||||
@property
|
|
||||||
def best_format(self):
|
|
||||||
n = len(self.participations.filter(valid=True).all())
|
|
||||||
fmt = [n] if n <= 5 else [3] * (n // 3 - 1) + [3 + n % 3]
|
|
||||||
return '+'.join(map(str, sorted(fmt, reverse=True)))
|
|
||||||
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy("participation:tournament_detail", args=(self.pk,))
|
return reverse_lazy("participation:tournament_detail", args=(self.pk,))
|
||||||
|
|
||||||
@ -360,16 +352,6 @@ class Pool(models.Model):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
letter = models.PositiveSmallIntegerField(
|
|
||||||
choices=[
|
|
||||||
(1, 'A'),
|
|
||||||
(2, 'B'),
|
|
||||||
(3, 'C'),
|
|
||||||
(4, 'D'),
|
|
||||||
],
|
|
||||||
verbose_name=_('letter'),
|
|
||||||
)
|
|
||||||
|
|
||||||
participations = models.ManyToManyField(
|
participations = models.ManyToManyField(
|
||||||
Participation,
|
Participation,
|
||||||
related_name="pools",
|
related_name="pools",
|
||||||
@ -405,10 +387,6 @@ class Pool(models.Model):
|
|||||||
return sum(passage.average(participation) for passage in self.passages.all()) \
|
return sum(passage.average(participation) for passage in self.passages.all()) \
|
||||||
+ sum(tweak.diff for tweak in participation.tweaks.filter(pool=self).all())
|
+ sum(tweak.diff for tweak in participation.tweaks.filter(pool=self).all())
|
||||||
|
|
||||||
async def aaverage(self, participation):
|
|
||||||
return sum([passage.average(participation) async for passage in self.passages.all()]) \
|
|
||||||
+ sum([tweak.diff async for tweak in participation.tweaks.filter(pool=self).all()])
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy("participation:pool_detail", args=(self.pk,))
|
return reverse_lazy("participation:pool_detail", args=(self.pk,))
|
||||||
|
|
||||||
@ -421,7 +399,6 @@ class Pool(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("pool")
|
verbose_name = _("pool")
|
||||||
verbose_name_plural = _("pools")
|
verbose_name_plural = _("pools")
|
||||||
ordering = ('round', 'letter',)
|
|
||||||
|
|
||||||
|
|
||||||
class Passage(models.Model):
|
class Passage(models.Model):
|
||||||
@ -435,7 +412,7 @@ class Passage(models.Model):
|
|||||||
solution_number = models.PositiveSmallIntegerField(
|
solution_number = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("defended solution"),
|
verbose_name=_("defended solution"),
|
||||||
choices=[
|
choices=[
|
||||||
(i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, len(settings.PROBLEMS) + 1)
|
(i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, settings.PROBLEM_COUNT + 1)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -589,7 +566,7 @@ class Solution(models.Model):
|
|||||||
problem = models.PositiveSmallIntegerField(
|
problem = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_("problem"),
|
verbose_name=_("problem"),
|
||||||
choices=[
|
choices=[
|
||||||
(i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, len(settings.PROBLEMS) + 1)
|
(i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, settings.PROBLEM_COUNT + 1)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
@ -6,22 +6,21 @@ from participation.models import Note, Participation, Passage, Pool, Team
|
|||||||
from tfjm.lists import get_sympa_client
|
from tfjm.lists import get_sympa_client
|
||||||
|
|
||||||
|
|
||||||
def create_team_participation(instance, created, raw, **_):
|
def create_team_participation(instance, created, **_):
|
||||||
"""
|
"""
|
||||||
When a team got created, create an associated participation.
|
When a team got created, create an associated participation.
|
||||||
"""
|
"""
|
||||||
if not raw:
|
participation = Participation.objects.get_or_create(team=instance)[0]
|
||||||
participation = Participation.objects.get_or_create(team=instance)[0]
|
participation.save()
|
||||||
participation.save()
|
if not created:
|
||||||
if not created:
|
participation.team.create_mailing_list()
|
||||||
participation.team.create_mailing_list()
|
|
||||||
|
|
||||||
|
|
||||||
def update_mailing_list(instance: Team, raw, **_):
|
def update_mailing_list(instance: Team, **_):
|
||||||
"""
|
"""
|
||||||
When a team name or trigram got updated, update mailing lists and Matrix rooms
|
When a team name or trigram got updated, update mailing lists and Matrix rooms
|
||||||
"""
|
"""
|
||||||
if instance.pk and not raw:
|
if instance.pk:
|
||||||
old_team = Team.objects.get(pk=instance.pk)
|
old_team = Team.objects.get(pk=instance.pk)
|
||||||
if old_team.trigram != instance.trigram:
|
if old_team.trigram != instance.trigram:
|
||||||
# TODO Rename Matrix room
|
# TODO Rename Matrix room
|
||||||
@ -37,12 +36,11 @@ def update_mailing_list(instance: Team, raw, **_):
|
|||||||
f"{coach.user.first_name} {coach.user.last_name}")
|
f"{coach.user.first_name} {coach.user.last_name}")
|
||||||
|
|
||||||
|
|
||||||
def create_notes(instance: Union[Passage, Pool], raw, **_):
|
def create_notes(instance: Union[Passage, Pool], **_):
|
||||||
if not raw:
|
if isinstance(instance, Pool):
|
||||||
if isinstance(instance, Pool):
|
for passage in instance.passages.all():
|
||||||
for passage in instance.passages.all():
|
create_notes(passage)
|
||||||
create_notes(passage, raw)
|
return
|
||||||
return
|
|
||||||
|
|
||||||
for jury in instance.pool.juries.all():
|
for jury in instance.pool.juries.all():
|
||||||
Note.objects.get_or_create(jury=jury, passage=instance)
|
Note.objects.get_or_create(jury=jury, passage=instance)
|
@ -76,20 +76,13 @@ class TournamentTable(tables.Table):
|
|||||||
|
|
||||||
|
|
||||||
class PoolTable(tables.Table):
|
class PoolTable(tables.Table):
|
||||||
letter = tables.LinkColumn(
|
teams = tables.LinkColumn(
|
||||||
'participation:pool_detail',
|
'participation:pool_detail',
|
||||||
args=[tables.A('id')],
|
args=[tables.A('id')],
|
||||||
verbose_name=_("pool").capitalize,
|
|
||||||
)
|
|
||||||
|
|
||||||
teams = tables.Column(
|
|
||||||
verbose_name=_("teams").capitalize,
|
verbose_name=_("teams").capitalize,
|
||||||
empty_values=(),
|
empty_values=(),
|
||||||
)
|
)
|
||||||
|
|
||||||
def render_letter(self, record):
|
|
||||||
return format_lazy(_("Pool {letter}{round}"), letter=record.get_letter_display(), round=record.round)
|
|
||||||
|
|
||||||
def render_teams(self, record):
|
def render_teams(self, record):
|
||||||
return ", ".join(participation.team.trigram for participation in record.participations.all()) \
|
return ", ".join(participation.team.trigram for participation in record.participations.all()) \
|
||||||
or _("No defined team")
|
or _("No defined team")
|
||||||
@ -99,7 +92,7 @@ class PoolTable(tables.Table):
|
|||||||
'class': 'table table-condensed table-striped',
|
'class': 'table table-condensed table-striped',
|
||||||
}
|
}
|
||||||
model = Pool
|
model = Pool
|
||||||
fields = ('letter', 'teams', 'round', 'tournament',)
|
fields = ('teams', 'round', 'tournament',)
|
||||||
|
|
||||||
|
|
||||||
class PassageTable(tables.Table):
|
class PassageTable(tables.Table):
|
@ -124,7 +124,7 @@
|
|||||||
initModal("updatePassage", "{% url "participation:passage_update" pk=passage.pk %}")
|
initModal("updatePassage", "{% url "participation:passage_update" pk=passage.pk %}")
|
||||||
|
|
||||||
{% if my_note is not None %}
|
{% if my_note is not None %}
|
||||||
initModal("updateNotes", "{% url "participation:update_notes" pk=my_note.pk %}")
|
initModal("updateNotesModal", "{% url "participation:update_notes" pk=my_note.pk %}")
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
initModal("uploadSynthesis", "{% url "participation:upload_synthesis" pk=passage.pk %}")
|
initModal("uploadSynthesis", "{% url "participation:upload_synthesis" pk=passage.pk %}")
|
@ -15,9 +15,6 @@
|
|||||||
<dt class="col-sm-3">{% trans "Round:" %}</dt>
|
<dt class="col-sm-3">{% trans "Round:" %}</dt>
|
||||||
<dd class="col-sm-9">{{ pool.get_round_display }}</dd>
|
<dd class="col-sm-9">{{ pool.get_round_display }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Letter:" %}</dt>
|
|
||||||
<dd class="col-sm-9">{{ pool.get_letter_display }}</dd>
|
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Teams:" %}</dt>
|
<dt class="col-sm-3">{% trans "Teams:" %}</dt>
|
||||||
<dd class="col-sm-9">
|
<dd class="col-sm-9">
|
||||||
{% for participation in pool.participations.all %}
|
{% for participation in pool.participations.all %}
|
14
apps/participation/templates/participation/upload_notes.html
Normal file
14
apps/participation/templates/participation/upload_notes.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% extends request.content_only|yesno:"empty.html,base.html" %}
|
||||||
|
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<div id="form-content">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans "Upload" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
37
apps/registration/admin.py
Normal file
37
apps/registration/admin.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Copyright (C) 2020 by Animath
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.admin import ModelAdmin
|
||||||
|
from polymorphic.admin import PolymorphicChildModelAdmin, PolymorphicParentModelAdmin
|
||||||
|
|
||||||
|
from .models import CoachRegistration, Payment, Registration, StudentRegistration, VolunteerRegistration
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Registration)
|
||||||
|
class RegistrationAdmin(PolymorphicParentModelAdmin):
|
||||||
|
child_models = (StudentRegistration, CoachRegistration, VolunteerRegistration,)
|
||||||
|
list_display = ("user", "type", "email_confirmed",)
|
||||||
|
polymorphic_list = True
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(StudentRegistration)
|
||||||
|
class StudentRegistrationAdmin(PolymorphicChildModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(CoachRegistration)
|
||||||
|
class CoachRegistrationAdmin(PolymorphicChildModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(VolunteerRegistration)
|
||||||
|
class VolunteerRegistrationAdmin(PolymorphicChildModelAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Payment)
|
||||||
|
class PaymentAdmin(ModelAdmin):
|
||||||
|
list_display = ('registration', 'type', 'valid', )
|
||||||
|
search_fields = ('registration__user__last_name', 'registration__user__first_name', 'registration__user__email',)
|
||||||
|
list_filter = ('type', 'valid',)
|
@ -192,11 +192,6 @@ class ParticipantRegistration(Registration):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _("participant registration")
|
|
||||||
verbose_name_plural = _("participant registrations")
|
|
||||||
|
|
||||||
|
|
||||||
class StudentRegistration(ParticipantRegistration):
|
class StudentRegistration(ParticipantRegistration):
|
||||||
"""
|
"""
|
||||||
Specific registration for students.
|
Specific registration for students.
|
||||||
@ -322,10 +317,6 @@ class VolunteerRegistration(Registration):
|
|||||||
from registration.forms import VolunteerRegistrationForm
|
from registration.forms import VolunteerRegistrationForm
|
||||||
return VolunteerRegistrationForm
|
return VolunteerRegistrationForm
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _("volunteer registration")
|
|
||||||
verbose_name_plural = _("volunteer registrations")
|
|
||||||
|
|
||||||
|
|
||||||
def get_scholarship_filename(instance, filename):
|
def get_scholarship_filename(instance, filename):
|
||||||
return f"authorization/scholarship/scholarship_{instance.registration.pk}"
|
return f"authorization/scholarship/scholarship_{instance.registration.pk}"
|
@ -43,12 +43,12 @@ def create_admin_registration(instance, **_):
|
|||||||
VolunteerRegistration.objects.get_or_create(user=instance, admin=True)
|
VolunteerRegistration.objects.get_or_create(user=instance, admin=True)
|
||||||
|
|
||||||
|
|
||||||
def create_payment(instance: Registration, raw, **_):
|
def create_payment(instance: Registration, **_):
|
||||||
"""
|
"""
|
||||||
When a user is saved, create the associated payment.
|
When a user is saved, create the associated payment.
|
||||||
For a free tournament, the payment is valid.
|
For a free tournament, the payment is valid.
|
||||||
"""
|
"""
|
||||||
if instance.participates and not raw:
|
if instance.participates:
|
||||||
payment = Payment.objects.get_or_create(registration=instance)[0]
|
payment = Payment.objects.get_or_create(registration=instance)[0]
|
||||||
if instance.team and instance.team.participation.valid and instance.team.participation.tournament.price == 0:
|
if instance.team and instance.team.participation.valid and instance.team.participation.tournament.price == 0:
|
||||||
payment.valid = True
|
payment.valid = True
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user