Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
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))
Ejemplo n.º 3
0
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))
Ejemplo n.º 4
0
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))
Ejemplo n.º 5
0
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))
Ejemplo n.º 6
0
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))
Ejemplo n.º 7
0
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))
Ejemplo n.º 8
0
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))
Ejemplo n.º 9
0
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))
Ejemplo n.º 10
0
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))
Ejemplo n.º 11
0
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))
Ejemplo n.º 12
0
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))
Ejemplo n.º 13
0
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))
Ejemplo n.º 14
0
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))
Ejemplo n.º 15
0
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))
Ejemplo n.º 16
0
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))
Ejemplo n.º 17
0
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))
Ejemplo n.º 18
0
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))
Ejemplo n.º 19
0
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))
Ejemplo n.º 20
0
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))
Ejemplo n.º 21
0
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))