Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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):

@tnurse18 tnurse18 Jun 4, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember correctly, there was already a view for this so creating this form may be redundant. The more forms we can reuse, the better.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only single-instance hour form that I could find is tied to an individual user and based on Event2012. I based this one off of the bulk hours one and I could combine them, but I figured this would be easier.

""" 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