Mercurial > public > sg101
view donations/models.py @ 629:f4c043cf55ac
Wiki integration. Requests don't always have sessions.
In particular this occurs when a request is made without a trailing slash.
The Common middleware redirects when this happens, and the middleware
process_request() processing stops before a session can get added.
So just set an attribute on the request object for each operation.
This seemed weird to me at first, but there are plenty of examples of this
in the Django code base already.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Tue, 13 Nov 2012 13:50:06 -0600 |
parents | 40ae28f33b3d |
children | e14f54f16dbc |
line wrap: on
line source
""" Models for the donations application. """ import datetime import decimal from django.db import models from django.contrib.auth.models import User from django.conf import settings from django.db.models import Sum class DonationManager(models.Manager): """Manager for the Donations model.""" def monthly_stats(self, year=None, month=None): """ Returns a tuple of items for the given month in the given year. If year is None, the current year is used. If month is None, the current month is used. The returned tuple has the following items, in order: (gross, net, donations) where: 'gross': total gross donations 'net': total net donations 'donations': list of donation objects """ today = datetime.date.today() if year is None: year = today.year if month is None: month = today.month qs = self.filter(payment_date__year=year, payment_date__month=month, test_ipn=settings.DONATIONS_DEBUG).order_by( 'payment_date').select_related('user') gross = decimal.Decimal() net = decimal.Decimal() donations = [] for donation in qs: gross += donation.mc_gross net += donation.mc_gross - donation.mc_fee donations.append(donation) return gross, net, donations def monthly_goal_pct(self, year=None, month=None, limit=True): """Returns progress towards the given monthly goal as an integer percent. If year is None, the current year is used. If month is None, the current month is used. If limit is True, the return value is limited to 100. """ today = datetime.datetime.today() if year is None: year = today.year if month is None: month = today.month r = self.filter(payment_date__year=year, payment_date__month=month).aggregate( Sum('mc_gross'), Sum('mc_fee')) gross, fee = r['mc_gross__sum'], r['mc_fee__sum'] if gross is not None and fee is not None: pct = int((gross - fee) / settings.DONATIONS_GOAL * 100) else: pct = 0 if limit: pct = min(pct, 100) return pct def top_donors(self, n=10): """Returns a list of the top n donors as user objects that have a total_donations field annotation. The data is taken from non anonymous donations from logged in users. """ qs = User.objects.filter(donation__isnull=False, donation__is_anonymous=False) \ .distinct() \ .annotate(total_donations=Sum('donation__mc_gross')) \ .order_by('-total_donations')[:n] return qs class Donation(models.Model): """Model to represent a donation to the website.""" user = models.ForeignKey(User, null=True, blank=True) is_anonymous = models.BooleanField() test_ipn = models.BooleanField(default=False, verbose_name="Test IPN") txn_id = models.CharField(max_length=20, verbose_name="Txn ID") txn_type = models.CharField(max_length=64) first_name = models.CharField(max_length=64, blank=True) last_name = models.CharField(max_length=64, blank=True) payer_email = models.EmailField(max_length=127, blank=True) payer_id = models.CharField(max_length=13, blank=True, verbose_name="Payer ID") mc_fee = models.DecimalField(max_digits=8, decimal_places=2, verbose_name="Fee") mc_gross = models.DecimalField(max_digits=8, decimal_places=2, verbose_name="Gross") memo = models.TextField(blank=True) payer_status = models.CharField(max_length=10, blank=True) payment_date = models.DateTimeField() objects = DonationManager() class Meta: ordering = ('-payment_date', ) def __unicode__(self): if self.user: return u'%s from %s' % (self.mc_gross, self.user.username) return u'%s from %s %s' % (self.mc_gross, self.first_name, self.last_name) def donor(self): """Returns the donor name for the donation.""" if self.is_anonymous: return settings.DONATIONS_ANON_NAME if self.user is not None: return self.user.username if self.first_name or self.last_name: name = u'%s %s' % (self.first_name, self.last_name) return name.strip() return settings.DONATIONS_ANON_NAME