Changeset - 75d96ce1c1c2
[Not reviewed]
Merge
0 5 0
Christopher Neugebauer - 8 years ago 2016-09-03 05:56:08
chrisjrn@gmail.com
Merge branch 'chrisjrn/amend_products'

Closes #33
5 files changed with 147 insertions and 20 deletions:
0 comments (0 inline, 0 general)
registrasion/controllers/item.py
Show inline comments
...
 
@@ -30,7 +30,7 @@ class ItemController(object):
 
    def __init__(self, user):
 
        self.user = user
 

	
 
    def items_purchased(self, category=None):
 
    def _items(self, cart_status, category=None):
 
        ''' Aggregates the items that this user has purchased.
 

	
 
        Arguments:
...
 
@@ -45,7 +45,7 @@ class ItemController(object):
 

	
 
        in_cart = (
 
            Q(productitem__cart__user=self.user) &
 
            Q(productitem__cart__status=commerce.Cart.STATUS_PAID)
 
            Q(productitem__cart__status=cart_status)
 
        )
 

	
 
        quantities_in_cart = When(
...
 
@@ -72,6 +72,20 @@ class ItemController(object):
 
            out.append(ProductAndQuantity(prod, prod.quantity))
 
        return out
 

	
 
    def items_purchased(self, category=None):
 
        ''' Aggregates the items that this user has purchased.
 

	
 
        Arguments:
 
            category (Optional[models.inventory.Category]): the category
 
                of items to restrict to.
 

	
 
        Returns:
 
            [ProductAndQuantity, ...]: A list of product-quantity pairs,
 
                aggregating like products from across multiple invoices.
 

	
 
        '''
 
        return self._items(commerce.Cart.STATUS_PAID)
 

	
 
    def items_pending(self):
 
        ''' Gets all of the items that the user has reserved, but has not yet
 
        paid for.
...
 
@@ -82,14 +96,16 @@ class ItemController(object):
 

	
 
        '''
 

	
 
        all_items = commerce.ProductItem.objects.filter(
 
            cart__user=self.user,
 
            cart__status=commerce.Cart.STATUS_ACTIVE,
 
        ).select_related(
 
            "product",
 
            "product__category",
 
        ).order_by(
 
            "product__category__order",
 
            "product__order",
 
        )
 
        return all_items
 
        return self._items(commerce.Cart.STATUS_ACTIVE)
 

	
 
    def items_released(self):
 
        ''' Gets all of the items that the user previously paid for, but has
 
        since refunded.
 

	
 
        Returns:
 
            [ProductAndQuantity, ...]: A list of product-quantity pairs for the
 
                items that the user has not yet paid for.
 

	
 
        '''
 

	
 
        return self._items(commerce.Cart.STATUS_RELEASED)
registrasion/forms.py
Show inline comments
 
from registrasion.controllers.product import ProductController
 
from registrasion.models import commerce
 
from registrasion.models import inventory
 

	
...
 
@@ -347,3 +348,33 @@ class VoucherForm(forms.Form):
 
        help_text="If you have a voucher code, enter it here",
 
        required=False,
 
    )
 

	
 

	
 
def staff_products_form_factory(user):
 
    ''' Creates a StaffProductsForm that restricts the available products to
 
    those that are available to a user. '''
 

	
 
    products = inventory.Product.objects.all()
 
    products = ProductController.available_products(user, products=products)
 

	
 
    product_ids = [product.id for product in products]
 
    product_set = inventory.Product.objects.filter(id__in=product_ids)
 

	
 
    class StaffProductsForm(forms.Form):
 
        ''' Form for allowing staff to add an item to a user's cart. '''
 

	
 
        product = forms.ModelChoiceField(
 
            widget=forms.Select,
 
            queryset=product_set,
 
        )
 

	
 
        quantity = forms.IntegerField(
 
            min_value=0,
 
        )
 

	
 
    return StaffProductsForm
 

	
 
def staff_products_formset_factory(user):
 
    ''' Creates a formset of StaffProductsForm for the given user. '''
 
    form_type = staff_products_form_factory(user)
 
    return forms.formset_factory(form_type)
registrasion/reporting/views.py
Show inline comments
...
 
@@ -236,17 +236,17 @@ def credit_notes(request, form):
 

	
 

	
 
@report_view("Attendee", form_type=forms.UserIdForm)
 
def attendee(request, form, attendee_id=None):
 
def attendee(request, form, user_id=None):
 
    ''' Returns a list of all manifested attendees if no attendee is specified,
 
    else displays the attendee manifest. '''
 

	
 
    if attendee_id is None and not form.has_changed():
 
    if user_id is None and not form.has_changed():
 
        return attendee_list(request)
 

	
 
    if form.cleaned_data["user"] is not None:
 
        attendee_id = form.cleaned_data["user"]
 
        user_id = form.cleaned_data["user"]
 

	
 
    attendee = people.Attendee.objects.get(id=attendee_id)
 
    attendee = people.Attendee.objects.get(user__id=user_id)
 

	
 
    reports = []
 

	
...
 
@@ -349,7 +349,7 @@ def attendee_list(request):
 

	
 
    for attendee in attendees:
 
        data.append([
 
            attendee.id,
 
            attendee.user.id,
 
            attendee.attendeeprofilebase.attendee_name(),
 
            attendee.user.email,
 
            attendee.has_registered > 0,
registrasion/urls.py
Show inline comments
...
 
@@ -13,12 +13,15 @@ from .views import (
 
    invoice_access,
 
    edit_profile,
 
    guided_registration,
 
    amend_registration,
 
)
 

	
 

	
 
public = [
 
    url(r"^amend/([0-9]+)$", amend_registration, name="amend_registration"),
 
    url(r"^category/([0-9]+)$", product_category, name="product_category"),
 
    url(r"^checkout$", checkout, name="checkout"),
 
    url(r"^checkout/([0-9]+)$", checkout, name="checkout"),
 
    url(r"^credit_note/([0-9]+)$", credit_note, name="credit_note"),
 
    url(r"^invoice/([0-9]+)$", invoice, name="invoice"),
 
    url(r"^invoice/([0-9]+)/([A-Z0-9]+)$", invoice, name="invoice"),
registrasion/views.py
Show inline comments
...
 
@@ -10,6 +10,7 @@ from registrasion.controllers.cart import CartController
 
from registrasion.controllers.credit_note import CreditNoteController
 
from registrasion.controllers.discount import DiscountController
 
from registrasion.controllers.invoice import InvoiceController
 
from registrasion.controllers.item import ItemController
 
from registrasion.controllers.product import ProductController
 
from registrasion.exceptions import CartValidationError
 

	
...
 
@@ -18,6 +19,7 @@ from collections import namedtuple
 
from django.conf import settings
 
from django.contrib.auth.decorators import login_required
 
from django.contrib.auth.decorators import user_passes_test
 
from django.contrib.auth.models import User
 
from django.contrib import messages
 
from django.core.exceptions import ObjectDoesNotExist
 
from django.core.exceptions import ValidationError
...
 
@@ -504,7 +506,7 @@ def _handle_voucher(request, prefix):
 

	
 

	
 
@login_required
 
def checkout(request):
 
def checkout(request, user_id=None):
 
    ''' Runs the checkout process for the current cart.
 

	
 
    If the query string contains ``fix_errors=true``, Registrasion will attempt
...
 
@@ -512,6 +514,10 @@ def checkout(request):
 
    cancelling expired discounts and vouchers, and removing any unavailable
 
    products.
 

	
 
    Arguments:
 
        user_id (castable to int):
 
            If the requesting user is staff, then the user ID can be used to
 
            run checkout for another user.
 
    Returns:
 
        render or redirect:
 
            If the invoice is generated successfully, or there's already a
...
 
@@ -525,7 +531,15 @@ def checkout(request):
 

	
 
    '''
 

	
 
    current_cart = CartController.for_user(request.user)
 
    if user_id is not None:
 
        if request.user.is_staff:
 
            user = User.objects.get(id=int(user_id))
 
        else:
 
            raise Http404()
 
    else:
 
        user = request.user
 

	
 
    current_cart = CartController.for_user(user)
 

	
 
    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
 
        current_cart.fix_simple_errors()
...
 
@@ -790,3 +804,66 @@ def credit_note(request, note_id, access_code=None):
 
    }
 

	
 
    return render(request, "registrasion/credit_note.html", data)
 

	
 

	
 
@user_passes_test(_staff_only)
 
def amend_registration(request, user_id):
 
    ''' Allows staff to amend a user's current registration cart, and etc etc.
 
    '''
 

	
 
    user = User.objects.get(id=int(user_id))
 
    current_cart = CartController.for_user(user)
 

	
 
    items = commerce.ProductItem.objects.filter(
 
        cart=current_cart.cart,
 
    ).select_related("product")
 
    initial = [{"product": i.product, "quantity": i.quantity} for i in items]
 

	
 
    StaffProductsFormSet = forms.staff_products_formset_factory(user)
 
    formset = StaffProductsFormSet(
 
        request.POST or None,
 
        initial=initial,
 
        prefix="products",
 
    )
 

	
 
    voucher_form = forms.VoucherForm(
 
        request.POST or None,
 
        prefix="voucher",
 
    )
 

	
 
    if request.POST and formset.is_valid():
 

	
 
        pq = [
 
            (f.cleaned_data["product"], f.cleaned_data["quantity"])
 
            for f in formset
 
            if "product" in f.cleaned_data and
 
            f.cleaned_data["product"] is not None
 
        ]
 

	
 
        try:
 
            current_cart.set_quantities(pq)
 
            return redirect(amend_registration, user_id)
 
        except ValidationError as ve:
 
            for ve_field in ve.error_list:
 
                product, message = ve_field.message
 
                for form in formset:
 
                    if form.cleaned_data["product"] == product:
 
                        form.add_error("quantity", message)
 

	
 
    if request.POST and voucher_form.is_valid():
 
        try:
 
            current_cart.apply_voucher(voucher_form.cleaned_data["voucher"])
 
            return redirect(amend_registration, user_id)
 
        except ValidationError as ve:
 
            voucher_form.add_error(None, ve)
 

	
 
    ic = ItemController(user)
 
    data = {
 
        "user": user,
 
        "paid": ic.items_purchased(),
 
        "cancelled": ic.items_released(),
 
        "form": formset,
 
        "voucher_form": voucher_form,
 
    }
 

	
 
    return render(request, "registrasion/amend_registration.html", data)
0 comments (0 inline, 0 general)