django-shop-simplevariations
django-shop-simplevariations copied to clipboard
Text Option "Text" not honored when adding the same Text
Hi
I am trying to get simplevariations to work in a given environment which requires exactly one text option (an engraving) and when I tryed to add the same product with the same text it was added to the same product with another text, in fact always the first cart item of this product with whatever text option was used.
A quick look in the source code revealed (views.py ca line 50):
if len(cartitemoptions) + len(cartitemtxtoptions) == (len(option_ids) + len(text_option_ids)):
found_cartitem_id = cartitem.id
merge = True
break
So the actual value of the text is not honored currently.
Update:I have to work on my fix for now, what was posted is not working correctliy
Best
Here is how i fixed it for now, it is not yet tested very well, be careful
class SimplevariationCartDetails(CartDetails): """Cart view that answers GET and POSTS request."""
## added sn_devdev
def options_equal(self, option_ids, cartitemoptions):
cartitem_ids = []
for cartitemoption in cartitemoptions:
cartitem_ids.append(unicode(cartitemoption.option.id))
result = set(option_ids) & set(cartitem_ids)
if result == set(option_ids):
return True
return False
## added sn_devdev
def text_options_equal(self, text_option_ids, cartitemtxtoptions):
itemtextopts = {}
for ito in cartitemtxtoptions:
itemtextopts.update({unicode(ito.text_option.id):ito.text}) ;
same = True
for to in text_option_ids:
if to not in itemtextopts:
same = False
for to in itemtextopts:
if to not in text_option_ids:
same = False
return same
def post(self, *args, **kwargs):
#it starts similar to the original post method
product_id = self.request.POST['add_item_id']
product_quantity = self.request.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)
#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}
for key in self.request.POST.keys():
if key.startswith('add_item_option_group_'):
option_ids.append(self.request.POST[key])
elif key.startswith('add_item_text_option_'):
id = key.split('add_item_text_option_')[1]
txt = self.request.POST[key]
if txt != '':
text_option_ids.update({id:txt})
#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()
)
"""
textoptions = CartItemTextOption.objects.filter(cartitem=cartitem)
if self.options_equal(option_ids, cartitemoptions) and self.text_options_equal(text_option_ids, textoptions):
found_cartitem_id = cartitem.id
merge = True
#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)
return self.post_success(product, cart_item)
def post_success(self, product, cart_item):
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 self.request.POST.keys():
if key.startswith('add_item_option_group_'):
option = Option.objects.get(pk=int(post[key]))
cartitem_option = CartItemOption()
cartitem_option.cartitem = cart_item
cartitem_option.option = option
cartitem_option.save()
elif key.startswith('add_item_text_option_'):
id = key.split('add_item_text_option_')[1]
txt = self.request.POST[key]
if txt != '':
txt_opt = TextOption.objects.get(pk=id)
cito = CartItemTextOption()
cito.text_option = txt_opt
cito.text = txt
cito.cartitem = cart_item
cito.save()
return self.success()