def member_signup_edit(request, id=None): if not has_elevated_perm(request,'membership','edit_membersignup'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) template = get_template('membership/member_signup_edit.html') if request.method == "POST": if 'cancel' in request.POST: return HttpResponseRedirect(reverse('member-signup-review')) else: if id: form = forms.MemberSignUpEditForm(request.POST, instance=models.MemberSignUp.objects.get(pk=id)) else: form = forms.MemberSignUpEditForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('member-signup-review')) else: if id: form = forms.MemberSignUpEditForm(instance=models.MemberSignUp.objects.get(pk=id)) context["edit"] = True else: form = forms.MemberSignUpEditForm() context['form'] = form return HttpResponse(template.render(context))
def close_out(request, date=None): '''Page to double-check payment amounts''' if not has_elevated_perm(request, 'accounting', 'add_transaction'): return HttpResponseRedirect(reverse('welcome')) #if not cashier_permission(request): # return HttpResponse('Sorry, you do not have cashier permission. %s' # % request.META['REMOTE_ADDR']) if date: try: date = datetime.date(*time.strptime(date, "%Y-%m-%d")[0:3]) except ValueError: raise Http404 else: date = datetime.date.today() trans = models.Transaction.objects.filter( timestamp__range=(date, date+datetime.timedelta(1))) columns = [{'type': 'Credit / Debit', 'total': 0, 'transactions': trans.filter(payment_type__in=('C','D'))}, {'type': 'Check / Money Order', 'total': 0, 'transactions': trans.filter(payment_type__in=('K','M'))}, {'type': 'EBT', 'total': 0, 'transactions': trans.filter(payment_type='E')}] for column in columns: if 'order_by' in request.GET: order_by = request.GET['order_by'] column['transactions'] = column['transactions'].order_by(order_by) for trans in column['transactions']: if not trans.fixes_target(): column['total'] += trans.fixed_payment_amount() return render_to_response('accounting/close_out.html', locals(), context_instance=RequestContext(request))
def accounts(request): ''' list of accounts ''' context = RequestContext(request) if not has_elevated_perm(request,'membership','add_account'): accounts = request.user.get_profile().accounts.all() if len(accounts) == 1: return HttpResponseRedirect(accounts[0].get_absolute_url()) else: accounts = models.Account.objects.all() if 'sort_by' in request.GET: form = forms.AccountListFilterForm(request.GET) else: form = forms.AccountListFilterForm() if 'sort_by' in request.GET and form.is_valid(): if form.cleaned_data['inactive'] and form.cleaned_data['active']: accounts = models.Account.objects.all() elif form.cleaned_data['inactive']: accounts = models.Account.objects.inactive() elif form.cleaned_data['active']: accounts = models.Account.objects.active() else: accounts = models.Account.objects.none() if form.cleaned_data['organizations']: accounts = accounts.filter(account_type='o') search = form.cleaned_data.get('search') if search: accounts = accounts.filter( Q(name__icontains=search) | Q(note__icontains=search)) sort = form.cleaned_data['sort_by'] if sort == 'alpha': accounts = accounts.order_by('name') elif sort == 'recent': accounts = accounts.order_by('-id') elif sort == 'hours': accounts = accounts.order_by('-hours_balance') elif sort == 'balance': accounts = accounts.order_by('-balance') else: accounts = models.Account.objects.active() context['form'] = form pager = p.Paginator(accounts, PER_PAGE) context['pager'] = pager page_number = request.GET.get('p') context['page'] = _get_current_page(pager, page_number) context['query_string'] = request.META['QUERY_STRING'].split('&p=', 1)[0] template = get_template('membership/accounts.html') return HttpResponse(template.render(context))
def locations(request): """ list of all event locations """ if not has_elevated_perm(request, "locations", "add_location"): return HttpResponseRedirect(reverse("welcome")) context = RequestContext(request) context["locations"] = models.Location.objects.order_by("-active", "name") template = get_template("events/locations.html") return HttpResponse(template.render(context))
def locations(request): ''' list of all event locations ''' if not has_elevated_perm(request, 'locations', 'add_location'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) context['locations'] = models.Location.objects.order_by('-active', 'name') template = get_template('events/locations.html') return HttpResponse(template.render(context))
def account_form(request, id=None): ''' edit account info ''' if not has_elevated_perm(request, 'membership', 'add_account'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) if id: account = get_object_or_404(models.Account, id=id) context['edit'] = True old_values = copy.deepcopy(account.__dict__) else: account = models.Account() if request.method == 'POST': if 'cancel' in request.POST: if id: return HttpResponseRedirect(reverse('account', args=[id])) else: return HttpResponseRedirect(reverse('accounts')) if 'delete' in request.POST: account.delete() log(request, account, 'delete') return HttpResponseRedirect(reverse('accounts')) form = forms.AccountForm(request.POST, instance=account) related_member_formset = forms.RelatedMemberFormSet(request.POST, instance=account, prefix='related_member') if form.is_valid() and related_member_formset.is_valid(): if context.get('edit'): account = form.save() log(request, account, 'edit', old_values=old_values) else: account = form.save() log(request, account, 'add') _setattr_formset_save(request, related_member_formset, 'account', account) return HttpResponseRedirect(reverse('account', args=[account.id])) else: form = forms.AccountForm(instance=account) related_member_formset = forms.RelatedMemberFormSet(instance=account, prefix='related_member') context['account'] = account context['form'] = form context['formsets'] = [ (related_member_formset, 'Members'), ] template = get_template('membership/account_form.html') return HttpResponse(template.render(context))
def account(request, id): ''' individual account page ''' account = get_object_or_404(models.Account, id=id) request_member = models.Member.objects.get(user=request.user) if (not has_elevated_perm(request,'membership','add_member') and not (request.user.is_authenticated() and request_member in account.members.all())): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) context['account'] = account transactions = account.transaction_set.order_by('-id')[:50] context['transactions'] = transactions template = get_template('membership/account.html') return HttpResponse(template.render(context))
def orientations(request): """ list of all orientations, the most recent first """ if not has_elevated_perm(request, "events", "add_orientation"): return HttpResponseRedirect(reverse("welcome")) context = RequestContext(request) upcoming_orientations = models.Orientation.objects.filter(start__gte=datetime.now()).order_by("-start") special_orientations = [models.Orientation.objects.get(pk=1), models.Orientation.objects.get(pk=2)] context["upcoming_orientations"] = upcoming_orientations context["special_orientations"] = special_orientations template = get_template("events/orientations.html") return HttpResponse(template.render(context))
def member(request, username): ''' individual member page ''' user = get_object_or_404(User, username=username) if (not has_elevated_perm(request,'membership','change_member') and (not (request.user.is_authenticated() and request.user.id == user.id))): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) member = user.get_profile() context['member'] = member # to get around silly {% url %} limits context['address_name'] = 'address' context['email_name'] = 'email' context['phone_name'] = 'phone' template = get_template('membership/member.html') return HttpResponse(template.render(context))
def members(request): ''' list of all members (active by default) ''' if not has_elevated_perm(request,'membership','add_member'): return HttpResponseRedirect(reverse('member', args=[request.user.username])) context = RequestContext(request) members = models.Member.objects.all() if 'sort_by' in request.GET: form = forms.MemberListFilterForm(request.GET) if form.is_valid(): search = form.cleaned_data.get('search') if search: members = members.filter( Q(user__first_name__icontains=search) | Q(user__last_name__icontains=search)) sort = form.cleaned_data['sort_by'] if sort == 'alpha': members = members.order_by('user__username') elif sort == 'oldjoin': members = members.order_by('date_joined') elif sort == 'newjoin': members = members.order_by('-date_joined') if not form.cleaned_data['active']: members = members.exclude(date_missing__isnull=True, date_departed__isnull=True) if not form.cleaned_data['missing']: members = members.exclude(date_missing__isnull=False) if not form.cleaned_data['departed']: members = members.exclude(date_departed__isnull=False) else: form = forms.MemberListFilterForm() members = members.filter(date_missing__isnull=True, date_departed__isnull=True) context['form'] = form pager = p.Paginator(members, PER_PAGE) context['pager'] = pager page_number = request.GET.get('p') context['page'] = _get_current_page(pager, page_number) # drop any p= queries from the query string context['query_string'] = request.META['QUERY_STRING'].split('&p=', 1)[0] template = get_template('membership/members.html') return HttpResponse(template.render(context))
def orientations(request): ''' list of all orientations, the most recent first ''' if not has_elevated_perm(request, 'events', 'add_orientation'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) recent_orientations = models.Orientation.objects.filter(start__gte=(datetime.datetime.now() - datetime.timedelta(3))).filter(start__lte=datetime.datetime.now()).order_by('-start') upcoming_orientations = models.Orientation.objects.filter(start__gte=datetime.datetime.now()).order_by('-start') special_orientations = [models.Orientation.objects.get(pk=1), models.Orientation.objects.get(pk=2)] context['recent_orientations'] = recent_orientations context['upcoming_orientations'] = upcoming_orientations context['special_orientations'] = special_orientations template = get_template('events/orientations.html') return HttpResponse(template.render(context))
def hours_balance(request): if not has_elevated_perm(request, 'accounting', 'add_transaction'): return HttpResponseRedirect(reverse('welcome')) if 'getcashierinfo' in request.GET: account_id = request.GET['account'] account = m_models.Account.objects.get(id=account_id) return HttpResponse(account.hours_balance) if request.method == 'POST': form = forms.HoursBalanceForm(request.POST) if form.is_valid(): hourstransaction = form.save(commit=False) # get info from form hourstransaction.entered_by = request.user # add entered_by hourstransaction.save() # save to database return HttpResponseRedirect(reverse('hours_balance')) else: form = forms.HoursBalanceForm() hours_transactions = models.HoursTransaction.objects.filter( timestamp__range=(today,today+datetime.timedelta(1))) return render_to_response('accounting/hours_balance.html', locals(), context_instance=RequestContext(request))
def transaction(request): # if not cashier_permission(request): # return HttpResponse('Sorry, you do not have cashier permission. %s' # % request.META['REMOTE_ADDR']) if not has_elevated_perm(request, 'accounting', 'add_transaction'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) if 'getcashierinfo' in request.GET: account_id = request.GET['account'] account = m_models.Account.objects.get(id=account_id) context['account'] = account if request.GET['getcashierinfo'] == 'members': template = get_template('accounting/snippets/members.html') elif request.GET['getcashierinfo'] == 'transactions': context['transactions'] = account.transaction_set.all() template = get_template('accounting/snippets/transactions.html') elif request.GET['getcashierinfo'] == 'acctinfo': template = get_template('accounting/snippets/acctinfo.html') return HttpResponse(template.render(context)) if request.method == 'POST': form = forms.TransactionForm(request.POST) if form.is_valid(): transaction = form.save(commit=False) # get info from form transaction.entered_by = request.user # add entered_by transaction.save() # save to database return HttpResponseRedirect(reverse('transaction')) else: form = forms.TransactionForm() today = datetime.date.today() transactions = models.Transaction.objects.filter( timestamp__range=(today,today+datetime.timedelta(1))) context = { 'transactions':transactions, 'form':form, 'can_reverse':True, } return render_to_response('accounting/transaction.html', context, context_instance=RequestContext(request))
def EBT_bulk_orders(request, EBTBulkOrder_id=None): # probably want to switch this to only list unpaid if not has_elevated_perm(request, 'accounting', 'add_ebt_bulk_order'): return HttpResponseRedirect(reverse('welcome')) if EBTBulkOrder_id: ebt_bo = get_object_or_404(models.EBTBulkOrder, id=EBTBulkOrder_id) else: ebt_bo = models.EBTBulkOrder() is_errors = False ret_resp = HttpResponseRedirect(reverse('EBT-bulk-orders')) if request.method == 'POST': if 'cancel' in request.POST: return ret_resp ebt_bo_form = forms.EBTBulkOrderForm(request.POST, instance=ebt_bo) if ebt_bo_form.is_valid(): ebt_bo_form.save() return ret_resp else: is_errors = True else: ebt_bo_form = forms.EBTBulkOrderForm(instance=ebt_bo) unpaid = models.EBTBulkOrder.objects.unpaid() context = { 'unpaid': unpaid.order_by('-id'), 'total_unpaid': unpaid.aggregate(Sum('amount')).values()[0], 'paid': models.EBTBulkOrder.objects.paid().order_by('-id')[:20], 'ebt_bo': ebt_bo, 'is_errors': is_errors, 'form': ebt_bo_form, 'add': EBTBulkOrder_id==None, #this bool determines template behavior } return render_to_response('accounting/EBT_bulk_orders.html', context, context_instance=RequestContext(request))
def timecard(request, date=None): context = RequestContext(request) 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']) 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. ''' task = models.Task.objects.get(id=request.POST['form-' + str(n) + '-id']) task.reminder_call = request.POST['form-' + str(n) + '-reminder_call'] 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 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))
def member_signup_review(request): if not has_elevated_perm(request,'membership','add_member'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) MemberSignUpReviewFormSet = formset_factory(forms.MemberSignUpReviewForm) ''' We have to populate the choices for the referring member form item. We could have done this in the form itself, but that would have caused each and every form to hit the database for the list of members, so instead we do one query on the database here and set it for each form we are about to show to the user. Here we just create the list, and we set it in each form later. The key here is that the choices have to be set before each form is validated. ''' #members = models.Member.objects.filter(date_departed__isnull=True) #member_choices = [('','')] #for member in members: # member_choices.append((member.id, str(member))) if request.method == "POST": formset = MemberSignUpReviewFormSet(request.POST) review_action = request.POST["review_action"] context["review_action"] = review_action record_ids = request.POST["record_ids"].split(',') record_states = request.POST["record_states"].split(',') new_members = [] formset_errors = False for n in range(0, formset.total_form_count()): new_member = models.MemberSignUp.objects.get(id=record_ids[n]) new_members.append(new_member) if record_states[n] == RECORD_STATE_INACTIVE: continue form = formset.forms[n] #form.set_referring_member_choices(member_choices) # We need to check if a given form has been selected, but the selected # value only appears in POST if the user has actually selected... I am sure there # is a better way to handle this, but I don't have time to figure it out now - TM try: if not request.POST['form-' + str(n) + '-selected']: # We clear any validation errors on forms that haven't been selected form.errors.clear() continue except MultiValueDictKeyError: # if the form wasn't selected, then we can just continue on to the next one #formset.data['form-' + str(n) + '-record_id'] = unicode(new_member.id) form.errors.clear() continue if review_action == "spam": new_member.spam = True new_member.active = False new_member.save() record_states[n] = RECORD_STATE_INACTIVE elif review_action == "delete": new_member.active = False new_member.save() record_states[n] = RECORD_STATE_INACTIVE elif review_action == "save": if form.is_valid(): # Create user user = User.objects.create_user(form.cleaned_data['user_name'].strip(), password=User.objects.make_random_password()) user.email = new_member.email user.first_name = new_member.first_name user.last_name = new_member.last_name ''' We save this here because the user needs a primary key value before we can add a group ''' user.save() user.groups.add(Group.objects.get(name="member")) user.save() log(request, user, 'add') # Create member member = models.Member() member.user = user member.status = 'd' # departed member.work_status = 'n' # no workshift # Per Dana: the departed date is set to a very specific value for new members # depending upon whether or not they have paid for the equity at sign up if form.cleaned_data["payment_verified"] and new_member.equity_paid > 0: member.date_departed = datetime.date(1904, 01, 01) else: member.date_departed = datetime.date(1904, 02, 02) member.referral_source = new_member.referral_source member.orientation = new_member.orientation member.referring_member = form.cleaned_data["referring_member"]; #if form.cleaned_data["referring_member"] and member.referral_source == "Current Member": # member.referring_member = models.Member.objects.get(id=form.cleaned_data["referring_member"]) member.save() log(request, member, 'add') address = models.Address() address.type = 'h' address.address1 = new_member.address1 address.address2 = new_member.address2 address.city = new_member.city address.state = new_member.state address.postal_code = new_member.postal_code address.country = new_member.country address.member = member address.save() phone = models.Phone() phone.type = 'h' phone.number = new_member.phone phone.member = member phone.save() # Create account current_date = unicode(datetime.date.today()) account = models.Account() account.name = unicode(new_member) + " " + current_date account.note = u'Joined Online %s' % current_date account.save() log(request, account, 'add') # Create account member account_member = models.AccountMember.objects.create(account=account, member=member) log(request, account_member, 'add') # Perform equity transaction if there was one if form.cleaned_data["payment_verified"] and new_member.equity_paid > 0: equity_transaction = a_models.Transaction.objects.create(account=account, member=member, purchase_type='O', purchase_amount=Decimal(new_member.equity_paid), note=u'Joined Online %s' % current_date) equity_transaction = a_models.Transaction.objects.create(account=account, member=member, purchase_type='S', purchase_amount=Decimal(0) - Decimal(new_member.equity_paid), note=u'Joined Online %s' % current_date) new_member.saved = True new_member.save() record_states[n] = RECORD_STATE_INACTIVE else: formset_errors = True # If there are no errors, just return a fresh GET request if not formset_errors: return HttpResponseRedirect(reverse('member-signup-review')) else: new_members = models.MemberSignUp.objects.filter(saved=False).filter(spam=False).filter(active=True) new_members_count = new_members.count() record_ids = [] record_states = [] for n in range(0, new_members_count): record_ids.append(str(new_members[n].id)) record_states.append(RECORD_STATE_ACTIVE) data = { 'form-TOTAL_FORMS': unicode(new_members_count), 'form-INITIAL_FORMS': unicode(new_members_count), 'form-MAX_NUM_FORMS': u'', } formset = MemberSignUpReviewFormSet(data) ''' We have to clear the errors on a GET request because for some reason the forms are trying to validate, even on GETs. We also take the opportunity to set the referring member choices here ''' for form in formset.forms: form.errors.clear() #form.set_referring_member_choices(member_choices) context["formset"] = formset context["record_ids"] = ','.join(record_ids) context["record_states"] = ','.join(record_states) context["formset_members_recordstates"] = zip(formset.forms, new_members, record_states) template = get_template('membership/member_signup_review.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))
def account_form(request, id=None): ''' edit account info ''' if not has_elevated_perm(request, 'membership', 'add_account'): return HttpResponseRedirect(reverse('welcome')) context = RequestContext(request) if id: account = get_object_or_404(models.Account, id=id) context['edit'] = True old_values = copy.deepcopy(account.__dict__) else: account = models.Account() if request.method == 'POST': if 'cancel' in request.POST: if id: return HttpResponseRedirect(reverse('account', args=[id])) else: return HttpResponseRedirect(reverse('accounts')) if 'delete' in request.POST: #account.delete() #log(request, account, 'delete') return HttpResponseRedirect(reverse('accounts')) form = forms.AccountForm(request.POST, instance=account) related_member_formset = forms.RelatedMemberFormSet(request.POST, instance=account, prefix='related_member') if form.is_valid() and related_member_formset.is_valid(): if context.get('edit'): account = form.save() log(request, account, 'edit', old_values=old_values) else: account = form.save() log(request, account, 'add') #account_log_entry = c_models.LogEntry() #account_log_entry.record_entry(account, request.user) #account_log_entry.save() _setattr_formset_save(request, related_member_formset, 'account', account) ''' We call account.save once last time here because this it is during account's post_save signal that the new account revision is created, and we need that formset saved before getting an accurate revision ''' account.save() return HttpResponseRedirect(reverse('account', args=[account.id])) else: form = forms.AccountForm(instance=account) related_member_formset = forms.RelatedMemberFormSet(instance=account, prefix='related_member') context['account'] = account context['form'] = form context['formsets'] = [ (related_member_formset, 'Members'), ] template = get_template('membership/account_form.html') return HttpResponse(template.render(context))
def member_form(request, username=None): ''' edit member info ''' edit = bool(username) if edit: user = get_object_or_404(User, username=username) member = user.get_profile() else: user = User() member = models.Member() is_errors = False if request.method == 'POST': if 'cancel' in request.POST: if edit: # FIXME this is bad if member has more than one account return HttpResponseRedirect(member.accounts.all()[0].get_absolute_url()) else: return HttpResponseRedirect(reverse('accounts')) if 'delete' in request.POST: member.delete() user.delete() return HttpResponseRedirect(reverse('accounts')) user_form = forms.UserForm(request.POST, prefix='user', instance=user) user_email_form = forms.UserEmailForm(request.POST, instance=user) member_form = forms.MemberForm(request.POST, prefix='member', instance=member) if has_elevated_perm(request, 'membership', 'add_member'): related_account_formset = forms.RelatedAccountFormSet(request.POST, instance=member, prefix='related_account') LOA_formset = forms.LeaveOfAbsenceFormSet(request.POST, instance=member, prefix='leave_of_absence') address_formset = forms.AddressFormSet(request.POST, instance=member, prefix='address') phone_formset = forms.PhoneFormSet(request.POST, instance=member, prefix='phone') if has_elevated_perm(request, 'membership', 'add_member'): if (user_form.is_valid() and member_form.is_valid() and related_account_formset.is_valid() and LOA_formset.is_valid()): user = user_form.save() member = member_form.save(commit=False) member.user = user member.save() for formset in (related_account_formset, LOA_formset): _setattr_formset_save(request, formset, 'member', member) if not edit: # TODO send member an email with login information see #224 # see also password_reset in django.contrib.auth.views.py pass else: is_errors = True else: if user_email_form.is_valid(): user = user_email_form.save() else: is_errors = True # must be after member.save() in case member is newly added if address_formset.is_valid() and phone_formset.is_valid() and not is_errors: for formset in (address_formset, phone_formset): _setattr_formset_save(request, formset, 'member', member) else: is_errors = True if not is_errors: # FIXME this is bad if member has more than one account try: redirect = member.accounts.all()[0].get_absolute_url() except IndexError: redirect = reverse('accounts') return HttpResponseRedirect(redirect) else: user_form = forms.UserForm(instance=user, prefix='user') user_email_form = forms.UserEmailForm(instance=user) member_form = forms.MemberForm(instance=member, prefix='member') related_account_formset = forms.RelatedAccountFormSet(instance=member, prefix='related_account') address_formset = forms.AddressFormSet(instance=member, prefix='address') phone_formset = forms.PhoneFormSet(instance=member, prefix='phone') LOA_formset = forms.LeaveOfAbsenceFormSet(instance=member, prefix='leave_of_absence') context = RequestContext(request) context['member'] = member context['user_form'] = user_form context['user_email_form'] = user_email_form context['member_form'] = member_form if has_elevated_perm(request, 'membership', 'add_member'): context['formsets'] = [ (related_account_formset, 'Accounts'), (LOA_formset, 'Leaves of Absence'), (address_formset, 'Addresses'), (phone_formset, 'Phones'), ] else: context['formsets'] = [ (address_formset, 'Addresses'), (phone_formset, 'Phones'), ] context['is_errors'] = is_errors context['edit'] = edit template = get_template('membership/member_form.html') return HttpResponse(template.render(context))
def member_form(request, username=None): ''' edit member info ''' edit = bool(username) if edit: user = get_object_or_404(User, username=username) member = user.get_profile() user_old_values = copy.deepcopy(user.__dict__) member_old_values = copy.deepcopy(member.__dict__) else: user = User() user.set_password(User.objects.make_random_password()) member = models.Member() is_errors = False if request.method == 'POST': if 'cancel' in request.POST: if edit: # FIXME this is bad if member has more than one account return HttpResponseRedirect(member.accounts.all()[0].get_absolute_url()) else: return HttpResponseRedirect(reverse('accounts')) if 'delete' in request.POST: # We dpn't allow deleting members from MESS anymore #member.delete() #user.delete() return HttpResponseRedirect(reverse('accounts')) user_form = forms.UserForm(request.POST, prefix='user', instance=user) user_email_form = forms.UserEmailForm(request.POST, instance=user) member_form = forms.MemberForm(request.POST, prefix='member', instance=member) member_interest_form = forms.MemberInterestForm(request.POST, prefix='member_interest', instance=member) if has_elevated_perm(request, 'membership', 'add_member'): related_account_formset = forms.RelatedAccountFormSet(request.POST, instance=member, prefix='related_account') LOA_formset = forms.LeaveOfAbsenceFormSet(request.POST, instance=member, prefix='leave_of_absence') address_formset = forms.AddressFormSet(request.POST, instance=member, prefix='address') phone_formset = forms.PhoneFormSet(request.POST, instance=member, prefix='phone') if has_elevated_perm(request, 'membership', 'add_member'): if (user_form.is_valid() and member_form.is_valid() and related_account_formset.is_valid() and LOA_formset.is_valid()): user = user_form.save() member = member_form.save(commit=False) member.user = user member.save() member_form.save_m2m() if edit: log(request, user, 'edit', old_values=user_old_values) log(request, member, 'edit', old_values=member_old_values) else: log(request, user, 'add') log(request, member, 'add') for formset in (related_account_formset, LOA_formset): _setattr_formset_save(request, formset, 'member', member) ''' We perform one more member.save() after the formsets have been saved. We do this because it is during the post_save of member.save() that the member revision is created, and to ensure we get an accurate revision the formset has to have been saved ''' member.save() if not edit: # TODO send member an email with login information see #224 # see also password_reset in django.contrib.auth.views.py pass else: is_errors = True else: if user_email_form.is_valid(): user = user_email_form.save() else: is_errors = True # We notify the member coordinator if a non-staff user has updated # their own profile if not request.user.is_staff and request.user.id == member_instance.user.id: notify_member_coordinator(member_instance) # must be after member.save() in case member is newly added if address_formset.is_valid() and phone_formset.is_valid() and not is_errors: for formset in (address_formset, phone_formset): _setattr_formset_save(request, formset, 'member', member) else: is_errors = True if member_interest_form.is_valid() and not is_errors: member_instance = member_interest_form.save(commit=False) member_instance.availability = get_member_availability(member_interest_form) member_instance.save() member_interest_form.save_m2m() else: is_errors = True if not is_errors: # FIXME this is bad if member has more than one account try: redirect = member.accounts.all()[0].get_absolute_url() except IndexError: redirect = reverse('accounts') return HttpResponseRedirect(redirect) else: user_form = forms.UserForm(instance=user, prefix='user') user_email_form = forms.UserEmailForm(instance=user) member_form = forms.MemberForm(instance=member, prefix='member') member_interest_form = forms.MemberInterestForm(instance=member, prefix='member_interest') set_member_availability(member, member_interest_form) related_account_formset = forms.RelatedAccountFormSet(instance=member, prefix='related_account') address_formset = forms.AddressFormSet(instance=member, prefix='address') phone_formset = forms.PhoneFormSet(instance=member, prefix='phone') LOA_formset = forms.LeaveOfAbsenceFormSet(instance=member, prefix='leave_of_absence') context = RequestContext(request) context['member'] = member context['user_form'] = user_form context['user_email_form'] = user_email_form context['member_form'] = member_form context['member_interest_form'] = member_interest_form if has_elevated_perm(request, 'membership', 'add_member'): context['formsets'] = [ (related_account_formset, 'Accounts'), (LOA_formset, 'Leaves of Absence'), (address_formset, 'Addresses'), (phone_formset, 'Phones'), ] else: context['formsets'] = [ (address_formset, 'Addresses'), (phone_formset, 'Phones'), ] context['is_errors'] = is_errors context['edit'] = edit template = get_template('membership/member_form.html') return HttpResponse(template.render(context))
def schedule(request, date=None): context = RequestContext(request) if not has_elevated_perm(request, 'scheduling', 'add_task'): 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) add_time = date + datetime.timedelta(hours=9) add_task_form = forms.TaskForm(instance=models.Task(time=add_time), prefix='add') add_recur_form = forms.RecurForm(prefix='recur-add') tasks = models.Task.objects.filter(time__year=date.year).filter( time__month=date.month).filter(time__day=date.day).order_by( 'time', 'hours', 'job', '-recur_rule') prepared_tasks = [] for index, task in enumerate(tasks): task.form = forms.TaskForm(instance=task, prefix=str(index)) task.recur_form = forms.RecurForm(instance=task.recur_rule, prefix='recur-%s' % index) prepared_tasks.append(task) if request.method == 'POST': if 'save-add' in request.POST: task_form = add_task_form = forms.TaskForm(request.POST, prefix='add') recur_form = add_recur_form = forms.RecurForm(request.POST, prefix='recur-add') else: task_index = request.POST.get('task-index') task = prepared_tasks[int(task_index)] if 'duplicate' in request.POST: task.excused = True task.save() task.duplicate() return HttpResponseRedirect(reverse('scheduling-schedule', args=[date.date()])) elif 'remove' in request.POST: if task.recur_rule: future_tasks = task.recur_rule.task_set.filter( time__gt=task.time) for future_task in future_tasks: future_task.delete() task.delete() return HttpResponseRedirect(reverse('scheduling-schedule', args=[date.date()])) task_form = task.form = forms.TaskForm(request.POST, instance=task, prefix=task_index) recur_form = task.recur_form = forms.RecurForm(request.POST, instance=task.recur_rule, prefix='recur-%s' % task_index) if task_form.is_valid() and recur_form.is_valid(): task = task_form.save() frequency = recur_form.cleaned_data['frequency'] interval = recur_form.cleaned_data['interval'] until = recur_form.cleaned_data['until'] if frequency and interval: task.set_recur_rule(frequency, interval, until) task.update_buffer() return HttpResponseRedirect(reverse('scheduling-schedule', args=[date.date()])) # else... if request.method != POST elif request.GET.has_key('jump_to_task_id'): try: context['jump_to_task_id'] = int(request.GET['jump_to_task_id']) except: pass context['date'] = date a_day = datetime.timedelta(days=1) context['previous_date'] = date - a_day context['next_date'] = date + a_day firstday = date + relativedelta(day=1) lastday = date + relativedelta(day=31) context['cal_json'] = simplejson.dumps(unassigned_days(firstday, lastday)) context['tasks'] = prepared_tasks context['add_task_form'] = add_task_form context['add_recur_form'] = add_recur_form # to include autocomplete js media files: context['form'] = {'media':add_task_form.media} template = loader.get_template('scheduling/schedule.html') return HttpResponse(template.render(context))