add lineup entry (analogous to positioning)

This commit is contained in:
2021-11-24 16:23:51 -06:00
parent 3bea6c5e62
commit 41e64a4ca9
7 changed files with 219 additions and 16 deletions

21
teamsnap/forms.py Normal file
View File

@@ -0,0 +1,21 @@
from django import forms
from .models import LineupEntry
from events.models import Event
from players.models import Player
from django.forms import modelformset_factory, inlineformset_factory, BaseModelFormSet,formset_factory
from crispy_forms.helper import FormHelper, Layout
class LineupEntryForm(forms.ModelForm):
availability = None
class Meta:
model = LineupEntry
widgets = {
'label': forms.Select(attrs={'class': 'form-control form-control-sm'})
}
exclude = ()
LineupEntryFormSet = modelformset_factory(
model=LineupEntry,
form=LineupEntryForm,
extra=0
)

View File

@@ -0,0 +1,27 @@
# Generated by Django 3.2.6 on 2021-11-21 18:47
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('teamsnap', '0010_event_is_game'),
]
operations = [
migrations.CreateModel(
name='LineupEntry',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('label', models.PositiveSmallIntegerField(blank=True, choices=[(11, 'EH'), (1, 'P'), (2, 'C'), (3, '1B'), (4, '2B'), (5, '3B'), (6, 'SS'), (7, 'LF'), (8, 'CF'), (9, 'RF'), (10, 'DH')], default=None, null=True)),
('sequence', models.PositiveSmallIntegerField(default=0, null=True)),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teamsnap.event')),
('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teamsnap.member')),
],
options={
'unique_together': {('member', 'event')},
},
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.2.6 on 2021-11-21 20:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teamsnap', '0011_lineupentry'),
]
operations = [
migrations.AddField(
model_name='lineupentry',
name='name',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='lineupentry',
name='teamsnap_id',
field=models.CharField(max_length=10, null=True, unique=True),
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 3.2.6 on 2021-11-21 20:10
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('teamsnap', '0012_auto_20211121_2010'),
]
operations = [
migrations.RemoveField(
model_name='lineupentry',
name='name',
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-21 20:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teamsnap', '0013_remove_lineupentry_name'),
]
operations = [
migrations.AlterField(
model_name='lineupentry',
name='teamsnap_id',
field=models.CharField(blank=True, max_length=10, null=True, unique=True),
),
]

View File

@@ -107,3 +107,27 @@ class Availability(TeamsnapBaseModel):
class Meta:
verbose_name_plural = "availabilities"
class LineupEntry(TeamsnapBaseModel):
name = None
teamsnap_id = models.CharField(max_length=10, unique=True, null=True, blank=True)
member = models.ForeignKey(Member, on_delete=models.CASCADE)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
positions = [
(11, 'EH'),
(1, 'P'),
(2, 'C'),
(3, '1B'),
(4, '2B'),
(5, '3B'),
(6, 'SS'),
(7, 'LF'),
(8, 'CF'),
(9, 'RF'),
(10,'DH')
]
label = models.PositiveSmallIntegerField(choices=positions, default=None, null=True, blank=True)
sequence = models.PositiveSmallIntegerField(default=0, null=True, blank=True)
class Meta:
unique_together = ('member', 'event',)

View File

@@ -1,9 +1,19 @@
from django.shortcuts import render, redirect
# from .teamsnap.api import TeamSnap, Team, Event, Availability
from .models import User, Member, Team, Event, Location
from .models import User, Member, Team, Event, Location, LineupEntry
from django.views.generic.list import ListView
from lib.views import BenchcoachListView
from .forms import LineupEntryForm, LineupEntryFormSet
from django.forms.models import model_to_dict
from django.urls import reverse
from django.db.models import Case, When
def queryset_from_ids(Model, id_list):
#https://stackoverflow.com/questions/4916851/django-get-a-queryset-from-array-of-ids-in-specific-order
preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(id_list)])
queryset = Model.objects.filter(pk__in=id_list).order_by(preserved)
return queryset
def edit_event(request, id):
event = Event.objects.get(id = id)
@@ -17,19 +27,82 @@ class EventsListView(BenchcoachListView):
title_strf = '{item.formatted_title}'
body_strf = "{item.start_date:%a, %b %-d, %-I:%M %p},\n{item.location.name}"
# def get_context_data(self):
# context = super().get_context_data()
# for item in context['items']:
# item['buttons'].append(
# {
# 'label': 'Edit Lineup',
# 'href': reverse('edit lineup', args=[item['id']])
# }
# )
# return context
def get_context_data(self):
context = super().get_context_data()
for item in context['items']:
item['buttons'].append(
{
'label': 'Edit Lineup',
'href': reverse('teamsnap edit lineup', args=[item['id']])
}
)
return context
class TeamListView(ListView):
model = Team
class TeamListView(BenchcoachListView):
Model = Team
edit_url = 'teamsnap edit team'
list_url = 'teamsnap list teams'
page_title = "TeamSnap Teams"
class LocationListView(ListView):
model = Location
class LocationListView(BenchcoachListView):
Model = Location
edit_url = 'teamsnap edit location'
list_url = 'teamsnap list locations'
page_title = "TeamSnap Locations"
def edit_lineup(request, event_id):
if request.method == 'POST':
# create a form instance and populate it with data from the request:
formset = LineupEntryFormSet(request.POST)
for form in formset:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
if isinstance(form.cleaned_data['id'], LineupEntry):
positioning_id = form.cleaned_data.pop('id').id #FIXME this is a workaround, not sure why it is necessary
positioning = LineupEntry.objects.filter(id=positioning_id)
positioning.update(**form.cleaned_data)
did_create = False
else:
positioning = LineupEntry.objects.create(**form.cleaned_data, event_id=event_id)
did_create = True
else:
pass
return render(request, 'success.html', {'call_back':'teamsnap edit lineup','id':event_id, 'errors':[error for error in formset.errors if error]}, status=200)
# return render(request, 'success.html', {'call_back':'schedule'})
event = Event.objects.get(id=event_id)
members = Member.objects.filter(is_non_player=False).prefetch_related('availability_set', 'lineupentry_set')
# players_d.sort(key=lambda d: (-d['availability'].available, d['last_name']))
for member in members:
LineupEntry.objects.get_or_create(member_id=member.id, event_id=event_id)
qs_starting_lineup = LineupEntry.objects.filter(event_id=event_id, sequence__isnull=False, sequence__gt=0).order_by('sequence')
qs_bench = LineupEntry.objects.filter(event_id=event_id, sequence=0).prefetch_related('member__availability_set').order_by('member__last_name')
# This is all a compromise to get the sorting just the way I wanted. THERE'S GOT TO BE A BETTER WAY
ids_starting_lineup = [item.id for item in qs_starting_lineup]
ids_bench_available = [item.id for item in qs_bench
if item.member.availability_set.get(event_id=event_id).status_code == 1]
ids_bench_maybe = [item.id for item in qs_bench
if item.member.availability_set.get(event_id=event_id).status_code == 2]
ids_bench_no = [item.id for item in qs_bench
if item.member.availability_set.get(event_id=event_id).status_code == 0]
ids_bench_unknown = [item.id for item in qs_bench
if item.member.availability_set.get(event_id=event_id).status_code is None]
qset = queryset_from_ids(LineupEntry, ids_starting_lineup + ids_bench_available + ids_bench_maybe + ids_bench_no + ids_bench_unknown)
formset = LineupEntryFormSet(queryset=qset)
for f in formset:
if f.instance.member_id:
f.availability = f.instance.member.availability_set.get(event_id=event_id)
# f.statline = f.instance.member.statline_set.get()
return render(request, 'teamsnap/lineup.html', {'title': 'Lineup',
'event': event,
'formset': formset,
})