diff --git a/open_prices/api/users/tests.py b/open_prices/api/users/tests.py index a3362d1..5797cba 100644 --- a/open_prices/api/users/tests.py +++ b/open_prices/api/users/tests.py @@ -30,7 +30,7 @@ def setUpTestData(cls): cls.url = reverse("api:users-list") UserFactory(price_count=15) UserFactory(price_count=0) - UserFactory(price_count=50, location_count=5, product_count=25) + UserFactory(price_count=50, location_count=5, product_count=25, proof_count=10) def test_user_list_order_by_price_count(self): url = self.url + "?order_by=-price_count" @@ -50,6 +50,12 @@ def test_user_list_order_by_product_count(self): self.assertEqual(response.data["total"], 2) # only users with prices self.assertEqual(response.data["items"][0]["product_count"], 25) + def test_user_list_order_by_proof_count(self): + url = self.url + "?order_by=-proof_count" + response = self.client.get(url) + self.assertEqual(response.data["total"], 2) # only users with prices + self.assertEqual(response.data["items"][0]["proof_count"], 10) + class UserListFilterApiTest(TestCase): @classmethod diff --git a/open_prices/api/users/views.py b/open_prices/api/users/views.py index 6ad7467..4e542e8 100644 --- a/open_prices/api/users/views.py +++ b/open_prices/api/users/views.py @@ -11,5 +11,11 @@ class UserViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): serializer_class = UserSerializer filter_backends = [DjangoFilterBackend, filters.OrderingFilter] filterset_class = UserFilter - ordering_fields = ["user_id", "price_count", "location_count", "product_count"] + ordering_fields = [ + "user_id", + "price_count", + "location_count", + "product_count", + "proof_count", + ] ordering = ["user_id"] diff --git a/open_prices/users/admin.py b/open_prices/users/admin.py index 9e24cf8..64860af 100644 --- a/open_prices/users/admin.py +++ b/open_prices/users/admin.py @@ -10,6 +10,8 @@ class UserAdmin(admin.ModelAdmin): "is_moderator", "price_count", "location_count", + "product_count", + "proof_count", "created", ) list_filter = ("is_moderator",) diff --git a/open_prices/users/migrations/0004_user_proof_count.py b/open_prices/users/migrations/0004_user_proof_count.py new file mode 100644 index 0000000..dc511c3 --- /dev/null +++ b/open_prices/users/migrations/0004_user_proof_count.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1 on 2024-09-12 14:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("users", "0003_user_product_count"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="proof_count", + field=models.PositiveIntegerField(blank=True, default=0, null=True), + ), + ] diff --git a/open_prices/users/models.py b/open_prices/users/models.py index 4eb173d..f872536 100644 --- a/open_prices/users/models.py +++ b/open_prices/users/models.py @@ -8,7 +8,13 @@ def has_prices(self): class User(models.Model): - SERIALIZED_FIELDS = ["user_id", "price_count", "location_count", "product_count"] + SERIALIZED_FIELDS = [ + "user_id", + "price_count", + "location_count", + "product_count", + "proof_count", + ] user_id = models.CharField(primary_key=True) @@ -17,6 +23,7 @@ class User(models.Model): price_count = models.PositiveIntegerField(default=0, blank=True, null=True) location_count = models.PositiveIntegerField(default=0, blank=True, null=True) product_count = models.PositiveIntegerField(default=0, blank=True, null=True) + proof_count = models.PositiveIntegerField(default=0, blank=True, null=True) created = models.DateTimeField(default=timezone.now) # updated = models.DateTimeField(auto_now=True) @@ -60,6 +67,17 @@ def update_product_count(self): ) self.save(update_fields=["product_count"]) + def update_proof_count(self): + from open_prices.prices.models import Price + + self.proof_count = ( + Price.objects.filter(owner=self.user_id) + .values_list("proof_id", flat=True) + .distinct() + .count() + ) + self.save(update_fields=["proof_count"]) + class Session(models.Model): user = models.ForeignKey( diff --git a/open_prices/users/tests.py b/open_prices/users/tests.py index e4463b1..06efe36 100644 --- a/open_prices/users/tests.py +++ b/open_prices/users/tests.py @@ -3,6 +3,7 @@ from open_prices.locations.factories import LocationFactory from open_prices.prices.factories import PriceFactory from open_prices.prices.models import Price +from open_prices.proofs.factories import ProofFactory from open_prices.users.factories import UserFactory from open_prices.users.models import User @@ -29,10 +30,16 @@ class UserPropertyTest(TestCase): def setUpTestData(cls): cls.user = UserFactory() cls.location = LocationFactory(**LOCATION_NODE_652825274) + cls.proof = ProofFactory( + location_osm_id=cls.location.osm_id, + location_osm_type=cls.location.osm_type, + owner=cls.user.user_id, + ) PriceFactory( product_code="0123456789100", location_osm_id=cls.location.osm_id, location_osm_type=cls.location.osm_type, + proof_id=cls.proof.id, price=1.0, owner=cls.user.user_id, ) @@ -40,6 +47,7 @@ def setUpTestData(cls): product_code="0123456789101", location_osm_id=cls.location.osm_id, location_osm_type=cls.location.osm_type, + proof_id=cls.proof.id, price=2.0, owner=cls.user.user_id, ) @@ -67,3 +75,10 @@ def test_update_product_count(self): # update_product_count() should fix product_count self.user.update_product_count() self.assertEqual(self.user.product_count, 2) + + def test_update_proof_count(self): + self.user.refresh_from_db() + self.assertEqual(self.user.proof_count, 0) + # update_proof_count() should fix proof_count + self.user.update_proof_count() + self.assertEqual(self.user.proof_count, 1)