def turnout(request): ''' shift turnout, using begin and end dates from the daterange form ''' if request.method == 'POST': form = forms.DateRangeForm(request.POST) if form.is_valid(): turnout = s_models.turnout(form.cleaned_data['start'], form.cleaned_data['end']) else: form = forms.DateRangeForm() turnout = s_models.turnout(today - datetime.timedelta(30), today) return render_to_response('reporting/turnout.html', locals(), context_instance=RequestContext(request))
def timecard(request, date=None): context = RequestContext(request) if date: try: # date = datetime.datetime.strptime(date, "%Y-%m-%d") Python 2.4 workaround date = datetime.datetime(*time.strptime(date, "%Y-%m-%d")[0:5]) except ValueError: raise Http404 else: today = datetime.date.today() # need datetime object for rrule, but datetime.today is, like, now date = datetime.datetime(today.year, today.month, today.day) # It seems our ordering was not deterministic enough, and that caused the # 'Task with this None already exists' if the request.POST and the queryset # ended up with different ordering. Fixed by adding order_by 'id'. -Paul tasks = models.Task.objects.filter(time__range=( datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max))).exclude( account__isnull=True, excused=True).order_by('time', 'hours', 'job', '-recur_rule', 'id') TaskFormSet = formset_factory(forms.TimecardForm) if request.method == 'POST': formset = TaskFormSet(request.POST) for form in formset.forms: if (form.is_valid()): task = models.Task.objects.get(id=form.cleaned_data['id']) task.hours_worked=form.cleaned_data['hours_worked'] task.excused = (form.cleaned_data['shift_status']=='excused') task.makeup = form.cleaned_data['makeup'] task.banked = form.cleaned_data['banked'] task.save() if (not formset.errors): return HttpResponseRedirect(reverse('scheduling-timecard', args=[date.date()])) else: num_tasks = unicode(len(tasks)) data = { 'form-TOTAL_FORMS': num_tasks, 'form-INITIAL_FORMS': num_tasks, 'form-MAX_NUM_FORMS': num_tasks, } for i in range(len(tasks)): task = tasks[i]; data['form-' + str(i) + '-id'] = task.id; if (task.hours_worked): data['form-' + str(i) + '-hours_worked'] = task.hours_worked else: data['form-' + str(i) + '-hours_worked'] = 0 if (task.hours_worked): data['form-' + str(i) + '-shift_status'] = u'worked' elif (task.excused): data['form-' + str(i) + '-shift_status'] = u'excused' else: data['form-' + str(i) + '-shift_status'] = u'unexcused' data['form-' + str(i) + '-hours'] = task.hours data['form-' + str(i) + '-makeup'] = task.makeup data['form-' + str(i) + '-banked'] = task.banked formset = TaskFormSet(data) # We used to use a model formset built with the Task # model, so the template expects each form to have # member named instance that points to its corresponding # task. We set these manually here - TM 1/17/2012 for i in range(len(formset.forms)): formset.forms[i].instance = tasks[i] context['formset'] = formset context['date'] = date a_day = datetime.timedelta(days=1) context['previous_date'] = date - a_day context['next_date'] = date + a_day context['old_rotations'] = old_rotations(date) context['turnout'] = models.turnout(date.date()) template = loader.get_template('scheduling/timecard.html') return HttpResponse(template.render(context))
def timecard(request, date=None): context = RequestContext(request) context['messages'] = [] if not has_elevated_perm(request, 'scheduling', 'add_timecard'): return HttpResponseRedirect(reverse('welcome')) if date: try: # date = datetime.datetime.strptime(date, "%Y-%m-%d") Python 2.4 workaround date = datetime.datetime(*time.strptime(date, "%Y-%m-%d")[0:5]) except ValueError: raise Http404 else: today = datetime.date.today() # need datetime object for rrule, but datetime.today is, like, now date = datetime.datetime(today.year, today.month, today.day) # It seems our ordering was not deterministic enough, and that caused the # 'Task with this None already exists' if the request.POST and the queryset # ended up with different ordering. Fixed by adding order_by 'id'. -Paul tasks = models.Task.objects.filter(time__range=( datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max))).exclude( account__isnull=True, excused=True).order_by('time', 'hours', 'job', '-recur_rule', 'id') TimecardFormSet = formset_factory(forms.TimecardForm) if request.method == 'POST': formset = TimecardFormSet(request.POST) for n in range(0, formset.total_form_count()): form = formset.forms[n] if (form.is_valid()): task = models.Task.objects.get(id=form.cleaned_data['id']) ''' It's possible for a task to exist with out a member attached to it. This shouldn't happen, but if it does don't save anything or email anyone. Just continue on to the next task ''' if not task.member: continue context['task'] = task ''' Automatic email for excused shifts or unexcused shifts Only goes out if this is the first the timecard has been submitted ''' if task.hours_worked is None: shift_status = form.cleaned_data['shift_status'] ''' Per Jamila and Shinara, we only send out emails if the task is not a make up or banked shift ''' if (shift_status == 'excused' or shift_status == 'unexcused') and not task.makeup and not task.banked: if task.job.name.strip() == "Committee": email_template = get_template("scheduling/emails/shift_" + shift_status + "_committee.html") subject_template = get_template("scheduling/emails/shift_" + shift_status + "_committee_subject.html") elif task.job.name.strip() == "Mill Creek Farm": email_template = get_template("scheduling/emails/shift_" + shift_status + "_mill_creek.html") subject_template = get_template("scheduling/emails/shift_" + shift_status + "_mill_creek_subject.html") else: email_template = get_template("scheduling/emails/shift_" + shift_status + ".html") subject_template = get_template("scheduling/emails/shift_" + shift_status + "_subject.html") subject = ''.join(subject_template.render(context).splitlines()) if task.member: if task.member.user.email: mail.send_mail( subject, email_template.render(context), MEMBER_COORDINATOR_EMAIL, [task.member.user.email] ) context['messages'].append( "Shift " + shift_status + " email sent to member %s %s of account %s" % ( task.member.user.first_name, task.member.user.last_name, task.account.name )) task.hours_worked=form.cleaned_data['hours_worked'] task.excused = (form.cleaned_data['shift_status']=='excused') task.makeup = form.cleaned_data['makeup'] task.banked = form.cleaned_data['banked'] task.reminder_call = form.cleaned_data['reminder_call'] task.save() else: ''' Even if we don't validate, we still save the reminder call value, as reminder calls take place a day before the timecard is ready to be submitted. ''' try: task = models.Task.objects.get(id=request.POST['form-' + str(n) + '-id']) task.reminder_call = request.POST['form-' + str(n) + '-reminder_call'] task.save() except Exception as e: ''' The DoesNotExist exception has been occurring but I do not know why. For now just send the IT coordinator an email with more information about the bug ''' mail.send_mail( "That DoesNotExist error", str(e) + '\n\nform-' + str(n) + '-reminder_call\n\n' + str(date) + '\n\n' + str(request.POST), "*****@*****.**", ['*****@*****.**'], ) if (not formset.errors): return HttpResponseRedirect(reverse('scheduling-timecard', args=[date.date()])) else: num_tasks = unicode(len(tasks)) data = { 'form-TOTAL_FORMS': num_tasks, 'form-INITIAL_FORMS': num_tasks, 'form-MAX_NUM_FORMS': num_tasks, } for i in range(len(tasks)): task = tasks[i]; data['form-' + str(i) + '-id'] = task.id; if (task.hours_worked): data['form-' + str(i) + '-hours_worked'] = task.hours_worked else: data['form-' + str(i) + '-hours_worked'] = 0 if (task.hours_worked): data['form-' + str(i) + '-shift_status'] = u'worked' elif (task.excused): data['form-' + str(i) + '-shift_status'] = u'excused' else: data['form-' + str(i) + '-shift_status'] = u'unexcused' data['form-' + str(i) + '-hours'] = task.hours data['form-' + str(i) + '-makeup'] = task.makeup data['form-' + str(i) + '-banked'] = task.banked data['form-' + str(i) + '-reminder_call'] = task.reminder_call formset = TimecardFormSet(data) # We used to use a model formset built with the Task # model, so the template expects each form to have # member named instance that points to its corresponding # task. We set these manually here - TM 1/17/2012 for i in range(len(formset.forms)): formset.forms[i].instance = tasks[i] context['formset'] = formset context['date'] = date a_day = datetime.timedelta(days=1) context['previous_date'] = date - a_day context['next_date'] = date + a_day context['old_rotations'] = old_rotations(date) context['turnout'] = models.turnout(date.date()) template = loader.get_template('scheduling/timecard.html') return HttpResponse(template.render(context))