@@ -0,0 +1,3342 @@
+# -*- coding: UTF-8 -*-%0A%22%22%22 Create EPS Python conference organizer discount coupons.%0A%0A    Parameters: %3Cconference%3E %3Ccount%3E%0A%0A    Valid for conference tickets, one use and one item per order.  Not valid%0A    for the social event.%0A%0A    Created coupons are written as CSV data to stdout.%0A%0A    Use --dry-run to test drive the script.%0A%0A%22%22%22%0Aimport string%0Aimport random%0Afrom optparse import make_option%0A%0Afrom django.core.management.base import BaseCommand, CommandError%0Afrom django.db import transaction%0A%0Afrom conference import models as cmodels%0Afrom assopy.models import Coupon%0A%0A%0A### Globals%0A%0A# Coupon prefix%0ACOUPON_PREFIX = 'PYO'%0A%0A# Discount%0AEPS_PYORGANIZER_DISCOUNT = '100%25'%0A%0A# Max usage per coupon%0ACOUPON_MAX_USAGE = 1%0A%0A# Max items per order%0ACOUPON_ITEMS_PER_USAGE = 1%0A%0A###%0A%0Aclass Command(BaseCommand):%0A%0A    option_list = BaseCommand.option_list + (%0A        make_option('--dry-run',%0A                    action='store_true',%0A                    dest='dry_run',%0A                    help='Do everything except create the coupons',%0A                    ),%0A    )%0A%0A    args = '%3Cconference%3E %3Ccount%3E'%0A%0A    # Dry run ?%0A    dry_run = False%0A%0A    @transaction.atomic%0A    def handle(self, *args, **options):%0A%0A        self.dry_run = options.get('dry_run', False)%0A%0A        try:%0A            conference = cmodels.Conference.objects.get(code=args%5B0%5D)%0A        except IndexError:%0A            raise CommandError('conference missing')%0A%0A        try:%0A            number_of_coupons = int(args%5B1%5D)%0A        except IndexError:%0A            raise CommandError('coupon count missing')%0A%0A        # Valid fares (conference fares only)%0A        fares = cmodels.Fare.objects%5C%0A            .filter(conference=conference.code,%0A                    ticket_type='conference')%0A%0A        # Get set of existing codes%0A        codes = set(c%5B'code'%5D for c in Coupon.objects%5C%0A            .filter(conference=conference.code)%5C%0A            .values('code'))%0A%0A        # Create coupons%0A        data = %5B%5D%0A        for i in range(number_of_coupons):%0A%0A            coupon_prefix = COUPON_PREFIX%0A            value = EPS_PYORGANIZER_DISCOUNT%0A%0A            # Determine a new code%0A            while True:%0A                # Codes: SPK-RANDOM%0A                code = (coupon_prefix + '-'%0A                        + ''.join(random.sample(string.uppercase, 6)))%0A                if code not in codes:%0A                    codes.add(code)%0A                    break%0A%0A            # Create coupon%0A            c = Coupon(conference=conference)%0A            c.code = code%0A            c.max_usage = COUPON_MAX_USAGE%0A            c.items_per_usage = COUPON_ITEMS_PER_USAGE%0A            c.value = value%0A            c.description = 'EPS Python Conference Organizer Discount'%0A            if not self.dry_run:%0A                c.save()%0A                c.fares = fares%0A%0A            # Build CSV data%0A            data_row = (%0A                c.code,%0A                c.value,%0A                c.max_usage,%0A                c.items_per_usage,%0A                )%0A            data.append(data_row)%0A%0A        # Output CSV data, UTF-8 encoded%0A        data.insert(0, (%0A            # Header%0A            'code', 'value', 'max_usage', 'items_per_usage',%0A            ))%0A        for row in data:%0A            csv_data = (u'%22%25s%22' %25 (unicode(x).replace(u'%22', u'%22%22'))%0A                        for x in row)%0A            print (u','.join(csv_data).encode('utf-8'))%0A

Add script to generate Python conference organizer discount coupons.