Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Remove redundant templates under /db/my/* #663

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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):
""" 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
11 changes: 1 addition & 10 deletions events/urls/my.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,11 @@

url(r'^events/', include([
url(r'^$', views.my.myevents, name="events"),
url(r'^(?P<eventid>[0-9]+)/report/$', views.my.ccreport, name="report"),

# TODO: merge these with their events equivalents.
url(r'^(?P<eventid>[0-9]+)/files/$', views.my.eventfiles, name="event-files"),
url(r'^(?P<eventid>[0-9]+)/report/$', views.my.ccreport, name="report"),
url(r'^(?P<eventid>[0-9]+)/hours/$', views.my.hours_list, name="hours-list"),
url(r'^(?P<eventid>[0-9]+)/hours/bulk/$', views.my.hours_bulk,
name="hours-bulk"),
url(r'^(?P<eventid>[0-9]+)/hours/mk/$', views.my.hours_mk,
name="hours-new"),
url(r'^(?P<eventid>[0-9]+)/hours/(?P<userid>[0-9]+)$', views.my.hours_edit,
name="hours-edit"),
url(r'^(?P<eventid>[0-9]+)/survey/$', login_required(views.my.PostEventSurveyCreate.as_view()),
name="post-event-survey"),
url(r'^survey/success/$', views.my.survey_success, name="survey-success"),
])),

]
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
177 changes: 8 additions & 169 deletions events/views/my.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import datetime
from itertools import chain

from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required
from django.db.models.aggregates import Sum
from django.forms.models import inlineformset_factory, modelformset_factory
from django.forms.models import modelformset_factory
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render, redirect
from django.urls.base import reverse
Expand All @@ -14,12 +13,10 @@
from django.template import loader

from emails.generators import generate_selfservice_notice_email
from events.forms import (EditHoursForm, InternalReportForm, MKHoursForm,
SelfServiceOrgRequestForm, PostEventSurveyForm, OfficeHoursForm)
from events.models import CCReport, BaseEvent, Event, Hours, PostEventSurvey, CCR_DELTA, OfficeHour
from events.forms import (SelfServiceOrgRequestForm, PostEventSurveyForm, OfficeHoursForm)
from events.models import CCReport, BaseEvent, PostEventSurvey, OfficeHour
from helpers.mixins import LoginRequiredMixin
from helpers.revision import set_revision_comment
from helpers.util import curry_class


@login_required
Expand Down Expand Up @@ -98,172 +95,14 @@ def myevents(request):

return render(request, 'myevents.html', context)


@login_required
def eventfiles(request, eventid):
return redirect('/db/events/view/' + eventid + '/#files')


# Views Relating to Crew Chiefs
@login_required
def ccreport(request, eventid):
""" Submits a crew chief report """
context = {}

user = request.user

uevent = user.ccinstances.filter(event__pk=eventid)
# check that the event in question belongs to the user
if not uevent:
return HttpResponse("This event must not have been yours, or is closed")

event = uevent[0].event
if not event.reports_editable:
return render(request, 'too_late.html', {'days': CCR_DELTA, 'event': event})

# get event
x = event.ccinstances.filter(crew_chief=user)
context['msg'] = "Crew Chief Report for '<em>%s</em>' (%s)" % (event, ",".join([str(i.category) for i in x]))

# create report
try:
report = CCReport.objects.get(event=event, crew_chief=user)
except CCReport.DoesNotExist:
report = None

# standard save flow
if request.method == 'POST':
formset = InternalReportForm(data=request.POST, event=event, request_user=user, instance=report)
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse("my:events"))
else:
context['formset'] = formset

else:
formset = InternalReportForm(event=event, request_user=user, instance=report)

context['formset'] = formset

return render(request, 'mycrispy.html', context)


@login_required
def hours_list(request, eventid):
""" Lists a user's work hours """
context = {}
user = request.user

event = user.ccinstances.filter(event__pk=eventid)

if not event:
return HttpResponse("You must not have cc'd this event, or it's closed")
event = event[0].event
context['event'] = event

hours = event.hours.all()
context['hours'] = hours

return render(request, 'myhours.html', context)


@login_required
def hours_mk(request, eventid):
""" Hour Entry Form for CC """
context = {}

user = request.user
uevent = user.ccinstances.filter(event__pk=eventid)

if not uevent:
return HttpResponse("This event must not have been yours, or is closed")

event = uevent[0].event

if not isinstance(event, Event):
# New event - redirect to bulk update tool instead
return HttpResponseRedirect(reverse("my:hours-bulk", args=(event.id,)))

if not event.reports_editable:
return render(request, 'too_late.html', {'days': CCR_DELTA, 'event': event})

context['msg'] = "Hours for '%s'" % event.event_name
if request.method == 'POST':
formset = MKHoursForm(event, request.POST)
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse("my:hours-list", args=(event.id,)))
if BaseEvent.objects.get(pk=eventid).closed:
return redirect('/db/events/view/' + str(eventid) + '/#reports')
elif (my_ccreports:= CCReport.objects.filter(event=eventid, crew_chief=request.user)).exists():
return redirect('/db/events/view/' + str(eventid) + '/report/update/' + str(my_ccreports.last().id) + '/')
else:
formset = MKHoursForm(event)

context['formset'] = formset

return render(request, 'mycrispy.html', context)


@login_required
def hours_edit(request, eventid, userid):
""" Hour Entry Form for CC (editing)"""
context = {}
user = request.user
uevent = user.ccinstances.filter(event__pk=eventid)

if not uevent:
return HttpResponse("You must not have cc'd this event, or it's closed")

event = uevent[0].event
if not event.reports_editable:
return render(request, 'too_late.html', {'days': CCR_DELTA, 'event': event})

hours = get_object_or_404(Hours, event=event, user_id=userid)
u = get_object_or_404(get_user_model(), pk=userid)
context['msg'] = "Hours for '%s' on '%s'" % (u, event.event_name)
if request.method == 'POST':
formset = EditHoursForm(request.POST, instance=hours)
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse("my:hours-list", args=(event.id,)))
else:
formset = EditHoursForm(instance=hours)

context['formset'] = formset

return render(request, 'mycrispy.html', context)


@login_required
def hours_bulk(request, eventid):
""" Bulk Hours Entry Form """
context = {}
user = request.user
uevent = user.ccinstances.filter(event__pk=eventid)

if not uevent:
return HttpResponse("You must not have cc'd this event, or it's closed")

event = uevent[0].event
if not event.reports_editable:
return render(request, 'too_late.html', {'days': CCR_DELTA, 'event': event})

context['msg'] = "Bulk Hours Entry"

context['event'] = event

mk_event_formset = inlineformset_factory(Event, Hours, extra=3, exclude=[])
mk_event_formset.form = curry_class(MKHoursForm, event=event)

if request.method == 'POST':
formset = mk_event_formset(request.POST, instance=event)
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse("my:hours-list", args=(event.id,)))
else:
formset = mk_event_formset(instance=event)

context['formset'] = formset

return render(request, 'formset_hours_bulk.html', context)

return redirect('/db/events/view/' + str(eventid) + '/report/mk/')

class PostEventSurveyCreate(LoginRequiredMixin, CreateView):
model = PostEventSurvey
Expand Down
2 changes: 1 addition & 1 deletion site_tmpl/emails/email_ccadd.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

<p>Submit your crew chief report <a href="{% get_base_url %}{% url 'my:report' ccinstance.event.id %}">here</a>.</p>

<p>Submit crew hours <a href="{% get_base_url %}{% url 'my:hours-list' ccinstance.event.id %}">here</a>.</p>
<p>Submit crew hours <a href="{% get_base_url %}{% url 'events:add-bulk-crew' ccinstance.event.id %}">here</a>.</p>
{% if is_new_cc %}
<p>By the way, congratulations on taking your first event as Crew Chief! Since this is your first
time as a CC, here are some helpful resources.
Expand Down
2 changes: 1 addition & 1 deletion site_tmpl/emails/email_ccadd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ See full details of this event at {% get_base_url %}{% url 'events:detail' ccins

Submit your crew chief report at {% get_base_url %}{% url 'my:report' ccinstance.event.id %}.

Submit crew hours at {% get_base_url %}{% url 'my:hours-list' ccinstance.event.id %}.
Submit crew hours at {% get_base_url %}{% url 'events:add-bulk-crew' ccinstance.event.id %}.

{% if is_new_cc %}
By the way, congratulations on taking your first event as Crew Chief! Since this is your first time as a CC, here are some helpful resources.
Expand Down
2 changes: 1 addition & 1 deletion site_tmpl/emails/email_reportreminder.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

<p>Submit your crew chief report <a href="{% get_base_url %}{% url 'my:report' reminder.event.id %}">here</a>.</p>

<p>Submit crew hours <a href="{% get_base_url %}{% url 'my:hours-list' reminder.event.id %}">here</a>.</p>
<p>Submit crew hours <a href="{% get_base_url %}{% url 'events:add-bulk-crew' reminder.event.id %}">here</a>.</p>

<p>For your convenience, the Workorder PDF is attached.</p>

Expand Down
2 changes: 1 addition & 1 deletion site_tmpl/emails/email_reportreminder.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Crew chief reports exist for two purposes: 1) to serve as a guide for crew chief

Submit your crew chief report at {% get_base_url %}{% url 'my:report' reminder.event.id %}.

Submit crew hours at {% get_base_url %}{% url 'my:hours-list' reminder.event.id %}.
Submit crew hours at {% get_base_url %}{% url 'events:add-bulk-crew' reminder.event.id %}.

For your convenience, the Workorder PDF is attached.

Expand Down
Loading