Skip to content

Commit

Permalink
feat(Users): Stats: new location country count & price currency count (
Browse files Browse the repository at this point in the history
  • Loading branch information
raphodn authored Feb 2, 2025
1 parent 0e2f575 commit 6834f9c
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 9 deletions.
6 changes: 4 additions & 2 deletions open_prices/common/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ def update_user_counts_task():
Update all user field counts
"""
for user in User.objects.all():
for field in User.COUNT_FIELDS:
getattr(user, f"update_{field}")()
user.update_price_count()
user.update_location_count()
user.update_product_count()
user.update_proof_count()


def update_location_counts_task():
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.1.4 on 2025-02-02 16:39

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("users", "0004_user_proof_count"),
]

operations = [
migrations.AddField(
model_name="user",
name="location_type_osm_country_count",
field=models.PositiveIntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name="user",
name="price_currency_count",
field=models.PositiveIntegerField(blank=True, default=0, null=True),
),
]
36 changes: 33 additions & 3 deletions open_prices/users/models.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
from django.db import models
from django.utils import timezone

from open_prices.locations import constants as location_constants


class UserQuerySet(models.QuerySet):
def has_prices(self):
return self.filter(price_count__gt=0)


class User(models.Model):
COUNT_FIELDS = ["price_count", "location_count", "product_count", "proof_count"]
COUNT_FIELDS = [
"price_count",
"price_currency_count",
"location_count",
"location_type_osm_country_count",
"product_count",
"proof_count",
]
SERIALIZED_FIELDS = [
"user_id",
] + COUNT_FIELDS
Expand All @@ -18,7 +27,11 @@ class User(models.Model):
is_moderator = models.BooleanField(default=False)

price_count = models.PositiveIntegerField(default=0, blank=True, null=True)
price_currency_count = models.PositiveIntegerField(default=0, blank=True, null=True)
location_count = models.PositiveIntegerField(default=0, blank=True, null=True)
location_type_osm_country_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)

Expand All @@ -40,7 +53,13 @@ def update_price_count(self):
from open_prices.prices.models import Price

self.price_count = Price.objects.filter(owner=self.user_id).count()
self.save(update_fields=["price_count"])
self.price_currency_count = (
Price.objects.filter(owner=self.user_id)
.values_list("currency", flat=True)
.distinct()
.count()
)
self.save(update_fields=["price_count", "price_currency_count"])

def update_location_count(self):
from open_prices.proofs.models import Proof
Expand All @@ -51,7 +70,18 @@ def update_location_count(self):
.distinct()
.count()
)
self.save(update_fields=["location_count"])
self.location_type_osm_country_count = (
Proof.objects.select_related("location")
.filter(
owner=self.user_id,
location_id__isnull=False,
location__type=location_constants.TYPE_OSM,
)
.values_list("location__osm_address_country", flat=True)
.distinct()
.count()
)
self.save(update_fields=["location_count", "location_type_osm_country_count"])

def update_product_count(self):
from open_prices.prices.models import Price
Expand Down
22 changes: 18 additions & 4 deletions open_prices/users/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"osm_name": "Monoprix",
"osm_lat": "45.1805534",
"osm_lon": "5.7153387",
"osm_address_city": "Grenoble",
"osm_address_country": "France",
"price_count": 15,
}
LOCATION_ONLINE_DECATHLON = {
Expand Down Expand Up @@ -44,6 +46,7 @@ def setUpTestData(cls):
cls.proof = ProofFactory(
location_osm_id=cls.location_1.osm_id,
location_osm_type=cls.location_1.osm_type,
currency="EUR",
owner=cls.user.user_id,
)
PriceFactory(
Expand All @@ -52,43 +55,54 @@ def setUpTestData(cls):
location_osm_type=cls.location_1.osm_type,
proof_id=cls.proof.id,
price=1.0,
currency=cls.proof.currency,
owner=cls.user.user_id,
)
PriceFactory(
product_code="0123456789101",
location_osm_id=cls.location_2.osm_id,
location_osm_type=cls.location_2.osm_type,
price=2.0,
currency=cls.proof.currency,
owner=cls.user.user_id,
)

def test_update_price_count(self):
self.user.refresh_from_db()
self.assertEqual(self.user.price_count, 2) # price signals
self.assertEqual(self.user.price_currency_count, 0)
# update_price_count() should fix price counts
self.user.update_price_count()
self.assertEqual(self.user.price_count, 2)
self.assertEqual(self.user.price_currency_count, 1)
# bulk delete prices to skip signals
Price.objects.filter(owner=self.user.user_id).delete()
self.assertEqual(self.user.price_count, 2) # should be 0
# update_price_count() should fix price_count
self.assertEqual(self.user.price_currency_count, 1) # should be 0
# update_price_count() should fix price counts
self.user.update_price_count()
self.assertEqual(self.user.price_count, 0)
self.assertEqual(self.user.price_currency_count, 0)

def test_update_location_count(self):
self.user.refresh_from_db()
self.assertEqual(self.user.location_count, 0)
# update_location_count() should fix location_count
self.assertEqual(self.user.location_type_osm_country_count, 0)
# update_location_count() should fix location counts
self.user.update_location_count()
self.assertEqual(self.user.location_count, 1) # proof locations
self.assertEqual(self.user.location_type_osm_country_count, 1)

def test_update_product_count(self):
self.user.refresh_from_db()
self.assertEqual(self.user.product_count, 0)
# update_product_count() should fix product_count
# update_product_count() should fix product counts
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
# update_proof_count() should fix proof counts
self.user.update_proof_count()
self.assertEqual(self.user.proof_count, 1)

0 comments on commit 6834f9c

Please sign in to comment.