def post_success(self, product, cart_item, post=None): super(SimplevariationCartDetails, self).post_success(product, cart_item) #if this cart item already has an option set we don't need to do #anything because an existing option set will never change. if we got a #set of different options, that would become a new CartItem. if cart_item.cartitemoption_set.exists(): return self.success() post = self.request.POST for key in post.keys(): if key.startswith(option_group_name_prefix): pk = post[key] if not pk: # blank option group was already validated # and allowed by the time this point # is reached, so just skip it continue data = parse_option_group_name(key) group = OptionGroup.objects.get(pk=data["pk"]) option = Option.objects.get(pk=pk) cartitem_option = CartItemOption() cartitem_option.cartitem = cart_item cartitem_option.option = option cartitem_option.group = group cartitem_option.choice = data["choice"] cartitem_option.save() elif key.startswith('add_item_text_option_'): txt = post[key] if not txt: # blank text option was already validated # and allowed by the time this point # is reached, so just skip it continue pk = key.split('add_item_text_option_')[1] txt_opt = TextOption.objects.get(pk=pk) cito = CartItemTextOption() cito.text_option = txt_opt cito.text = txt cito.cartitem = cart_item cito.save() return self.success()
def post(self, *args, **kwargs): # get a copy of POST so it is mutable post = self.request.POST.copy() #it starts similar to the original post method product_id = post['add_item_id'] product_quantity = post.get('add_item_quantity') if not product_quantity: product_quantity = 1 product = Product.objects.get(pk=product_id) cart_object = get_or_create_cart(self.request, save=True) #now we need to find out which options have been chosen by the user option_ids = [] text_option_ids = {} # A dict of {TextOption.id:CartItemTextOption.text} errors = {} for key in post.keys(): if key.startswith(option_group_name_prefix): pk = post[key] if pk: option_ids.append(pk) else: # verify the option isn't required data = parse_option_group_name(key) og = OptionGroup.objects.get(pk=data["pk"]) if og.required: choose_count = og.get_choose_count() ek = u"%s%s" % ( og, u" (%d of %d)" % ( data["choice"], choose_count ) if 1 < choose_count else "" ) store_error(errors, ek, "Required", "You must make a selection") elif key.startswith('add_item_text_option_'): pk = key.split('add_item_text_option_')[1] txtopt = TextOption.objects.get(pk=pk) txt = post[key] if txt: text_option_ids.update({pk:txt}) # verify text meets max_length requirements if txtopt.max_length and txtopt.max_length < len(txt): store_error(errors, txtopt.name, "Max Length", "Field Is Too Long") else: # verify the option isn't required if txtopt.required: store_error(errors, txtopt.name, "Required", "Field Is Required") if errors: return render_errors_response( request = self.request, template_name = "shop_simplevariations/cart_validation_errors.html", errors = errors ) #now we need to find out if there are any cart items that have the exact #same set of options qs = CartItem.objects.filter(cart=cart_object).filter(product=product) found_cartitem_id = None merge = False for cartitem in qs: # for each CartItem in the Cart, get it's options and text options cartitemoptions = CartItemOption.objects.filter( cartitem=cartitem, option__in=option_ids ) cartitemtxtoptions = CartItemTextOption.objects.filter( text_option__in=text_option_ids.keys(), text__in=text_option_ids.values() ) if len(cartitemoptions) + len(cartitemtxtoptions) == (len(option_ids) + len(text_option_ids)): found_cartitem_id = cartitem.id merge = True break #if we found a CartItem object that has the same options, we need #to select this one instead of just any CartItem that belongs to this #cart and this product. if found_cartitem_id: qs = CartItem.objects.filter(pk=found_cartitem_id) cart_item = cart_object.add_product( product, product_quantity, merge=merge, queryset=qs) cart_object.save() return self.post_success(product, cart_item)