コード例 #1
0
def eventseries(request, id):
    series = get_object_or_404(ConferenceSeries, pk=id)
    events = list(series.conference_set.filter(promoactive=True).order_by('startdate'))

    return render(request, 'events/series.html', {
        'series': series,
        'upcoming': [e for e in events if e.enddate >= today_global()],
        'past': [e for e in events if e.enddate < today_global()],
    })
コード例 #2
0
def pastevents(request):
    events = list(Conference.objects.filter(promoactive=True, enddate__gte=today_global()).order_by('startdate'))
    past = Conference.objects.filter(promoactive=True, enddate__lt=today_global()).order_by('-startdate')
    series = ConferenceSeries.objects.filter(visible=True).extra(
        where=["EXISTS (SELECT 1 FROM confreg_conference c WHERE c.series_id=confreg_conferenceseries.id AND c.promoactive)"]
    )

    return render(request, 'events/past.html', {
        'events': events,
        'past': past,
        'series': series,
    })
コード例 #3
0
def eventsindex(request):
    events = list(Conference.objects.filter(promoactive=True, enddate__gte=today_global()).order_by('startdate'))
    past = Conference.objects.filter(promoactive=True, enddate__lt=today_global()).order_by('-startdate')[:5]
    series = ConferenceSeries.objects.filter(visible=True).extra(
        where=["EXISTS (SELECT 1 FROM confreg_conference c WHERE c.series_id=confreg_conferenceseries.id AND c.promoactive)"]
    )

    return render(request, 'events/index.html', {
        'events': events,
        'past': past,
        'series': series,
        'regopen': [e for e in events if e.active],
        'cfpopen': [e for e in events if e.callforpapersopen],
        'cfsopen': [e for e in events if e.callforsponsorsopen],
    })
コード例 #4
0
ファイル: views.py プロジェクト: sfrost/pgeu-system
def _meeting(request, member, meeting, isproxy):
    if not (member.paiduntil and member.paiduntil >= today_global()):
        return HttpResponse("Your membership is not active")

    if not meeting.allmembers:
        if not meeting.members.filter(pk=member.pk).exists():
            return HttpResponse("Access denied.")

    # Allow four hours in the past, just in case
    if meeting.dateandtime + timedelta(hours=4) < timezone.now():
        return HttpResponse("Meeting is in the past.")

    if member.paiduntil < timezone.localdate(meeting.dateandtime):
        return HttpResponse("Your membership expires before the meeting")

    if not meeting.joining_active:
        return HttpResponse("This meeting is not open for joining yet")

    # All is well with this member. Generate a key if necessary
    (key, created) = MemberMeetingKey.objects.get_or_create(member=member, meeting=meeting)
    if created:
        # New key!
        key.key = base64.urlsafe_b64encode(os.urandom(40)).rstrip(b'=').decode('utf8')
        key.save()

    if key.proxyname and not isproxy:
        return HttpResponse("You have assigned a proxy attendee for this meeting ({0}). This means you cannot attend the meeting yourself.".format(key.proxyname))

    return render(request, 'membership/meeting.html', {
        'member': member,
        'meeting': meeting,
        'key': key,
        })
コード例 #5
0
    def handle(self, *args, **options):
        # Only conferences that are actually running right now need to be considered.
        # Normally this is likely just one.
        for conference in Conference.objects.filter(
                startdate__lte=today_global() + timedelta(days=2),
                enddate__gte=today_global() - timedelta(days=2)):

            # Re-get the conference object to switch the timezone for django
            conference = get_conference_or_404(conference.urlname)

            with transaction.atomic():
                # Sessions that can take reminders
                for s in ConferenceSession.objects.select_related('room') \
                                                  .filter(conference=conference,
                                                          starttime__gt=timezone.now(),
                                                          starttime__lt=timezone.now() + timedelta(minutes=15),
                                                          status=1,
                                                          reminder_sent=False):

                    send_private_broadcast(
                        conference,
                        'The session "{0}" will start soon (at {1}){2}'.format(
                            s.title,
                            timezone.localtime(s.starttime).strftime("%H:%M"),
                            s.room and " in room {}".format(s.room) or '',
                        ),
                        expiry=timedelta(minutes=15))

                    # Now also send DM reminders out to the speakers who have registered to get one
                    for reg in ConferenceRegistration.objects.filter(
                            conference=conference,
                            attendee__speaker__conferencesession=s):

                        msg = """Hello! We'd like to remind you that your session "{0}" is starting soon (at {1}) in room {2}.""".format(
                            s.title,
                            timezone.localtime(s.starttime).strftime("%H:%M"),
                            s.room and s.room.roomname or 'unknown',
                        )

                        # Send the message. Make it expire in 15 minutes, because that's after
                        # the session started anyway.
                        send_reg_direct_message(reg,
                                                msg,
                                                expiry=timedelta(minutes=15))

                    s.reminder_sent = True
                    s.save()
コード例 #6
0
 def expiressoon(self):
     if self.paiduntil:
         if self.paiduntil < today_global() + timedelta(days=60):
             return True
         else:
             return False
     else:
         return True
コード例 #7
0
ファイル: views.py プロジェクト: tourdownunder/pgeu-system
def home(request):
    elections = Election.objects.filter(isopen=True).order_by('startdate')
    open_elections = [
        e for e in elections
        if e.startdate <= today_global() and e.enddate >= today_global()
    ]
    past_elections = [
        e for e in elections
        if e.startdate < today_global() and e.enddate < today_global()
    ]
    upcoming_elections = [e for e in elections if e.startdate > today_global()]

    return render(
        request, 'elections/home.html', {
            'open': open_elections,
            'past': past_elections,
            'upcoming': upcoming_elections,
        })
コード例 #8
0
 def should_run(self):
     # Are there any conferences open for registration, conference is still in the future,
     # that have additional options with autocancel set
     return Conference.objects.filter(
         active=True,
         conferenceadditionaloption__invoice_autocancel_hours__isnull=
         False,
         enddate__gt=today_global() + timedelta(days=1),
     ).exists()
コード例 #9
0
ファイル: views.py プロジェクト: sfrost/pgeu-system
def meeting_proxy(request, meetingid):
    # Assign proxy voter for meeting
    meeting = get_object_or_404(Meeting, pk=meetingid)
    member = get_object_or_404(Member, user=request.user)

    if not (member.paiduntil and member.paiduntil >= today_global()):
        return HttpResponse("Your membership is not active")

    if not meeting.allmembers:
        if not meeting.members.filter(pk=member.pk).exists():
            return HttpResponse("Access denied.")

    if member.paiduntil < timezone.localdate(meeting.dateandtime):
        return HttpResponse("Your membership expires before the meeting")

    # Do we have one already?
    try:
        key = MemberMeetingKey.objects.get(member=member, meeting=meeting)
    except MemberMeetingKey.DoesNotExist:
        key = MemberMeetingKey()
        key.meeting = meeting
        key.member = member

    initial = {
        'name': key.proxyname,
    }

    if request.method == 'POST':
        form = ProxyVoterForm(initial=initial, data=request.POST)
        if form.is_valid():
            if form.cleaned_data['name']:
                key.proxyname = form.cleaned_data['name']
                key.proxyaccesskey = generate_random_token()
                key.key = base64.urlsafe_b64encode(os.urandom(40)).rstrip(b'=').decode('utf8')
                key.save()
                MemberLog(member=member,
                          timestamp=timezone.now(),
                          message="Assigned {0} as proxy voter in {1}".format(key.proxyname, meeting.name)
                ).save()
                return HttpResponseRedirect('.')
            else:
                key.delete()
                MemberLog(member=member,
                          timestamp=timezone.now(),
                          message="Canceled proxy voting in {0}".format(meeting.name)
                ).save()
                return HttpResponseRedirect("../../")
    else:
        form = ProxyVoterForm(initial=initial)

    return render(request, 'membership/meetingproxy.html', {
        'member': member,
        'meeting': meeting,
        'key': key,
        'form': form,
        })
コード例 #10
0
def attendee_events(request):
    events = list(Conference.objects.filter(promoactive=True, enddate__gte=today_global()).order_by('startdate'))
    series = ConferenceSeries.objects.filter(visible=True).extra(
        where=["EXISTS (SELECT 1 FROM confreg_conference c WHERE c.series_id=confreg_conferenceseries.id AND c.promoactive)"]
    )
    attended = Conference.objects.only('urlname', 'conferencename', 'location').filter(conferenceregistration__attendee=request.user, conferenceregistration__payconfirmedat__isnull=False).distinct().order_by('-startdate')
    return render(request, 'events/attendee.html', {
        'attended': attended,
        'events': events,
        'series': series,
    })
コード例 #11
0
    def process_invoice_payment(self, invoice):
        # We'll get the member from the processorid
        try:
            member = Member.objects.get(pk=invoice.processorid)
        except member.DoesNotExist:
            raise Exception("Could not find member id %s for invoice!" %
                            invoice.processorid)

        cfg = get_config()

        # The invoice is paid, so it's no longer active!
        # It'll still be in the archive, of course, but not linked from the
        # membership record.
        member.activeinvoice = None

        # Extend the membership. If already paid to a date in the future,
        # extend from that date. Otherwise, from today.
        if member.paiduntil and member.paiduntil > today_global():
            member.paiduntil = member.paiduntil + timedelta(
                days=cfg.membership_years * 365)
        else:
            member.paiduntil = today_global() + timedelta(
                days=cfg.membership_years * 365)
        member.expiry_warning_sent = None

        # If the member isn't already a member, set todays date as the
        # starting date.
        if not member.membersince:
            member.membersince = today_global()

        member.save()

        # Create a log record too, and save it
        MemberLog(
            member=member,
            timestamp=timezone.now(),
            message="Payment for %s years received, membership extended to %s"
            % (cfg.membership_years, member.paiduntil)).save()
コード例 #12
0
ファイル: api.py プロジェクト: sfrost/pgeu-system
    def get_transactions(self, startdate=None, enddate=None):
        if not enddate:
            enddate = today_global() + timedelta(days=1)

        if not startdate:
            startdate = enddate - timedelta(days=60)

        return self.get(
            'borderless-accounts/{0}/statement.json'.format(self.get_account()['id']),
            {
                'currency': settings.CURRENCY_ABBREV,
                'intervalStart': self.format_date(startdate),
                'intervalEnd': self.format_date(enddate),
            },
        )['transactions']
コード例 #13
0
ファイル: views.py プロジェクト: tourdownunder/pgeu-system
def ownvotes(request, electionid):
    election = get_object_or_404(Election, pk=electionid)
    if not election.isopen:
        raise Http404("This election is not open (yet)")

    if election.enddate >= today_global():
        raise Http404("This election has not ended yet")

    member = get_object_or_404(Member, user=request.user)

    votes = Vote.objects.select_related().filter(
        voter=member, election=election).order_by('-score')

    return render(request, 'elections/ownvotes.html', {
        'election': election,
        'votes': votes,
    })
コード例 #14
0
ファイル: views.py プロジェクト: sfrost/pgeu-system
def index(request):
    events = Conference.objects.filter(
        promoactive=True, enddate__gte=today_global()).order_by('startdate')
    series = ConferenceSeries.objects.filter(visible=True).extra(where=[
        "EXISTS (SELECT 1 FROM confreg_conference c WHERE c.series_id=confreg_conferenceseries.id AND c.promoactive)"
    ])

    # Native query, because django ORM vs UNION...
    # If a news item has the flag "high priority until" until a date that's still in the future,
    # make sure it always bubbles to the top of the list. We do this by creating a secondary ordering
    # field to order by first. To make sure we capture all such things, we need to get at least the
    # same number of items from each subset and then LIMIT it once again for the total limit.
    news = exec_to_dict("""WITH main AS (
  SELECT id, NULL::text AS confurl, NULL::text AS urlname, CASE WHEN highpriorityuntil > CURRENT_TIMESTAMP THEN 1 ELSE 0 END AS priosort, datetime, title, summary
  FROM newsevents_news
  WHERE datetime<CURRENT_TIMESTAMP ORDER BY datetime DESC LIMIT 5),
conf AS (
  SELECT n.id, c.confurl, c.urlname, 0 AS priosort, datetime, c.conferencename || ': ' || title AS title, summary
  FROM confreg_conferencenews n
  INNER JOIN confreg_conference c ON c.id=conference_id
  WHERE datetime<CURRENT_TIMESTAMP
  ORDER BY datetime DESC LIMIT 5)
SELECT id, confurl, urlname, datetime, title, summary, priosort FROM main
UNION ALL
SELECT id, confurl, urlname, datetime, title, summary, priosort FROM conf
ORDER BY priosort DESC, datetime DESC LIMIT 5""")
    for n in news:
        n['summaryhtml'] = markdown.markdown(n['summary'])
        if n['confurl']:
            n['itemlink'] = '/events/{0}/news/{1}-{2}/'.format(
                n['urlname'],
                slugify(n['title']),
                n['id'],
            )
        else:
            n['itemlink'] = '/news/{0}-{1}/'.format(slugify(n['title']),
                                                    n['id'])

    return render(request, 'index.html', {
        'events': events,
        'series': series,
        'news': news,
    })
コード例 #15
0
ファイル: views.py プロジェクト: sfrost/pgeu-system
def meetings(request):
    # Only available for actual members
    member = get_object_or_404(Member, user=request.user)
    q = Q(dateandtime__gte=timezone.now() - timedelta(hours=4)) & (Q(allmembers=True) | Q(members=member))
    meetings = Meeting.objects.filter(q).distinct().order_by('dateandtime')

    meetinginfo = [{
        'id': m.id,
        'name': m.name,
        'joining_active': m.joining_active,
        'dateandtime': m.dateandtime,
        'key': m.get_key_for(member),
        } for m in meetings]

    return render(request, 'membership/meetings.html', {
        'active': member.paiduntil and member.paiduntil >= today_global(),
        'member': member,
        'meetings': meetinginfo,
        })
コード例 #16
0
ファイル: views.py プロジェクト: tourdownunder/pgeu-system
def year(request, year):
    authenticate_backend_group(request, 'Accounting managers')

    try:
        year = Year.objects.get(year=int(year))
    except Year.DoesNotExist:
        # Year does not exist, but what do we do about it?
        if int(year) == today_global().year:
            # For current year, we automatically create the year and move on
            year = Year(year=int(year), isopen=True)
            year.save()
            messages.info(
                request,
                "Year {} did not exist in the system, but since it's the current year it has now been created."
                .format(year.year))
        else:
            return HttpResponse(
                "Year {} does not exist in the system, and is not current year."
                .format(int(year)))

    if 'search' in request.GET:
        _setup_search(request, request.GET['search'])
        return HttpResponseRedirect('/accounting/%s/' % year.year)

    (searchterm, entries) = _perform_search(request, year)

    paginator = EntryPaginator(entries)
    currpage = get_int_or_error(request.GET, 'p', 1)

    return render(
        request, 'accounting/main.html', {
            'entries': paginator.page(currpage),
            'page': currpage,
            'pages': paginator.get_pages(currpage),
            'numpages': paginator.num_pages,
            'hasopen': any([not e.closed for e in entries]),
            'year': year,
            'years': Year.objects.all(),
            'reportable_objects': _get_reportable_objects(year),
            'searchterm': searchterm,
        })
コード例 #17
0
ファイル: views.py プロジェクト: tourdownunder/pgeu-system
def oneinvoice(request, invoicenum):
    authenticate_backend_group(request, 'Invoice managers')
    # Called to view an invoice, to edit one, and to create a new one,
    # since they're all based on the same model and form.
    if invoicenum == 'new':
        invoice = Invoice(
            invoicedate=today_global(),
            duedate=today_global() + timedelta(days=30),
        )
    else:
        invoice = get_object_or_404(Invoice, pk=invoicenum)

    def rowfield_callback(field, **kwargs):
        f = field.formfield()
        if invoice.finalized and f:
            if type(f.widget).__name__ == 'TextInput':
                f.widget.attrs['readonly'] = "readonly"
            else:
                f.widget.attrs['disabled'] = True
        return f

    can_delete = not invoice.finalized
    InvoiceRowInlineFormset = inlineformset_factory(Invoice, InvoiceRow, InvoiceRowForm, can_delete=can_delete, formfield_callback=rowfield_callback)

    if request.method == 'POST':
        if request.POST['submit'] == 'Delete':
            # No need to validate before deleting. But we do a double check
            # that the invoice is really not finalized.
            if invoice.finalized:
                raise Exception("Cannot delete a finalized invoice!")
            invoiceid = invoice.id  # Need to save this away since we delete it
            invoice.delete()
            messages.info(request, "Invoice %s deleted." % invoiceid)
            return HttpResponseRedirect('/invoiceadmin/')

        # Disabled SELECTs are not included in the POST. Therefor, we must copy the
        # data over for those fields.
        postcopy = request.POST.copy()
        if not invoicenum == 'new':
            for fld in ('accounting_account', 'accounting_object', ):
                if fld not in postcopy:
                    postcopy[fld] = getattr(invoice, fld)

        form = InvoiceForm(data=postcopy, instance=invoice)
        if form.instance.finalized:
            formset = InvoiceRowInlineFormset(instance=invoice)
        else:
            formset = InvoiceRowInlineFormset(data=postcopy, instance=invoice)
            formset.forms[0].empty_permitted = False
        if form.is_valid():
            if formset.is_valid() or form.instance.finalized:
                if form.instance.finalized:
                    # When finalized, only a very limited set of fields can be
                    # edited. This doesn't include the invoice rows, so don't
                    # even bother to save the fieldset.
                    form.instance.save(update_fields=[fn for fn in form.available_in_finalized if not isinstance(form[fn].field, ModelMultipleChoiceField)])
                    for m in form.instance.allowedmethods.all():
                        if m not in form.cleaned_data['allowedmethods']:
                            form.instance.allowedmethods.remove(m)
                    for i in form.cleaned_data['allowedmethods']:
                        form.instance.allowedmethods.add(i)
                else:
                    # Need to set totalamount to something here, so it doesn't
                    # cause an exception. It'll get fixed when we finalize!
                    if not form.instance.finalized:
                        form.instance.total_amount = -1
                    form.save()
                    formset.save()

                if request.POST['submit'] == 'Finalize':
                    # Finalize this invoice. It's already been saved..
                    wrapper = InvoiceWrapper(form.instance)
                    wrapper.finalizeInvoice()
                elif request.POST['submit'] == 'Preview':
                    return HttpResponseRedirect("/invoiceadmin/%s/preview/" % form.instance.pk)

                return HttpResponseRedirect("/invoiceadmin/%s/" % form.instance.pk)
        # Else fall through
    else:
        form = InvoiceForm(instance=invoice)
        formset = InvoiceRowInlineFormset(instance=invoice)

    if invoice.processor:
        manager = InvoiceManager()
        processor = manager.get_invoice_processor(invoice)
        adminurl = processor.get_admin_url(invoice)
    else:
        adminurl = None
    return render(request, 'invoices/invoiceform.html', {
        'form': form,
        'formset': formset,
        'invoice': invoice,
        'adminurl': adminurl,
        'currency_symbol': settings.CURRENCY_SYMBOL,
        'vatrates': VatRate.objects.all(),
        'breadcrumbs': [('/invoiceadmin/', 'Invoices'), ],
        'helplink': 'payment',
    })
コード例 #18
0
    def handle(self, *args, **options):
        # We're always going to process all conferences, since most will not have any
        # open discount codes.
        filt = Q(sponsor__isnull=False, is_invoiced=False) & (
            Q(validuntil__lte=today_global()) | Q(num_uses__gte=F('maxuses')))
        codes = DiscountCode.objects.annotate(
            num_uses=Count('registrations')).filter(filt)
        for code in codes:
            # Either the code has expired, or it is fully used by now. Time to generate the invoice. We'll also
            # send an email to the sponsor (and the admins) to inform them of what's happening.
            # The invoice will be a one-off one, we don't need a registered manager for it since the
            # discounts have already been given out.

            if code.count == 0:
                # In case there is not a single user, we just notify the user of this and set it to
                # invoiced in the system so we don't try again.
                code.is_invoiced = True
                code.save()
                send_conference_sponsor_notification(
                    code.conference,
                    "[{0}] Discount code expired".format(code.conference),
                    "Discount code {0} has expired without any uses.".format(
                        code.code),
                )

                for manager in code.sponsor.managers.all():
                    send_conference_mail(
                        code.conference,
                        manager.email,
                        "Discount code {0} expired".format(code.code),
                        'confsponsor/mail/discount_expired.txt', {
                            'code': code,
                            'sponsor': code.sponsor,
                            'conference': code.conference,
                        },
                        sender=code.conference.sponsoraddr,
                        receivername='{0} {1}'.format(manager.first_name,
                                                      manager.last_name))
            else:
                # At least one use, so we generate the invoice
                invoicerows = []
                for r in code.registrations.all():
                    if code.discountamount:
                        # Fixed amount discount. Always apply
                        discountvalue = code.discountamount
                    else:
                        # Percentage discount, so we need to calculate it. Ordered discount codes will
                        # only support a registration-only style discount code, so only count it
                        # against that.
                        discountvalue = r.regtype.cost * code.discountpercentage / 100
                    invoicerows.append([
                        'Attendee "{0}"'.format(r.fullname), 1, discountvalue,
                        r.conference.vat_registrations
                    ])
                # All invoices are always due immediately
                manager = InvoiceManager()
                code.invoice = manager.create_invoice(
                    code.sponsor_rep,
                    code.sponsor_rep.email,
                    "{0} {1}".format(code.sponsor_rep.first_name,
                                     code.sponsor_rep.last_name),
                    '%s\n%s' % (code.sponsor.name, code.sponsor.invoiceaddr),
                    '{0} discount code {1}'.format(code.conference, code.code),
                    timezone.now(),
                    timezone.now() + timedelta(days=1),
                    invoicerows,
                    accounting_account=settings.ACCOUNTING_CONFREG_ACCOUNT,
                    accounting_object=code.conference.accounting_object,
                    paymentmethods=code.conference.paymentmethods.all(),
                )
                code.invoice.save()
                code.is_invoiced = True
                code.save()

                wrapper = InvoiceWrapper(code.invoice)
                wrapper.email_invoice()

                # Now also fire off emails, both to the admins and to all the managers of the sponsor
                # (so they know where the invoice was sent).
                send_conference_sponsor_notification(
                    code.conference,
                    "[{0}] Discount code {1} has been invoiced".format(
                        code.conference, code.code),
                    "The discount code {0} has been closed,\nand an invoice has been sent to {1}.\n\nA total of {2} registrations used this code, and the total amount was {3}.\n"
                    .format(
                        code.code,
                        code.sponsor,
                        len(invoicerows),
                        code.invoice.total_amount,
                    ),
                )

                for manager in code.sponsor.managers.all():
                    send_conference_mail(
                        code.conference,
                        manager.email,
                        "Discount code {0} has been invoiced".format(
                            code.code),
                        'confsponsor/mail/discount_invoiced.txt', {
                            'code': code,
                            'conference': code.conference,
                            'sponsor': code.sponsor,
                            'invoice': code.invoice,
                            'curr': settings.CURRENCY_ABBREV,
                            'expired_time': code.validuntil < today_global(),
                        },
                        sender=code.conference.sponsoraddr,
                        receivername='{0} {1}'.format(manager.first_name,
                                                      manager.last_name))
コード例 #19
0
 def should_run(self):
     # We check for conferences to run at two days before and two days after to cover
     # any extreme timezone differences.
     return Conference.objects.filter(startdate__lte=today_global() + timedelta(days=2),
                                      enddate__gte=today_global() - timedelta(days=2)).exists()
コード例 #20
0
ファイル: views.py プロジェクト: sfrost/pgeu-system
def home(request):
    try:
        member = Member.objects.get(user=request.user)
        registration_complete = True

        # We have a batch job that expires members, but do it here as well to make sure
        # the web is up to date with information if necessary.
        if member.paiduntil and member.paiduntil < today_global():
            MemberLog(member=member,
                      timestamp=timezone.now(),
                      message="Membership expired").save()
            member.membersince = None
            member.paiduntil = None
            member.save()

    except Member.DoesNotExist:
        # No record yet, so we create one. Base the information on whatever we
        # have already.
        member = Member(user=request.user, fullname="{0} {1}".format(request.user.first_name, request.user.last_name))
        registration_complete = False

    cfg = get_config()

    if request.method == "POST":
        if request.POST["submit"] == "Generate invoice":
            # Generate an invoice for the user
            if member.activeinvoice:
                raise Exception("This should not happen - generating invoice when one already exists!")

            manager = InvoiceManager()
            processor = InvoiceProcessor.objects.get(processorname="membership processor")
            invoicerows = [('%s - %s years membership - %s' % (settings.ORG_NAME, cfg.membership_years, request.user.email), 1, cfg.membership_cost, None), ]
            member.activeinvoice = manager.create_invoice(
                request.user,
                request.user.email,
                request.user.first_name + ' ' + request.user.last_name,
                '',  # We don't have an address
                '%s membership for %s' % (settings.ORG_NAME, request.user.email),
                timezone.now(),
                timezone.now(),
                invoicerows,
                processor=processor,
                processorid=member.pk,
                canceltime=timezone.now() + timedelta(days=7),
                accounting_account=settings.ACCOUNTING_MEMBERSHIP_ACCOUNT,
                paymentmethods=cfg.paymentmethods.all(),
                )
            member.activeinvoice.save()
            member.save()

            # We'll redirect back to the same page, so make sure
            # someone doing say a hard refresh on the page doesn't
            # cause weird things to happen.
            return HttpResponseRedirect('/membership/')

        form = MemberForm(data=request.POST, instance=member)
        if form.is_valid():
            member = form.save(commit=False)
            member.user = request.user
            member.save()
            if not registration_complete:
                MemberLog(member=member,
                          timestamp=timezone.now(),
                          message="Registration received, awaiting payment").save()
                registration_complete = True  # So we show the payment info!
            elif form.has_changed():
                # Figure out what changed
                MemberLog(member=member,
                          timestamp=timezone.now(),
                          message="Modified registration data for field(s): %s" % (", ".join(form.changed_data)),
                          ).save()
            return HttpResponseRedirect(".")
    else:
        form = MemberForm(instance=member)

    logdata = MemberLog.objects.filter(member=member).order_by('-timestamp')[:30]

    return render(request, 'membership/index.html', {
        'form': form,
        'member': member,
        'invoice': InvoicePresentationWrapper(member.activeinvoice, "%s/membership/" % settings.SITEBASE),
        'registration_complete': registration_complete,
        'logdata': logdata,
        'amount': cfg.membership_cost,
        'cancelurl': '/account/',
    })
コード例 #21
0
ファイル: views.py プロジェクト: tourdownunder/pgeu-system
def index(request):
    authenticate_backend_group(request, 'Accounting managers')
    # Always redirect to the current year
    return HttpResponseRedirect("%s/" % today_global().year)
コード例 #22
0
ファイル: backendviews.py プロジェクト: pgeu/pgeu-system
def sendmail(request):
    authenticate_backend_group(request, 'Membership administrators')

    cfg = get_config()

    if request.method == 'POST':
        idl = request.POST['idlist']
    else:
        idl = request.GET['idlist']

    if idl == 'allactive':
        recipients = list(Member.objects.filter(paiduntil__gte=today_global()))
        idlist = [m.user_id for m in recipients]
    else:
        idlist = list(map(int, idl.split(',')))
        recipients = Member.objects.filter(pk__in=idlist)

    initial = {
        '_from':
        '{0} <{1}>'.format(cfg.sender_name, cfg.sender_email),
        'recipients':
        escape(", ".join([
            '{0} <{1}>'.format(x.fullname, x.user.email) for x in recipients
        ])),
        'idlist':
        idl,
    }

    if request.method == 'POST':
        p = request.POST.copy()
        p['recipients'] = initial['recipients']
        form = BackendMemberSendEmailForm(data=p, initial=initial)
        if form.is_valid():
            with transaction.atomic():
                msgtxt = "{0}\n\n-- \nThis message was sent to members of {1}\n".format(
                    form.cleaned_data['message'], settings.ORG_NAME)
                mail = MemberMail(
                    sentat=timezone.now(),
                    sentfrom="{} <{}>".format(cfg.sender_name,
                                              cfg.sender_email),
                    subject=form.cleaned_data['subject'],
                    message=msgtxt,
                )
                mail.save()
                mail.sentto.set(recipients)

                for r in recipients:
                    send_simple_mail(
                        cfg.sender_email,
                        r.user.email,
                        form.cleaned_data['subject'],
                        msgtxt,
                        sendername=cfg.sender_name,
                        receivername=r.fullname,
                    )
                messages.info(request,
                              "Email sent to %s members" % len(recipients))

            return HttpResponseRedirect('/admin/membership/emails/')
    else:
        form = BackendMemberSendEmailForm(initial=initial)

    return render(
        request, 'confreg/admin_backend_form.html', {
            'basetemplate': 'adm/admin_base.html',
            'form': form,
            'what': 'new email',
            'savebutton': 'Send email',
            'cancelurl':
            '/admin/membership/emails/' if idl == 'allactive' else '../',
            'breadcrumbs': [
                ('../', 'Members'),
            ],
        })
コード例 #23
0
ファイル: views.py プロジェクト: tourdownunder/pgeu-system
def election(request, electionid):
    election = get_object_or_404(Election, pk=electionid)
    if not election.isopen:
        raise Http404("This election is not open (yet)")

    if election.startdate > today_global():
        raise Http404("This election has not started yet")

    if election.enddate < today_global():
        # Election is closed, consider publishing the results
        if not election.resultspublic:
            # If user is an admin, show anyway, otherwise throw an error
            if not request.user.is_superuser:
                raise Http404(
                    "The results for this election aren't published yet.")

        # Ok, so we do have the results. Use a custom query to make sure we get decently formatted data
        # and no client-side ORM aggregation
        curs = connection.cursor()
        curs.execute(
            "SELECT c.name, sum(v.score) AS score FROM elections_candidate c INNER JOIN elections_vote v ON c.id=v.candidate_id WHERE v.election_id=%(election)s AND c.election_id=%(election)s GROUP BY c.name ORDER BY 2 DESC",
            {
                'election': election.pk,
            })
        res = curs.fetchall()
        if len(res) == 0:
            raise Http404('No results found for this election')

        return render(
            request, 'elections/results.html', {
                'election':
                election,
                'topscore':
                res[0][1],
                'scores': [{
                    'name': r[0],
                    'score': r[1],
                    'width': 300 * r[1] // res[0][1]
                } for r in res],
            })

    if len(election.candidate_set.all()) <= 0:
        raise Http404("This election has no candidates!")

    # Otherwise, we show up the form. This part requires login
    if not request.user.is_authenticated:
        return HttpResponseRedirect("/login/?next=%s" % request.path)

    try:
        member = Member.objects.get(user=request.user)

        # Make sure member has paid
        if not member.paiduntil:
            return render(request, 'elections/mustbemember.html', {})

        # Make sure that the membership hasn't expired
        if member.paiduntil < today_global():
            return render(request, 'elections/mustbemember.html', {})

        # Verify that the user has been a member for at least 28 days.
        if member.membersince > election.startdate - timedelta(days=28):
            return render(
                request, 'elections/memberfourweeks.html', {
                    'membersince': member.membersince,
                    'mustregbefore': election.startdate - timedelta(days=28),
                    'election': election,
                })

    except Member.DoesNotExist:
        return render(request, 'elections/mustbemember.html', {})

    if request.method == "POST":
        form = VoteForm(election, member, data=request.POST)
        if form.is_valid():
            # Save the form
            form.save()
    else:
        # Not a POST, so generate an empty form
        form = VoteForm(election, member)

    return render(request, 'elections/form.html', {
        'form': form,
        'election': election,
    })