def cart(request): """It showes customer's cart and allows to change products numbers. """ cart = Cart(request) products = cart.get() products_ids = {p.id: p for p in products} OrderFormSet = formset_factory(OrderForm, extra=0) if request.method == 'POST': formset = OrderFormSet(request.POST) if formset.is_valid() and formset.has_changed(): for cd in formset.cleaned_data: product = get_object_or_404(Product, pk=cd['product']) cart.add_or_update(product, cd['count']) else: data = [{'product': p.id, 'count': c} for p, c in products.items()] formset = OrderFormSet(initial=data) for form in formset: form.product_info = products_ids[int(form.hidden_fields()[0].value())] context = { 'products': products, 'formset': formset, 'cart_count': cart.count(), 'total': cart.total(), } return cart.set(render(request, 'sales/cart.html', context))
def confirm(request): """It confirms a customer's order and sets delivery address """ if not hasattr(request.user, 'customer'): raise Http404("user is not related with a customer") customer = request.user.customer cart = Cart(request) if cart.is_empty(): # empty cart can't approve any order return redirect(reverse('index')) products = [] try: for product, count in cart.get().items(): product.count = count product.total = round(product.price * int(count), 2) products.append(product) except (ValueError,) as err: raise Http404(err) if request.method == 'POST': form = DeliveryForm(request.POST) form.set_choises(customer) if form.is_valid(): data = form.cleaned_data with transaction.atomic(): if data['new']: # create new delivery address delivery = Delivery( customer=customer, address=data['new'], ) delivery.save() else: # use existed address delivery = get_object_or_404(Delivery, pk=data['existed']) order = Order( customer=customer, desc=data['comment'], ) order.save() for product in products: ProductSet.objects.create( product=product, order=order, number=product.count, ) return cart.clean(redirect(reverse('order', args=[order.id]))) else: form = DeliveryForm() form.set_choises(customer) context = { 'products': products, 'cart_count': cart.count(), 'total': cart.total(), 'form': form, } return render(request, 'sales/confirm.html', context)