django-shop-simplevariations icon indicating copy to clipboard operation
django-shop-simplevariations copied to clipboard

Text Option "Text" not honored when adding the same Text

Open sn-devdev opened this issue 13 years ago • 1 comments

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

sn-devdev avatar Nov 21 '11 15:11 sn-devdev

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()

sn-devdev avatar Nov 25 '11 10:11 sn-devdev