Changeset - b13e6f7ce2c2
[Not reviewed]
0 2 0
Christopher Neugebauer - 8 years ago 2016-03-26 09:01:46
chrisjrn@gmail.com
Factors out voucher form handling into its own function
2 files changed with 43 insertions and 16 deletions:
0 comments (0 inline, 0 general)
registrasion/models.py
Show inline comments
...
 
@@ -151,51 +151,55 @@ class Product(models.Model):
 
    category = models.ForeignKey(Category, verbose_name=_("Product category"))
 
    price = models.DecimalField(max_digits=8,
 
                                decimal_places=2,
 
                                verbose_name=_("Price"))
 
    limit_per_user = models.PositiveIntegerField(
 
        blank=True,
 
        verbose_name=_("Limit per user"))
 
    reservation_duration = models.DurationField(
 
        default=datetime.timedelta(hours=1),
 
        verbose_name=_("Reservation duration"))
 
    order = models.PositiveIntegerField(verbose_name=("Display order"))
 

	
 

	
 
@python_2_unicode_compatible
 
class Voucher(models.Model):
 
    ''' Registration vouchers '''
 

	
 
    # Vouchers reserve a cart for a fixed amount of time, so that
 
    # items may be added without the voucher being swiped by someone else
 
    RESERVATION_DURATION = datetime.timedelta(hours=1)
 

	
 
    def __str__(self):
 
        return "Voucher for %s" % self.recipient
 

	
 
    @classmethod
 
    def normalise_code(cls, code):
 
        return code.upper()
 

	
 
    def save(self, *a, **k):
 
        ''' Normalise the voucher code to be uppercase '''
 
        self.code = self.code.upper()
 
        self.code = self.normalise_code(self.code)
 
        super(Voucher, self).save(*a, **k)
 

	
 
    recipient = models.CharField(max_length=64, verbose_name=_("Recipient"))
 
    code = models.CharField(max_length=16,
 
                            unique=True,
 
                            verbose_name=_("Voucher code"))
 
    limit = models.PositiveIntegerField(verbose_name=_("Voucher use limit"))
 

	
 

	
 
# Product Modifiers
 

	
 
@python_2_unicode_compatible
 
class DiscountBase(models.Model):
 
    ''' Base class for discounts. Each subclass has controller code that
 
    determines whether or not the given discount is available to be added to
 
    the current cart. '''
 

	
 
    objects = InheritanceManager()
 

	
 
    def __str__(self):
 
        return "Discount: " + self.description
 

	
 
    description = models.CharField(max_length=255,
 
                                   verbose_name=_("Description"))
registrasion/views.py
Show inline comments
...
 
@@ -78,148 +78,171 @@ def edit_profile(request):
 
    if request.POST and form.is_valid():
 
        form.instance.attendee = attendee
 
        form.save()
 

	
 
    data = {
 
        "form": form,
 
    }
 
    return render(request, "profile_form.html", data)
 

	
 

	
 
@login_required
 
def product_category(request, category_id):
 
    ''' Registration selections form for a specific category of items.
 
    '''
 

	
 
    PRODUCTS_FORM_PREFIX = "products"
 
    VOUCHERS_FORM_PREFIX = "vouchers"
 

	
 
    category_id = int(category_id)  # Routing is [0-9]+
 
    category = rego.Category.objects.get(pk=category_id)
 
    current_cart = CartController.for_user(request.user)
 

	
 
    attendee = rego.Attendee.get_instance(request.user)
 

	
 
    # Handle the voucher form *before* listing products.
 
    v = handle_voucher(request, VOUCHERS_FORM_PREFIX)
 
    voucher_form, voucher_handled = v
 
    if voucher_handled:
 
        # Do not handle product form
 
        pass
 

	
 
    products = rego.Product.objects.filter(category=category)
 
    products = products.order_by("order")
 
    products = ProductController.available_products(
 
        request.user,
 
        products=products,
 
    )
 

	
 
    ProductsForm = forms.ProductsForm(products)
 

	
 
    if request.method == "POST":
 
        cat_form = ProductsForm(
 
            request.POST,
 
            request.FILES,
 
            prefix=PRODUCTS_FORM_PREFIX)
 
        voucher_form = forms.VoucherForm(
 
            request.POST,
 
            prefix=VOUCHERS_FORM_PREFIX)
 

	
 
        if (voucher_form.is_valid() and
 
                voucher_form.cleaned_data["voucher"].strip()):
 
            # Apply voucher
 
            # leave
 
            voucher = voucher_form.cleaned_data["voucher"]
 
            try:
 
                current_cart.apply_voucher(voucher)
 
            except Exception as e:
 
                voucher_form.add_error("voucher", e)
 
            # Re-visit current page.
 
        if voucher_handled:
 
            # The voucher form was handled here.
 
            pass
 
        elif cat_form.is_valid():
 
            try:
 
                handle_valid_cat_form(cat_form, current_cart)
 
            except ValidationError:
 
                pass
 

	
 
            # If category is required, the user must have at least one
 
            # in an active+valid cart
 

	
 
            if category.required:
 
                carts = rego.Cart.reserved_carts()
 
                carts = carts.filter(user=request.user)
 
                items = rego.ProductItem.objects.filter(
 
                    product__category=category,
 
                    cart=carts,
 
                )
 
                if len(items) == 0:
 
                    cat_form.add_error(
 
                        None,
 
                        "You must have at least one item from this category",
 
                    )
 

	
 
            if not cat_form.errors:
 
                if category_id > attendee.highest_complete_category:
 
                    attendee.highest_complete_category = category_id
 
                    attendee.save()
 
                return redirect("dashboard")
 

	
 
    else:
 
        # Create initial data for each of products in category
 
        items = rego.ProductItem.objects.filter(
 
            product__category=category,
 
            cart=current_cart.cart,
 
        )
 
        quantities = []
 
        for product in products:
 
            # Only add items that are enabled.
 
            try:
 
                quantity = items.get(product=product).quantity
 
            except ObjectDoesNotExist:
 
                quantity = 0
 
            quantities.append((product, quantity))
 

	
 
        cat_form = ProductsForm(
 
            prefix=PRODUCTS_FORM_PREFIX,
 
            product_quantities=quantities,
 
        )
 

	
 
        voucher_form = forms.VoucherForm(prefix=VOUCHERS_FORM_PREFIX)
 

	
 
    discounts = discount.available_discounts(request.user, [], products)
 
    data = {
 
        "category": category,
 
        "discounts": discounts,
 
        "form": cat_form,
 
        "voucher_form": voucher_form,
 
    }
 

	
 
    return render(request, "product_category.html", data)
 

	
 

	
 
@transaction.atomic
 
def handle_valid_cat_form(cat_form, current_cart):
 
    for product_id, quantity, field_name in cat_form.product_quantities():
 
        product = rego.Product.objects.get(pk=product_id)
 
        try:
 
            current_cart.set_quantity(product, quantity, batched=True)
 
        except ValidationError as ve:
 
            cat_form.add_error(field_name, ve)
 
    if cat_form.errors:
 
        raise ValidationError("Cannot add that stuff")
 
    current_cart.end_batch()
 

	
 
def handle_voucher(request, prefix):
 
    ''' Handles a voucher form in the given request. Returns the voucher
 
    form instance, and whether the voucher code was handled. '''
 

	
 
    voucher_form = forms.VoucherForm(request.POST or None, prefix=prefix)
 
    current_cart = CartController.for_user(request.user)
 

	
 
    if (voucher_form.is_valid() and
 
            voucher_form.cleaned_data["voucher"].strip()):
 

	
 
        voucher = voucher_form.cleaned_data["voucher"]
 
        voucher = rego.Voucher.normalise_code(voucher)
 

	
 
        if len(current_cart.cart.vouchers.filter(code=voucher)) > 0:
 
            # This voucher has already been applied to this cart.
 
            # Do not apply code
 
            handled = False
 
        else:
 
            try:
 
                current_cart.apply_voucher(voucher)
 
            except Exception as e:
 
                voucher_form.add_error("voucher", e)
 
            handled = True
 
    else:
 
        handled = False
 

	
 
    return (voucher_form, handled)
 

	
 
@login_required
 
def checkout(request):
 
    ''' Runs checkout for the current cart of items, ideally generating an
 
    invoice. '''
 

	
 
    current_cart = CartController.for_user(request.user)
 
    current_invoice = InvoiceController.for_cart(current_cart.cart)
 

	
 
    return redirect("invoice", current_invoice.invoice.id)
 

	
 

	
 
@login_required
 
def invoice(request, invoice_id):
 
    ''' Displays an invoice for a given invoice id. '''
 

	
 
    invoice_id = int(invoice_id)
 
    inv = rego.Invoice.objects.get(pk=invoice_id)
 
    current_invoice = InvoiceController(inv)
 

	
 
    data = {
 
        "invoice": current_invoice.invoice,
 
    }
 

	
0 comments (0 inline, 0 general)