forked from DGNum/gestioCOF
519ef9dc20
Creating form fields in the class and modifiying them dynamically can cause concurrency issues because the form class is shared between tabs.
207 lines
7.3 KiB
Python
207 lines
7.3 KiB
Python
from django import forms
|
|
from django.forms.models import BaseInlineFormSet
|
|
from django.template import loader
|
|
from django.utils import timezone
|
|
|
|
from bda.models import Attribution, Spectacle, SpectacleRevente
|
|
|
|
|
|
class InscriptionInlineFormSet(BaseInlineFormSet):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# self.instance is a Participant object
|
|
tirage = self.instance.tirage
|
|
|
|
# set once for all "spectacle" field choices
|
|
# - restrict choices to the spectacles of this tirage
|
|
# - force_choices avoid many db requests
|
|
spectacles = tirage.spectacle_set.select_related("location")
|
|
choices = [(sp.pk, str(sp)) for sp in spectacles]
|
|
self.force_choices("spectacle", choices)
|
|
|
|
def force_choices(self, name, choices):
|
|
"""Set choices of a field.
|
|
|
|
As ModelChoiceIterator (default use to get choices of a
|
|
ModelChoiceField), it appends an empty selection if requested.
|
|
|
|
"""
|
|
for form in self.forms:
|
|
field = form.fields[name]
|
|
if field.empty_label is not None:
|
|
field.choices = [("", field.empty_label)] + choices
|
|
else:
|
|
field.choices = choices
|
|
|
|
|
|
class TokenForm(forms.Form):
|
|
token = forms.CharField(widget=forms.widgets.Textarea())
|
|
|
|
|
|
class AttributionModelMultipleChoiceField(forms.ModelMultipleChoiceField):
|
|
def label_from_instance(self, obj):
|
|
return str(obj.spectacle)
|
|
|
|
|
|
class ReventeModelMultipleChoiceField(forms.ModelMultipleChoiceField):
|
|
def __init__(self, *args, own=True, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.own = own
|
|
|
|
def label_from_instance(self, obj):
|
|
label = "{show}{suffix}"
|
|
suffix = ""
|
|
if self.own:
|
|
# C'est notre propre revente : informations sur le statut
|
|
if obj.soldTo is not None:
|
|
suffix = " -- Vendue à {firstname} {lastname}".format(
|
|
firstname=obj.soldTo.user.first_name,
|
|
lastname=obj.soldTo.user.last_name,
|
|
)
|
|
elif obj.shotgun:
|
|
suffix = " -- Tirage infructueux"
|
|
elif obj.notif_sent:
|
|
suffix = " -- Inscriptions au tirage en cours"
|
|
else:
|
|
# Ce n'est pas à nous : on ne voit jamais l'acheteur
|
|
suffix = " -- Vendue par {firstname} {lastname}".format(
|
|
firstname=obj.seller.user.first_name, lastname=obj.seller.user.last_name
|
|
)
|
|
|
|
return label.format(show=str(obj.attribution.spectacle), suffix=suffix)
|
|
|
|
|
|
class ResellForm(forms.Form):
|
|
attributions = AttributionModelMultipleChoiceField(
|
|
label="",
|
|
queryset=Attribution.objects.none(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
)
|
|
|
|
def __init__(self, participant, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["attributions"].queryset = (
|
|
participant.attribution_set.filter(spectacle__date__gte=timezone.now())
|
|
.exclude(revente__seller=participant)
|
|
.select_related("spectacle", "spectacle__location", "participant__user")
|
|
)
|
|
|
|
|
|
class AnnulForm(forms.Form):
|
|
def __init__(self, participant, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["reventes"] = ReventeModelMultipleChoiceField(
|
|
own=True,
|
|
label="",
|
|
queryset=participant.original_shows.filter(
|
|
attribution__spectacle__date__gte=timezone.now(), soldTo__isnull=True
|
|
)
|
|
.select_related(
|
|
"attribution__spectacle", "attribution__spectacle__location"
|
|
)
|
|
.order_by("-date"),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
)
|
|
|
|
|
|
class TemplateLabelField(forms.ModelMultipleChoiceField):
|
|
"""
|
|
Extends ModelMultipleChoiceField to offer two more customization options :
|
|
- `label_from_instance` can be used with a template file
|
|
- the widget rendering template can be specified with `option_template_name`
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
label_template_name=None,
|
|
context_object_name="obj",
|
|
option_template_name=None,
|
|
*args,
|
|
**kwargs
|
|
):
|
|
super().__init__(*args, **kwargs)
|
|
self.label_template_name = label_template_name
|
|
self.context_object_name = context_object_name
|
|
if option_template_name is not None:
|
|
self.widget.option_template_name = option_template_name
|
|
|
|
def label_from_instance(self, obj):
|
|
if self.label_template_name is None:
|
|
return super().label_from_instance(obj)
|
|
else:
|
|
return loader.render_to_string(
|
|
self.label_template_name, context={self.context_object_name: obj}
|
|
)
|
|
|
|
|
|
class InscriptionReventeForm(forms.Form):
|
|
def __init__(self, tirage, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["spectacles"] = TemplateLabelField(
|
|
queryset=tirage.spectacle_set.select_related("location").filter(
|
|
date__gte=timezone.now()
|
|
),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
label_template_name="bda/forms/spectacle_label_table.html",
|
|
option_template_name="bda/forms/checkbox_table.html",
|
|
context_object_name="spectacle",
|
|
)
|
|
|
|
|
|
class ReventeTirageAnnulForm(forms.Form):
|
|
def __init__(self, participant, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["reventes"] = TemplateLabelField(
|
|
queryset=participant.entered.filter(soldTo__isnull=True).select_related(
|
|
"attribution__spectacle", "seller__user"
|
|
),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
label_template_name="bda/forms/revente_other_label_table.html",
|
|
option_template_name="bda/forms/checkbox_table.html",
|
|
context_object_name="revente",
|
|
)
|
|
|
|
participant.entered.filter(soldTo__isnull=True).select_related(
|
|
"attribution__spectacle", "seller__user"
|
|
)
|
|
|
|
|
|
class ReventeTirageForm(forms.Form):
|
|
def __init__(self, participant, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields["reventes"] = TemplateLabelField(
|
|
queryset=(
|
|
SpectacleRevente.objects.filter(
|
|
notif_sent=True, shotgun=False, tirage_done=False
|
|
)
|
|
.exclude(confirmed_entry=participant)
|
|
.select_related("attribution__spectacle")
|
|
),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
label_template_name="bda/forms/revente_other_label_table.html",
|
|
option_template_name="bda/forms/checkbox_table.html",
|
|
context_object_name="revente",
|
|
)
|
|
|
|
|
|
class SoldForm(forms.Form):
|
|
def __init__(self, participant, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["reventes"].queryset = ReventeModelMultipleChoiceField(
|
|
own=True,
|
|
label="",
|
|
queryset=participant.original_shows.filter(soldTo__isnull=False)
|
|
.exclude(soldTo=participant)
|
|
.select_related(
|
|
"attribution__spectacle", "attribution__spectacle__location"
|
|
),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
)
|
|
|