@@ -237,3 +237,35 @@ class AdminRevenueTests(TestCase):
|
||||
self.assertEqual(len(seller_data), 1)
|
||||
self.assertEqual(seller_data[0]['total_revenue'], Decimal('1100.00'))
|
||||
self.assertEqual(seller_data[0]['platform_fees'], Decimal('30.70'))
|
||||
|
||||
class CardListStockTests(TestCase):
|
||||
def setUp(self):
|
||||
# Create Data
|
||||
self.user = User.objects.create_user(username='stock_seller', password='password')
|
||||
self.seller = Seller.objects.create(
|
||||
user=self.user,
|
||||
store_name='Stock Store',
|
||||
slug='stock-store'
|
||||
)
|
||||
self.game = Game.objects.create(name='Stock Game', slug='stock-game')
|
||||
self.set = Set.objects.create(game=self.game, name='Stock Set')
|
||||
self.card = Card.objects.create(set=self.set, name='Stock Card')
|
||||
|
||||
def test_stock_aggregation(self):
|
||||
# 1. No listings
|
||||
url = reverse('store:card_list')
|
||||
response = self.client.get(url, {'hide_out_of_stock': 'off'})
|
||||
# Expect card in context
|
||||
self.assertEqual(len(response.context['page_obj']), 1)
|
||||
self.assertEqual(response.context['page_obj'][0].total_quantity, 0)
|
||||
|
||||
# 2. Add listings
|
||||
CardListing.objects.create(card=self.card, seller=self.seller, price=10, quantity=5, status='listed')
|
||||
CardListing.objects.create(card=self.card, seller=self.seller, price=10, quantity=3, status='listed')
|
||||
|
||||
# Add a sold listing (should be ignored)
|
||||
CardListing.objects.create(card=self.card, seller=self.seller, price=10, quantity=2, status='sold')
|
||||
|
||||
response = self.client.get(url, {'hide_out_of_stock': 'off'})
|
||||
# Should be 5 + 3 = 8
|
||||
self.assertEqual(response.context['page_obj'][0].total_quantity, 8)
|
||||
|
||||
@@ -4,6 +4,8 @@ from django.db.models import Q
|
||||
from django.core.paginator import Paginator
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from .models import Card, Game, Set, Cart, CartItem, CardListing, PackListing, VirtualPack, Order, OrderItem, Seller, Bounty, BountyOffer, SellerReport
|
||||
from django.db.models import Sum, Value
|
||||
from django.db.models.functions import Coalesce
|
||||
from .forms import SellerRegistrationForm, CardListingForm, PackListingForm, AddCardListingForm, SellerEditForm, BountyForm, BountyOfferForm, BulkListingForm
|
||||
from django.utils.text import slugify
|
||||
import random
|
||||
@@ -19,6 +21,14 @@ def index(request):
|
||||
def card_list(request):
|
||||
cards = Card.objects.all().select_related('set', 'set__game').prefetch_related('listings')
|
||||
|
||||
# Annotate with total quantity of listed items
|
||||
cards = cards.annotate(
|
||||
total_quantity=Coalesce(
|
||||
Sum('listings__quantity', filter=Q(listings__status='listed')),
|
||||
Value(0)
|
||||
)
|
||||
)
|
||||
|
||||
# Filtering
|
||||
game_slug = request.GET.get('game')
|
||||
if game_slug:
|
||||
@@ -43,7 +53,7 @@ def card_list(request):
|
||||
hide_oos = 'on'
|
||||
|
||||
if hide_oos == 'on':
|
||||
cards = cards.filter(listings__quantity__gt=0, listings__status='listed').distinct()
|
||||
cards = cards.filter(total_quantity__gt=0)
|
||||
|
||||
# Simple logic: only show cards that have listings or show all?
|
||||
# Let's show all for browsing, but indicate stock.
|
||||
|
||||
Reference in New Issue
Block a user