Changing in the Quantity of variants reflecting in the wrong item in Order Summary

Submitted 3 years, 11 months ago
Ticket #12
Views 313
Language/Framework Django
Priority Low
Status Closed

I have a problem with the variations and the quantity related to it in the order summary page.

This is an example to simplify the error

when I add to the cart 2 items with different variations:

  • Item X with a size small
  • Item X with a size medium

When I change the quantity of item X size medium, this change is reflecting in item X size small which was chosen first.

In the order summary, there are a plus and minus in the template to change the quantity.

I have identified the problem but I can't figure out why it is occurring

Here is the template:

        <h2> Order Summary</h2>
            <tbody>
            {% for order_item in object.items.all %}
            <tr>
                <th scope="row">{{ forloop.counter }}</th>
                <td>{{ order_item.item.title }}</td>
                <td>{{ order_item.item.price }}</td>
                <td>
                <a href="{% url 'core:remove-single-item-from-cart' order_item.item.slug %}"><i class="fas fa-minus mr-2"></a></i>
                {{ order_item.quantity }}
                <a href="{% url 'core:add-to-cart' order_item.item.slug %}"><i class="fas fa-plus ml-2"></a></i>
                </td>

                <td>
                {% if order_item.variation.all %}
                {% for variation in order_item.variation.all %}
                {{ variation.title|capfirst }}
                {% endfor %}
                {% endif %}
                </td> 

Here is the views.py

class OrderSummaryView(LoginRequiredMixin, View):
    def get(self, *args, **kwargs):

        try:
            order = Order.objects.get(user=self.request.user, ordered=False)
            context = {
                'object': order
            }
            return render(self.request, 'order_summary.html', context)
        except ObjectDoesNotExist:
            messages.warning(self.request, "You do not have an active order")
            return redirect("/")


@login_required
def add_to_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)

    order_item_qs = OrderItem.objects.filter(
        item=item,
        user=request.user,
        ordered=False
    )

    item_var = []  # item variation
    if request.method == 'POST':
        for items in request.POST:
            key = items
            val = request.POST[key]
            try:
                v = Variation.objects.get(
                    item=item,
                    category__iexact=key,
                    title__iexact=val
                )
                item_var.append(v)
            except:
                pass

        if len(item_var) > 0:
            for items in item_var:
                order_item_qs = order_item_qs.filter(
                    variation__exact=items,
                )

    if order_item_qs.exists():
        order_item = order_item_qs.first()
        order_item.quantity += 1
        order_item.save()
    else:
        order_item = OrderItem.objects.create(
            item=item,
            user=request.user,
            ordered=False
        )
        order_item.variation.add(*item_var)
        order_item.save()

    order_qs = Order.objects.filter(user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if not order.items.filter(item__id=order_item.id).exists():
            order.items.add(order_item)
            messages.info(request, "This item quantity was updated.")
            return redirect("core:order-summary")
    else:
        ordered_date = timezone.now()
        order = Order.objects.create(
            user=request.user, ordered_date=ordered_date)
        order.items.add(order_item)
        messages.info(request, "This item was added to cart.")
        return redirect("core:order-summary")


@login_required
def remove_from_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_qs = Order.objects.filter(
        user=request.user,
        ordered=False
    )
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                item=item,
                user=request.user,
                ordered=False
            )[0]
            order.items.remove(order_item)
            order_item.delete()
            messages.info(request, "This item was removed from your cart")
            return redirect("core:order-summary")

        else:
            messages.info(request, "This item was not in your cart")
            return redirect("core:product", slug=slug)
    else:
        messages.info(request, "You don't have an active order")
        return redirect("core:product", slug=slug)


@login_required
def remove_single_item_from_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_qs = Order.objects.filter(
        user=request.user,
        ordered=False
    )
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                item=item,
                user=request.user,
                ordered=False
            )[0]
            if order_item.quantity > 1:
                order_item.quantity -= 1
                order_item.save()
            else:
                order.items.remove(order_item)
            messages.info(request, "This item quantity was updated")
            return redirect("core:order-summary")
        else:
            messages.info(request, "This item was not in your cart")
            return redirect("core:product", slug=slug)
    else:
        messages.info(request, "You do not have an active order")
        return redirect("core:product", slug=slug)
# End Remove Items (Products removed from Cart)

here is the models.py


class Item(models.Model):
    title             = models.CharField(max_length=100)
    -------------------------------------------------------------------------
    updated           = models.DateTimeField(auto_now_add=False, auto_now=True)
    active            = models.BooleanField(default=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("core:product", kwargs={
            'slug': self.slug
        })

    def get_add_to_cart_url(self):
        return reverse("core:add-to-cart", kwargs={
            'slug': self.slug
        })

    def get_remove_from_cart_url(self):
        return reverse("core:remove-from-cart", kwargs={
            'slug': self.slug
        })


class VariationManager(models.Manager):
    def all(self):
        return super(VariationManager, self).filter(active=True)

    def sizes(self):
        return self.all().filter(category='size')

    def colors(self):
        return self.all().filter(category='color')


VAR_CATEGORIES = (
    ('size', 'size',),
    ('color', 'color',),
    ('package', 'package'),
)


class Variation(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    category = models.CharField(
        max_length=120, choices=VAR_CATEGORIES, default='size')
    title = models.CharField(max_length=120)
    image = models.ImageField(null=True, blank=True)
    price = models.DecimalField(
        decimal_places=2, max_digits=100, null=True, blank=True)
    objects = VariationManager()
    active = models.BooleanField(default=True)

    def __str__(self):
        return self.title

class OrderItem(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    ordered = models.BooleanField(default=False)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    variation = models.ManyToManyField(Variation)

    def __str__(self):
        return f"{self.quantity} of {self.item.title}"
Submitted on May 29, 20
add a comment

1 Answer

Acknowledged.

Submitted 3 years, 11 months ago

Looks like issue in rendering the quantity value in your html.. so double check how its rendering in html

- Vengat 3 years, 11 months ago

I check it but I think there might be something incorrect in the views

- ahmed.hisham87 3 years, 11 months ago

This is more like funcitonal issue. we would suggest please debug your code step by step. i mean let say, first when you click on add and then print statement in your views, what its returning, and then add different size product and check what it is returning from your view. If both are same, then problem in view. Because this is not an error, as i mentioned, this is functional requirement. as something you may need to explore.

- Vengat 3 years, 11 months ago

Hello Teckiys, I have checked the views and went through it step by step but I am still having difficulty with this issue can I open a new ticket for it?

- ahmed.hisham87 3 years, 8 months ago

yes please create the new ticket with more details.

- Vengat 3 years, 8 months ago

I think we can work on here itself, as it is same issue. Can you share the debug steps which you take, because if I remember correctly its issue in your view code

- Vengat 3 years, 8 months ago


Latest Blogs