mirror of
https://github.com/ae-utbm/sith.git
synced 2026-02-20 21:08:39 +00:00
Compare commits
2 Commits
taiste
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30c327a6f1 | ||
|
|
2995823d6e |
@@ -35,7 +35,7 @@ TODO : rewrite the pagination used in this template an Alpine one
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<p><input type="submit" value="{% trans %}Show{% endtrans %}" /></p>
|
||||
<p><input type="submit" value="{% trans %}Download as CSV{% endtrans %}" formaction="{{ url('club:sellings_csv', club_id=object.id) }}"/></p>
|
||||
<p><input type="submit" value="{% trans %}Download as cvs{% endtrans %}" formaction="{{ url('club:sellings_csv', club_id=object.id) }}"/></p>
|
||||
</form>
|
||||
<p>
|
||||
{% trans %}Quantity: {% endtrans %}{{ total_quantity }} {% trans %}units{% endtrans %}<br/>
|
||||
|
||||
@@ -12,7 +12,7 @@ from django.utils.timezone import localdate, make_aware, now
|
||||
from faker import Faker
|
||||
|
||||
from club.models import Club, Membership
|
||||
from core.models import Group, User, UserBan
|
||||
from core.models import Group, User
|
||||
from counter.models import (
|
||||
Counter,
|
||||
Customer,
|
||||
@@ -40,7 +40,6 @@ class Command(BaseCommand):
|
||||
|
||||
self.stdout.write("Creating users...")
|
||||
users = self.create_users()
|
||||
self.create_bans(random.sample(users, k=len(users) // 200)) # 0.5% of users
|
||||
subscribers = random.sample(users, k=int(0.8 * len(users)))
|
||||
self.stdout.write("Creating subscriptions...")
|
||||
self.create_subscriptions(subscribers)
|
||||
@@ -89,8 +88,6 @@ class Command(BaseCommand):
|
||||
self.stdout.write("Done")
|
||||
|
||||
def create_users(self) -> list[User]:
|
||||
# Create a single password hash for all users to make it faster.
|
||||
# It's insecure as hell, but it's ok since it's only for dev purposes.
|
||||
password = make_password("plop")
|
||||
users = [
|
||||
User(
|
||||
@@ -117,33 +114,14 @@ class Command(BaseCommand):
|
||||
public_group.users.add(*users)
|
||||
return users
|
||||
|
||||
def create_bans(self, users: list[User]):
|
||||
ban_groups = [
|
||||
settings.SITH_GROUP_BANNED_COUNTER_ID,
|
||||
settings.SITH_GROUP_BANNED_SUBSCRIPTION_ID,
|
||||
settings.SITH_GROUP_BANNED_ALCOHOL_ID,
|
||||
]
|
||||
UserBan.objects.bulk_create(
|
||||
[
|
||||
UserBan(
|
||||
user=user,
|
||||
ban_group_id=i,
|
||||
reason=self.faker.sentence(),
|
||||
expires_at=make_aware(self.faker.future_datetime("+1y")),
|
||||
)
|
||||
for user in users
|
||||
for i in random.sample(ban_groups, k=random.randint(1, len(ban_groups)))
|
||||
]
|
||||
)
|
||||
|
||||
def create_subscriptions(self, users: list[User]):
|
||||
def prepare_subscription(_user: User, start_date: date) -> Subscription:
|
||||
payment_method = random.choice(settings.SITH_SUBSCRIPTION_PAYMENT_METHOD)[0]
|
||||
duration = random.randint(1, 4)
|
||||
s = Subscription(member=_user, payment_method=payment_method)
|
||||
s.subscription_start = s.compute_start(d=start_date, duration=duration)
|
||||
s.subscription_end = s.compute_end(duration)
|
||||
return s
|
||||
sub = Subscription(member=_user, payment_method=payment_method)
|
||||
sub.subscription_start = sub.compute_start(d=start_date, duration=duration)
|
||||
sub.subscription_end = sub.compute_end(duration)
|
||||
return sub
|
||||
|
||||
subscriptions = []
|
||||
customers = []
|
||||
|
||||
@@ -39,9 +39,8 @@ class ProductAdmin(SearchModelAdmin):
|
||||
"code",
|
||||
"product_type",
|
||||
"selling_price",
|
||||
"profit",
|
||||
"archived",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
)
|
||||
list_select_related = ("product_type",)
|
||||
search_fields = ("name", "code")
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
# Generated by Django 5.2.8 on 2026-02-10 15:40
|
||||
from operator import attrgetter
|
||||
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
from django.db.migrations.state import StateApps
|
||||
from django.db.models import OuterRef, Subquery
|
||||
|
||||
from counter.models import Selling
|
||||
|
||||
|
||||
def apply_product_history_dates(apps: StateApps, schema_editor):
|
||||
"""Approximate a posteriori the value of created_at and updated_at."""
|
||||
Product = apps.get_model("counter", "Product")
|
||||
sales_subquery = Selling.objects.filter(product=OuterRef("pk")).values("date")
|
||||
|
||||
# for products that have an associated sale, we set the creation date
|
||||
# to the one of the first sale, and the update date to the one of the last sale
|
||||
products = list(
|
||||
Product.objects.exclude(sellings=None)
|
||||
.annotate(
|
||||
new_created_at=Subquery(sales_subquery.order_by("date")[:1]),
|
||||
new_updated_at=Subquery(sales_subquery.order_by("-date")[:1]),
|
||||
)
|
||||
.only("id")
|
||||
)
|
||||
for product in products:
|
||||
product.created_at = product.new_created_at
|
||||
product.updated_at = product.new_updated_at
|
||||
|
||||
# For the remaining products (those without sale),
|
||||
# they are given the creation and update date of the previous product having sales.
|
||||
products_without_sale = list(Product.objects.filter(sellings=None).only("id"))
|
||||
for product in products_without_sale:
|
||||
previous_product = max(
|
||||
(p for p in products if p.id < product.id), key=attrgetter("id")
|
||||
)
|
||||
product.created_at = previous_product.created_at
|
||||
product.updated_at = previous_product.updated_at
|
||||
products.extend(products_without_sale)
|
||||
|
||||
Product.objects.bulk_update(products, fields=["created_at", "updated_at"])
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [("counter", "0035_remove_selling_is_validated_and_more")]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="created_at",
|
||||
field=models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
default=django.utils.timezone.now,
|
||||
verbose_name="created at",
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="updated_at",
|
||||
field=models.DateTimeField(auto_now=True, verbose_name="updated at"),
|
||||
),
|
||||
migrations.RunPython(
|
||||
apply_product_history_dates, reverse_code=migrations.RunPython.noop
|
||||
),
|
||||
]
|
||||
@@ -399,8 +399,6 @@ class Product(models.Model):
|
||||
Group, related_name="products", verbose_name=_("buying groups"), blank=True
|
||||
)
|
||||
archived = models.BooleanField(_("archived"), default=False)
|
||||
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
|
||||
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("product")
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
{% block content %}
|
||||
{% if object %}
|
||||
<h2>{% trans name=object %}Edit product {{ name }}{% endtrans %}</h2>
|
||||
<p><i>{% trans %}Creation date{% endtrans %} : {{ object.created_at|date }}</i></p>
|
||||
<p><i>{% trans %}Last update{% endtrans %} : {{ object.updated_at|date }}</i></p>
|
||||
{% else %}
|
||||
<h2>{% trans %}Product creation{% endtrans %}</h2>
|
||||
{% endif %}
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
:disabled="csvLoading"
|
||||
:aria-busy="csvLoading"
|
||||
>
|
||||
{% trans %}Download as CSV{% endtrans %} <i class="fa fa-file-arrow-down"></i>
|
||||
{% trans %}Download as cvs{% endtrans %} <i class="fa fa-file-arrow-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-02-14 15:21+0100\n"
|
||||
"POT-Creation-Date: 2026-02-08 16:14+0100\n"
|
||||
"PO-Revision-Date: 2016-07-18\n"
|
||||
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||
@@ -388,7 +388,7 @@ msgstr "Montrer"
|
||||
|
||||
#: club/templates/club/club_sellings.jinja
|
||||
#: counter/templates/counter/product_list.jinja
|
||||
msgid "Download as CSV"
|
||||
msgid "Download as cvs"
|
||||
msgstr "Télécharger en CSV"
|
||||
|
||||
#: club/templates/club/club_sellings.jinja
|
||||
@@ -1566,7 +1566,7 @@ msgstr "Visiteur"
|
||||
msgid "ban type"
|
||||
msgstr "type de ban"
|
||||
|
||||
#: core/models.py counter/models.py
|
||||
#: core/models.py
|
||||
msgid "created at"
|
||||
msgstr "créé le"
|
||||
|
||||
@@ -3109,10 +3109,6 @@ msgstr "groupe d'achat"
|
||||
msgid "archived"
|
||||
msgstr "archivé"
|
||||
|
||||
#: counter/models.py
|
||||
msgid "updated at"
|
||||
msgstr "mis à jour le"
|
||||
|
||||
#: counter/models.py
|
||||
msgid "product"
|
||||
msgstr "produit"
|
||||
@@ -3668,14 +3664,6 @@ msgstr ""
|
||||
msgid "Edit product %(name)s"
|
||||
msgstr "Édition du produit %(name)s"
|
||||
|
||||
#: counter/templates/counter/product_form.jinja
|
||||
msgid "Creation date"
|
||||
msgstr "Date de création"
|
||||
|
||||
#: counter/templates/counter/product_form.jinja
|
||||
msgid "Last update"
|
||||
msgstr "Dernière mise à jour"
|
||||
|
||||
#: counter/templates/counter/product_form.jinja
|
||||
msgid "Product creation"
|
||||
msgstr "Création de produit"
|
||||
@@ -3963,8 +3951,8 @@ msgid ""
|
||||
"inconvenience."
|
||||
msgstr ""
|
||||
"Les paiements par carte bancaire sont actuellement désactivés sur l'eboutic. "
|
||||
"Vous pouvez cependant toujours recharger votre compte dans un des lieux de "
|
||||
"vie de l'AE. Veuillez nous excuser pour le désagrément."
|
||||
"Vous pouvez cependant toujours recharger votre compte dans un des lieux de vie de l'AE. "
|
||||
"Veuillez nous excuser pour le désagrément."
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_checkout.jinja
|
||||
msgid ""
|
||||
@@ -4133,8 +4121,8 @@ msgstr "Les candidatures sont fermées pour cette élection"
|
||||
#: election/templates/election/election_detail.jinja
|
||||
msgid "Candidate pictures won't display for privacy reasons."
|
||||
msgstr ""
|
||||
"La photo du candidat ne s'affiche pas pour des raisons de respect de la vie "
|
||||
"privée."
|
||||
"La photo du candidat ne s'affiche pas pour "
|
||||
"des raisons de respect de la vie privée."
|
||||
|
||||
#: election/templates/election/election_detail.jinja
|
||||
msgid "Polls close "
|
||||
|
||||
14
uv.lock
generated
14
uv.lock
generated
@@ -775,11 +775,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.20.0"
|
||||
version = "3.21.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/73/71/74364ff065ca78914d8bd90b312fe78ddc5e11372d38bc9cb7104f887ce1/filelock-3.21.2.tar.gz", hash = "sha256:cfd218cfccf8b947fce7837da312ec3359d10ef2a47c8602edd59e0bacffb708", size = 31486, upload-time = "2026-02-13T01:27:15.223Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/73/3a18f1e1276810e81477c431009b55eeccebbd7301d28a350b77aacf3c33/filelock-3.21.2-py3-none-any.whl", hash = "sha256:d6cd4dbef3e1bb63bc16500fc5aa100f16e405bbff3fb4231711851be50c1560", size = 21479, upload-time = "2026-02-13T01:27:13.611Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2380,16 +2380,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
version = "20.35.4"
|
||||
version = "20.36.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "distlib" },
|
||||
{ name = "filelock" },
|
||||
{ name = "platformdirs" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba", size = 6032239, upload-time = "2026-01-09T18:21:01.296Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f", size = 6008258, upload-time = "2026-01-09T18:20:59.425Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2446,4 +2446,4 @@ dependencies = [
|
||||
{ name = "django-haystack" },
|
||||
{ name = "filelock" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a3/db/c6219763f6c4519cdaae812e60fd9471a7805de2b39d912931e45575c8e6/xapian-haystack-3.1.0.tar.gz", hash = "sha256:9f9ab90bf450bf6699d164594d569243aafb6c9f0990a16855f55a1d16bc09c6", size = 37887, upload-time = "2023-03-19T11:58:37.035Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a3/db/c6219763f6c4519cdaae812e60fd9471a7805de2b39d912931e45575c8e6/xapian-haystack-3.1.0.tar.gz", hash = "sha256:9f9ab90bf450bf6699d164594d569243aafb6c9f0990a16855f55a1d16bc09c6", size = 37887, upload-time = "2023-03-19T11:58:37.035Z" }
|
||||
|
||||
Reference in New Issue
Block a user