Skip to content

Commit

Permalink
Feat: edit button for user hours on event detail
Browse files Browse the repository at this point in the history
Adds an edit button (and page) to the event detail mega page. Edit page shows all user hour instances for event and allow editor to add additional instances or delete instance(s).
  • Loading branch information
benjamin-antupit committed Jun 4, 2022
1 parent 0dc50dc commit d0eecf0
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 4 deletions.
55 changes: 55 additions & 0 deletions events/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from django.utils import timezone
# python multithreading bug workaround
from pagedown.widgets import PagedownWidget
from accounts.models import User

from data.forms import DynamicFieldContainer, FieldAccessForm, FieldAccessLevel
from events.fields import GroupedModelChoiceField
Expand Down Expand Up @@ -1268,6 +1269,60 @@ class Meta:
category = ModelChoiceField(queryset=Category.objects.all(), required=False)
service = ModelChoiceField(queryset=Service.objects.all(), required=False) # queryset gets changed in constructor

class MKSingleHoursForm(forms.ModelForm):
""" Hours Form for a single user at an event"""
def __init__(self, event, user, *args, **kwargs):
self.event = event
self.user = user
self.helper = FormHelper()
self.helper.form_class = "form-horizontal"
self.helper.form_method = "post"
self.helper.form_action = ""
self.helper.layout = Layout(
Field('user'),
Field('hours'),
Field('service'),
FormActions(
Submit('save', 'Save Changes'),
# Reset('reset','Reset Form'),
)
)
super(MKSingleHoursForm, self).__init__(*args, **kwargs)
self.fields['service'].queryset = get_qs_from_event(self.event)
if isinstance(self.event, Event2019):
self.fields['category'].queryset = Category.objects.filter(
pk__in=self.event.serviceinstance_set.values_list('service__category', flat=True))
if user is not None:
self.fields['user'] = forms.ModelChoiceField(queryset=User.objects.filter(pk=user.id), disabled=True, empty_label=None, initial=user)

def clean(self):
user = self.user if self.user is not None else self.cleaned_data.get('user')
super(MKSingleHoursForm, self).clean()
category = self.cleaned_data.get('category')
service = self.cleaned_data.get('service')
if user is None:
# this problem will raise an error elsewhere
return
if self.event.hours.filter(user=user, category=category, service=service).exists() and not self.instance.pk:
raise ValidationError("User already has hours for this category/service. Edit those instead")

def save(self, commit=True):
obj = super(MKSingleHoursForm, self).save(commit=False)
if obj.category is None and obj.service is not None:
obj.category = obj.service.category
obj.event = self.event
if commit:
obj.save()
return obj

class Meta:
model = Hours
fields = ('user','hours', 'category', 'service')

user = AutoCompleteSelectField('Users', required=True)
hours = forms.DecimalField(min_value=decimal.Decimal("0.00"))
category = ModelChoiceField(queryset=Category.objects.all(), required=False)
service = ModelChoiceField(queryset=Service.objects.all(), required=False) # queryset gets changed in constructor

class EditHoursForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
Expand Down
4 changes: 4 additions & 0 deletions events/urls/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def generate_date_patterns(func, name):
flow_views.rmcrew, name="remove-crew"),
url(r'^(?P<id>[0-9]+)/hours/bulk/$', flow_views.hours_bulk_admin,
name="add-bulk-crew"),
url(r'^(?P<id>[0-9]+)/hours/single/(?P<user>[0-9a-f]+)/$', flow_views.hours_single_admin,
name="edit_single_crew_hours"),
url(r'^(?P<id>[0-9]+)/hours/single/$', flow_views.hours_single_admin,
name="edit_single_crew_hours"),
url(r'^selfcrew/(?P<id>[0-9]+)/$', flow_views.hours_prefill_self, name="selfcrew"),
url(r'^crewchief/(?P<id>[0-9a-f]+)/$', flow_views.assigncc, name="chiefs"),
url(r'^rmcc/(?P<id>[0-9a-f]+)/(?P<user>[0-9a-f]+)/$', flow_views.rmcc, name="remove-chief"),
Expand Down
39 changes: 37 additions & 2 deletions events/views/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
from django.views.decorators.http import require_GET, require_POST
from reversion.models import Version

from accounts.models import UserPreferences
from accounts.models import User, UserPreferences
from emails.generators import (ReportReminderEmailGenerator, EventEmailGenerator, BillingEmailGenerator,
DefaultLNLEmailGenerator as DLEG, send_survey_if_necessary)
from slack.views import cc_report_reminder
from slack.api import lookup_user, slack_post
from events.forms import (AttachmentForm, BillingForm, BillingUpdateForm, MultiBillingForm,
from events.forms import (AttachmentForm, BillingForm, BillingUpdateForm, EditHoursForm, MKSingleHoursForm, MultiBillingForm,
MultiBillingUpdateForm, CCIForm, CrewAssign, EventApprovalForm,
EventDenialForm, EventReviewForm, ExtraForm, InternalReportForm, MKHoursForm,
BillingEmailForm, MultiBillingEmailForm, ServiceInstanceForm, WorkdayForm, CrewCheckinForm,
Expand Down Expand Up @@ -449,6 +449,41 @@ def hours_bulk_admin(request, id):
context['formset'] = formset
return render(request, 'formset_hours_bulk.html', context)

@login_required
def hours_single_admin(request, id, user=None):
""" Update single crew member hours """
try:
user = User.objects.get(pk=user)
context = {'msg': "Update Crew Hours"}
except User.DoesNotExist:
context = {'msg': "Add Crew Hours"}
event = get_object_or_404(BaseEvent, pk=id)
if not event.reports_editable and not request.user.has_perm('events.edit_event_hours') and \
request.user.has_perm('events.edit_event_hours', event):
return render(request, 'too_late.html', {'days': CCR_DELTA, 'event': event})
if not (request.user.has_perm('events.edit_event_hours') or
request.user.has_perm('events.edit_event_hours', event) and event.reports_editable):
raise PermissionDenied
if event.closed:
messages.add_message(request, messages.ERROR, 'Event is closed.')
return HttpResponseRedirect(reverse('events:detail', args=(event.id,)))
context['event'] = event
context['oldevent'] = isinstance(event, Event)

mk_hours_formset = inlineformset_factory(BaseEvent, Hours, exclude=[], extra=(0 if event.hours.filter(user=user).exists() else 1))
mk_hours_formset.form = curry_class(MKSingleHoursForm, event=event, user=user)

if request.method == 'POST':
formset = mk_hours_formset(request.POST, instance=event)
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse('events:detail', args=(event.id,)) + "#reports")
else:
formset = mk_hours_formset(instance=event, queryset=Hours.objects.filter(user=user))

context['formset'] = formset
return render(request, 'formset_hours_bulk.html', context)


@login_required
@require_GET
Expand Down
2 changes: 1 addition & 1 deletion site_tmpl/formset_hours_bulk.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% block content %}
<div class="row">
<div class="col-md-12">
<h2> {{msg }} Crew Chiefs for "{{ event }}"</h2>
<h2> {{ msg }} for "{{ event }}"</h2>
<form method="post" action="" class="form-inline" enctype="multipart/form-data">
{% csrf_token %}
{{ formset.management_form }}
Expand Down
9 changes: 8 additions & 1 deletion site_tmpl/uglydetail.html
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,8 @@ <h4> Crew Chiefs Needing Reports </h4>
{% endif %}
{% if not event.closed %}
{% permission request.user has 'events.edit_event_hours' of event %}
<div class="pull-right">
<div class="pull-right btn-group">
<a class="btn btn-success btn-lg" href="{% url 'events:edit_single_crew_hours' event.id %}">Add New</a>
<a class="btn btn-primary btn-lg" href="{% url 'events:add-bulk-crew' event.id %}">Edit</a>
</div>
{% endpermission %}
Expand All @@ -593,6 +594,7 @@ <h2> Hours </h2>
<th>Member</th>
<th>Hours</th>
<th>Category</th>
<th></th>
</tr>
</thead>
{% for hour in event.hours.all %}
Expand All @@ -607,6 +609,11 @@ <h2> Hours </h2>
{% endif %}
</td>
<td>{{ hour.category }}</td>
<td>
{% if not event.closed %}{% permission request.user has 'events.edit_event_hours' of event %}
<a class="btn btn-primary btn-sm" href="{% url "events:edit_single_crew_hours" event.id hour.user.id %}">Edit</a>
{% endpermission %}{% endif %}
</td>
</tr>
{% endfor %}
</table>
Expand Down

0 comments on commit d0eecf0

Please sign in to comment.