mirror of
https://github.com/ae-utbm/sith.git
synced 2024-12-24 16:51:17 +00:00
ruff rule DJ
Co-authored-by: Bartuccio Antoine <klmp200@users.noreply.github.com>
This commit is contained in:
parent
f941435232
commit
2ac578c3ad
@ -61,6 +61,15 @@ class Company(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("company")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:co_edit", kwargs={"co_id": self.id})
|
||||
|
||||
def get_display_name(self):
|
||||
return self.name
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -87,15 +96,6 @@ class Company(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:co_edit", kwargs={"co_id": self.id})
|
||||
|
||||
def get_display_name(self):
|
||||
return self.name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class BankAccount(models.Model):
|
||||
name = models.CharField(_("name"), max_length=30)
|
||||
@ -112,6 +112,12 @@ class BankAccount(models.Model):
|
||||
verbose_name = _("Bank account")
|
||||
ordering = ["club", "name"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:bank_details", kwargs={"b_account_id": self.id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -125,12 +131,6 @@ class BankAccount(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:bank_details", kwargs={"b_account_id": self.id})
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class ClubAccount(models.Model):
|
||||
name = models.CharField(_("name"), max_length=30)
|
||||
@ -151,6 +151,12 @@ class ClubAccount(models.Model):
|
||||
verbose_name = _("Club account")
|
||||
ordering = ["bank_account", "name"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:club_details", kwargs={"c_account_id": self.id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -188,12 +194,6 @@ class ClubAccount(models.Model):
|
||||
def get_open_journal(self):
|
||||
return self.journals.filter(closed=False).first()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:club_details", kwargs={"c_account_id": self.id})
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_display_name(self):
|
||||
return _("%(club_account)s on %(bank_account)s") % {
|
||||
"club_account": self.name,
|
||||
@ -224,6 +224,12 @@ class GeneralJournal(models.Model):
|
||||
verbose_name = _("General journal")
|
||||
ordering = ["-start_date"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:journal_details", kwargs={"j_id": self.id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -249,12 +255,6 @@ class GeneralJournal(models.Model):
|
||||
def can_be_viewed_by(self, user):
|
||||
return self.club_account.can_be_viewed_by(user)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:journal_details", kwargs={"j_id": self.id})
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def update_amounts(self):
|
||||
self.amount = 0
|
||||
self.effective_amount = 0
|
||||
@ -356,6 +356,18 @@ class Operation(models.Model):
|
||||
unique_together = ("number", "journal")
|
||||
ordering = ["-number"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.amount} € | {self.date} | {self.accounting_type} | {self.done}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.number is None:
|
||||
self.number = self.journal.operations.count() + 1
|
||||
super().save(*args, **kwargs)
|
||||
self.journal.update_amounts()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:journal_details", kwargs={"j_id": self.journal.id})
|
||||
|
||||
def __getattribute__(self, attr):
|
||||
if attr == "target":
|
||||
return self.get_target()
|
||||
@ -409,12 +421,6 @@ class Operation(models.Model):
|
||||
tar = Company.objects.filter(id=self.target_id).first()
|
||||
return tar
|
||||
|
||||
def save(self):
|
||||
if self.number is None:
|
||||
self.number = self.journal.operations.count() + 1
|
||||
super().save()
|
||||
self.journal.update_amounts()
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -443,17 +449,6 @@ class Operation(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:journal_details", kwargs={"j_id": self.journal.id})
|
||||
|
||||
def __str__(self):
|
||||
return "%d € | %s | %s | %s" % (
|
||||
self.amount,
|
||||
self.date,
|
||||
self.accounting_type,
|
||||
self.done,
|
||||
)
|
||||
|
||||
|
||||
class AccountingType(models.Model):
|
||||
"""
|
||||
@ -486,6 +481,12 @@ class AccountingType(models.Model):
|
||||
verbose_name = _("accounting type")
|
||||
ordering = ["movement_type", "code"]
|
||||
|
||||
def __str__(self):
|
||||
return self.code + " - " + self.get_movement_type_display() + " - " + self.label
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:type_list")
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -496,12 +497,6 @@ class AccountingType(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:type_list")
|
||||
|
||||
def __str__(self):
|
||||
return self.code + " - " + self.get_movement_type_display() + " - " + self.label
|
||||
|
||||
|
||||
class SimplifiedAccountingType(models.Model):
|
||||
"""
|
||||
@ -520,6 +515,15 @@ class SimplifiedAccountingType(models.Model):
|
||||
verbose_name = _("simplified type")
|
||||
ordering = ["accounting_type__movement_type", "accounting_type__code"]
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"{self.get_movement_type_display()} "
|
||||
f"- {self.accounting_type.code} - {self.label}"
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:simple_type_list")
|
||||
|
||||
@property
|
||||
def movement_type(self):
|
||||
return self.accounting_type.movement_type
|
||||
@ -527,18 +531,6 @@ class SimplifiedAccountingType(models.Model):
|
||||
def get_movement_type_display(self):
|
||||
return self.accounting_type.get_movement_type_display()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("accounting:simple_type_list")
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
self.get_movement_type_display()
|
||||
+ " - "
|
||||
+ self.accounting_type.code
|
||||
+ " - "
|
||||
+ self.label
|
||||
)
|
||||
|
||||
|
||||
class Label(models.Model):
|
||||
"""Label allow a club to sort its operations"""
|
||||
|
@ -15,7 +15,7 @@ class Migration(migrations.Migration):
|
||||
name="owner_group",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
default=club.models.Club.get_default_owner_group,
|
||||
default=club.models.get_default_owner_group,
|
||||
related_name="owned_club",
|
||||
to="core.Group",
|
||||
),
|
||||
|
140
club/models.py
140
club/models.py
@ -40,6 +40,11 @@ from core.models import Group, MetaGroup, Notification, Page, RealGroup, SithFil
|
||||
# Create your models here.
|
||||
|
||||
|
||||
# This function prevents generating migration upon settings change
|
||||
def get_default_owner_group():
|
||||
return settings.SITH_GROUP_ROOT_ID
|
||||
|
||||
|
||||
class Club(models.Model):
|
||||
"""
|
||||
The Club class, made as a tree to allow nice tidy organization
|
||||
@ -74,10 +79,6 @@ class Club(models.Model):
|
||||
)
|
||||
address = models.CharField(_("address"), max_length=254)
|
||||
|
||||
# This function prevents generating migration upon settings change
|
||||
def get_default_owner_group():
|
||||
return settings.SITH_GROUP_ROOT_ID
|
||||
|
||||
owner_group = models.ForeignKey(
|
||||
Group,
|
||||
related_name="owned_club",
|
||||
@ -105,6 +106,34 @@ class Club(models.Model):
|
||||
class Meta:
|
||||
ordering = ["name", "unix_name"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@transaction.atomic()
|
||||
def save(self, *args, **kwargs):
|
||||
old = Club.objects.filter(id=self.id).first()
|
||||
creation = old is None
|
||||
if not creation and old.unix_name != self.unix_name:
|
||||
self._change_unixname(self.unix_name)
|
||||
super().save(*args, **kwargs)
|
||||
if creation:
|
||||
board = MetaGroup(name=self.unix_name + settings.SITH_BOARD_SUFFIX)
|
||||
board.save()
|
||||
member = MetaGroup(name=self.unix_name + settings.SITH_MEMBER_SUFFIX)
|
||||
member.save()
|
||||
subscribers = Group.objects.filter(
|
||||
name=settings.SITH_MAIN_MEMBERS_GROUP
|
||||
).first()
|
||||
self.make_home()
|
||||
self.home.edit_groups.set([board])
|
||||
self.home.view_groups.set([member, subscribers])
|
||||
self.home.save()
|
||||
self.make_page()
|
||||
cache.set(f"sith_club_{self.unix_name}", self)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("club:club_view", kwargs={"club_id": self.id})
|
||||
|
||||
@cached_property
|
||||
def president(self):
|
||||
return self.members.filter(
|
||||
@ -183,28 +212,6 @@ class Club(models.Model):
|
||||
self.page.parent = self.parent.page
|
||||
self.page.save(force_lock=True)
|
||||
|
||||
@transaction.atomic()
|
||||
def save(self, *args, **kwargs):
|
||||
old = Club.objects.filter(id=self.id).first()
|
||||
creation = old is None
|
||||
if not creation and old.unix_name != self.unix_name:
|
||||
self._change_unixname(self.unix_name)
|
||||
super().save(*args, **kwargs)
|
||||
if creation:
|
||||
board = MetaGroup(name=self.unix_name + settings.SITH_BOARD_SUFFIX)
|
||||
board.save()
|
||||
member = MetaGroup(name=self.unix_name + settings.SITH_MEMBER_SUFFIX)
|
||||
member.save()
|
||||
subscribers = Group.objects.filter(
|
||||
name=settings.SITH_MAIN_MEMBERS_GROUP
|
||||
).first()
|
||||
self.make_home()
|
||||
self.home.edit_groups.set([board])
|
||||
self.home.view_groups.set([member, subscribers])
|
||||
self.home.save()
|
||||
self.make_page()
|
||||
cache.set(f"sith_club_{self.unix_name}", self)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
# Invalidate the cache of this club and of its memberships
|
||||
for membership in self.members.ongoing().select_related("user"):
|
||||
@ -212,12 +219,6 @@ class Club(models.Model):
|
||||
cache.delete(f"sith_club_{self.unix_name}")
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("club:club_view", kwargs={"club_id": self.id})
|
||||
|
||||
def get_display_name(self):
|
||||
return self.name
|
||||
|
||||
@ -373,14 +374,21 @@ class Membership(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
self.club.name
|
||||
+ " - "
|
||||
+ self.user.username
|
||||
+ " - "
|
||||
+ str(settings.SITH_CLUB_ROLES[self.role])
|
||||
+ str(" - " + str(_("past member")) if self.end_date is not None else "")
|
||||
f"{self.club.name} - {self.user.username} "
|
||||
f"- {settings.SITH_CLUB_ROLES[self.role]} "
|
||||
f"- {str(_('past member')) if self.end_date is not None else ''}"
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
if self.end_date is None:
|
||||
cache.set(f"membership_{self.club_id}_{self.user_id}", self)
|
||||
else:
|
||||
cache.set(f"membership_{self.club_id}_{self.user_id}", "not_member")
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("club:club_members", kwargs={"club_id": self.club_id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be super edited by the given user
|
||||
@ -400,16 +408,6 @@ class Membership(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("club:club_members", kwargs={"club_id": self.club_id})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
if self.end_date is None:
|
||||
cache.set(f"membership_{self.club_id}_{self.user_id}", self)
|
||||
else:
|
||||
cache.set(f"membership_{self.club_id}_{self.user_id}", "not_member")
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
super().delete(*args, **kwargs)
|
||||
cache.delete(f"membership_{self.club_id}_{self.user_id}")
|
||||
@ -451,6 +449,26 @@ class Mailing(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s" % (self.club, self.email_full)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.is_moderated:
|
||||
for user in (
|
||||
RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID)
|
||||
.first()
|
||||
.users.all()
|
||||
):
|
||||
if not user.notifications.filter(
|
||||
type="MAILING_MODERATION", viewed=False
|
||||
).exists():
|
||||
Notification(
|
||||
user=user,
|
||||
url=reverse("com:mailing_admin"),
|
||||
type="MAILING_MODERATION",
|
||||
).save(*args, **kwargs)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
if Mailing.objects.filter(email=self.email).exists():
|
||||
raise ValidationError(_("This mailing list already exists."))
|
||||
@ -488,26 +506,6 @@ class Mailing(models.Model):
|
||||
resp += sub.fetch_format()
|
||||
return resp
|
||||
|
||||
def save(self):
|
||||
if not self.is_moderated:
|
||||
for user in (
|
||||
RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID)
|
||||
.first()
|
||||
.users.all()
|
||||
):
|
||||
if not user.notifications.filter(
|
||||
type="MAILING_MODERATION", viewed=False
|
||||
).exists():
|
||||
Notification(
|
||||
user=user,
|
||||
url=reverse("com:mailing_admin"),
|
||||
type="MAILING_MODERATION",
|
||||
).save()
|
||||
super().save()
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s" % (self.club, self.email_full)
|
||||
|
||||
|
||||
class MailingSubscription(models.Model):
|
||||
"""
|
||||
@ -535,6 +533,9 @@ class MailingSubscription(models.Model):
|
||||
class Meta:
|
||||
unique_together = (("user", "email", "mailing"),)
|
||||
|
||||
def __str__(self):
|
||||
return "(%s) - %s : %s" % (self.mailing, self.get_username, self.email)
|
||||
|
||||
def clean(self):
|
||||
if not self.user and not self.email:
|
||||
raise ValidationError(_("At least user or email is required"))
|
||||
@ -577,6 +578,3 @@ class MailingSubscription(models.Model):
|
||||
|
||||
def fetch_format(self):
|
||||
return self.get_email + " "
|
||||
|
||||
def __str__(self):
|
||||
return "(%s) - %s : %s" % (self.mailing, self.get_username, self.email)
|
||||
|
@ -46,14 +46,14 @@ class Sith(models.Model):
|
||||
weekmail_destinations = models.TextField(_("weekmail destinations"), default="")
|
||||
version = utils.get_git_revision_short_hash()
|
||||
|
||||
def __str__(self):
|
||||
return "⛩ Sith ⛩"
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_com_admin
|
||||
|
||||
def __str__(self):
|
||||
return "⛩ Sith ⛩"
|
||||
|
||||
|
||||
NEWS_TYPES = [
|
||||
("NOTICE", _("Notice")),
|
||||
@ -90,23 +90,6 @@ class News(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_com_admin or user == self.author
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
return user.is_com_admin
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
return self.is_moderated or user.is_com_admin
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("com:news_detail", kwargs={"news_id": self.id})
|
||||
|
||||
def get_full_url(self):
|
||||
return "https://%s%s" % (settings.SITH_URL, self.get_absolute_url())
|
||||
|
||||
def __str__(self):
|
||||
return "%s: %s" % (self.type, self.title)
|
||||
|
||||
@ -124,6 +107,23 @@ class News(models.Model):
|
||||
param="1",
|
||||
).save()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("com:news_detail", kwargs={"news_id": self.id})
|
||||
|
||||
def get_full_url(self):
|
||||
return "https://%s%s" % (settings.SITH_URL, self.get_absolute_url())
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_com_admin or user == self.author
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
return user.is_com_admin
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
return self.is_moderated or user.is_com_admin
|
||||
|
||||
|
||||
def news_notification_callback(notif):
|
||||
count = (
|
||||
@ -185,6 +185,9 @@ class Weekmail(models.Model):
|
||||
class Meta:
|
||||
ordering = ["-id"]
|
||||
|
||||
def __str__(self):
|
||||
return f"Weekmail {self.id} (sent: {self.sent}) - {self.title}"
|
||||
|
||||
def send(self):
|
||||
"""
|
||||
Send the weekmail to all users with the receive weekmail option opt-in.
|
||||
@ -240,9 +243,6 @@ class Weekmail(models.Model):
|
||||
"""
|
||||
return "http://" + settings.SITH_URL + static("com/img/weekmail_footerP22.png")
|
||||
|
||||
def __str__(self):
|
||||
return "Weekmail %s (sent: %s) - %s" % (self.id, self.sent, self.title)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
@ -273,18 +273,21 @@ class WeekmailArticle(models.Model):
|
||||
)
|
||||
rank = models.IntegerField(_("rank"), default=-1)
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s (%s)" % (self.title, self.author, self.club)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_com_admin
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s (%s)" % (self.title, self.author, self.club)
|
||||
|
||||
|
||||
class Screen(models.Model):
|
||||
name = models.CharField(_("name"), max_length=128)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def active_posters(self):
|
||||
now = timezone.now()
|
||||
return self.posters.filter(is_moderated=True, date_begin__lte=now).filter(
|
||||
@ -296,9 +299,6 @@ class Screen(models.Model):
|
||||
return False
|
||||
return user.is_com_admin
|
||||
|
||||
def __str__(self):
|
||||
return "%s" % (self.name)
|
||||
|
||||
|
||||
class Poster(models.Model):
|
||||
name = models.CharField(
|
||||
@ -328,6 +328,9 @@ class Poster(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.is_moderated:
|
||||
for u in (
|
||||
@ -360,6 +363,3 @@ class Poster(models.Model):
|
||||
@property
|
||||
def page(self):
|
||||
return self.club.page
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -16,7 +16,7 @@ class Migration(migrations.Migration):
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
verbose_name="owner group",
|
||||
default=core.models.Page.get_default_owner_group,
|
||||
default=core.models.get_default_owner_group,
|
||||
related_name="owned_page",
|
||||
to="core.Group",
|
||||
),
|
||||
|
177
core/models.py
177
core/models.py
@ -845,12 +845,15 @@ class Preferences(models.Model):
|
||||
_("get a notification for every refilling"), default=False
|
||||
)
|
||||
|
||||
def get_display_name(self):
|
||||
return self.user.get_display_name()
|
||||
def __str__(self):
|
||||
return f"Preferences of {self.user}"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.user.get_absolute_url()
|
||||
|
||||
def get_display_name(self):
|
||||
return self.user.get_display_name()
|
||||
|
||||
|
||||
def get_directory(instance, filename):
|
||||
return ".{0}/{1}".format(instance.get_parent_path(), filename)
|
||||
@ -928,6 +931,31 @@ class SithFile(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("file")
|
||||
|
||||
def __str__(self):
|
||||
return self.get_parent_path() + "/" + self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
sas = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first()
|
||||
self.is_in_sas = sas in self.get_parent_list() or self == sas
|
||||
copy_rights = False
|
||||
if self.id is None:
|
||||
copy_rights = True
|
||||
super().save(*args, **kwargs)
|
||||
if copy_rights:
|
||||
self.copy_rights()
|
||||
if self.is_in_sas:
|
||||
for u in (
|
||||
RealGroup.objects.filter(id=settings.SITH_GROUP_SAS_ADMIN_ID)
|
||||
.first()
|
||||
.users.all()
|
||||
):
|
||||
Notification(
|
||||
user=u,
|
||||
url=reverse("sas:moderation"),
|
||||
type="SAS_MODERATION",
|
||||
param="1",
|
||||
).save()
|
||||
|
||||
def can_be_managed_by(self, user: User) -> bool:
|
||||
"""
|
||||
Tell if the user can manage the file (edit, delete, etc.) or not.
|
||||
@ -1033,28 +1061,6 @@ class SithFile(models.Model):
|
||||
if self.is_file and (self.file is None or self.file == ""):
|
||||
raise ValidationError(_("You must provide a file"))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
sas = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first()
|
||||
self.is_in_sas = sas in self.get_parent_list() or self == sas
|
||||
copy_rights = False
|
||||
if self.id is None:
|
||||
copy_rights = True
|
||||
super().save(*args, **kwargs)
|
||||
if copy_rights:
|
||||
self.copy_rights()
|
||||
if self.is_in_sas:
|
||||
for u in (
|
||||
RealGroup.objects.filter(id=settings.SITH_GROUP_SAS_ADMIN_ID)
|
||||
.first()
|
||||
.users.all()
|
||||
):
|
||||
Notification(
|
||||
user=u,
|
||||
url=reverse("sas:moderation"),
|
||||
type="SAS_MODERATION",
|
||||
param="1",
|
||||
).save()
|
||||
|
||||
def apply_rights_recursively(self, *, only_folders=False):
|
||||
children = self.children.all()
|
||||
if only_folders:
|
||||
@ -1189,9 +1195,6 @@ class SithFile(models.Model):
|
||||
def get_download_url(self):
|
||||
return reverse("core:download", kwargs={"file_id": self.id})
|
||||
|
||||
def __str__(self):
|
||||
return self.get_parent_path() + "/" + self.name
|
||||
|
||||
|
||||
class LockError(Exception):
|
||||
"""There was a lock error on the object"""
|
||||
@ -1211,6 +1214,11 @@ class NotLocked(LockError):
|
||||
pass
|
||||
|
||||
|
||||
# This function prevents generating migration upon settings change
|
||||
def get_default_owner_group():
|
||||
return settings.SITH_GROUP_ROOT_ID
|
||||
|
||||
|
||||
class Page(models.Model):
|
||||
"""
|
||||
The page class to build a Wiki
|
||||
@ -1250,10 +1258,6 @@ class Page(models.Model):
|
||||
# playing with a Page object, use get_full_name() instead!
|
||||
_full_name = models.CharField(_("page name"), max_length=255, blank=True)
|
||||
|
||||
# This function prevents generating migration upon settings change
|
||||
def get_default_owner_group():
|
||||
return settings.SITH_GROUP_ROOT_ID
|
||||
|
||||
owner_group = models.ForeignKey(
|
||||
Group,
|
||||
related_name="owned_page",
|
||||
@ -1286,6 +1290,38 @@ class Page(models.Model):
|
||||
("change_prop_page", "Can change the page's properties (groups, ...)"),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.get_full_name()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
Performs some needed actions before and after saving a page in database
|
||||
"""
|
||||
locked = kwargs.pop("force_lock", False)
|
||||
if not locked:
|
||||
locked = self.is_locked()
|
||||
if not locked:
|
||||
raise NotLocked("The page is not locked and thus can not be saved")
|
||||
self.full_clean()
|
||||
if not self.id:
|
||||
super().save(
|
||||
*args, **kwargs
|
||||
) # Save a first time to correctly set _full_name
|
||||
# This reset the _full_name just before saving to maintain a coherent field quicker for queries than the
|
||||
# recursive method
|
||||
# It also update all the children to maintain correct names
|
||||
self._full_name = self.get_full_name()
|
||||
for c in self.children.all():
|
||||
c.save()
|
||||
super().save(*args, **kwargs)
|
||||
self.unset_lock()
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""
|
||||
This is needed for black magic powered UpdateView's children
|
||||
"""
|
||||
return reverse("core:page", kwargs={"page_name": self._full_name})
|
||||
|
||||
@staticmethod
|
||||
def get_page_by_full_name(name):
|
||||
"""
|
||||
@ -1293,9 +1329,6 @@ class Page(models.Model):
|
||||
"""
|
||||
return Page.objects.filter(_full_name=name).first()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
Cleans up only the name for the moment, but this can be used to make any treatment before saving the object
|
||||
@ -1333,29 +1366,6 @@ class Page(models.Model):
|
||||
p = p.parent
|
||||
return l
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
Performs some needed actions before and after saving a page in database
|
||||
"""
|
||||
locked = kwargs.pop("force_lock", False)
|
||||
if not locked:
|
||||
locked = self.is_locked()
|
||||
if not locked:
|
||||
raise NotLocked("The page is not locked and thus can not be saved")
|
||||
self.full_clean()
|
||||
if not self.id:
|
||||
super().save(
|
||||
*args, **kwargs
|
||||
) # Save a first time to correctly set _full_name
|
||||
# This reset the _full_name just before saving to maintain a coherent field quicker for queries than the
|
||||
# recursive method
|
||||
# It also update all the children to maintain correct names
|
||||
self._full_name = self.get_full_name()
|
||||
for c in self.children.all():
|
||||
c.save()
|
||||
super().save(*args, **kwargs)
|
||||
self.unset_lock()
|
||||
|
||||
def is_locked(self):
|
||||
"""
|
||||
Is True if the page is locked, False otherwise
|
||||
@ -1415,15 +1425,6 @@ class Page(models.Model):
|
||||
return self.lock_user
|
||||
raise NotLocked("The page is not locked and thus can not return its user")
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""
|
||||
This is needed for black magic powered UpdateView's children
|
||||
"""
|
||||
return reverse("core:page", kwargs={"page_name": self._full_name})
|
||||
|
||||
def __str__(self):
|
||||
return self.get_full_name()
|
||||
|
||||
def get_full_name(self):
|
||||
"""
|
||||
Computes the real full_name of the page based on its name and its parent's name
|
||||
@ -1480,15 +1481,22 @@ class PageRev(models.Model):
|
||||
class Meta:
|
||||
ordering = ["date"]
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__dict__)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.revision is None:
|
||||
self.revision = self.page.revisions.all().count() + 1
|
||||
super().save(*args, **kwargs)
|
||||
# Don't forget to unlock, otherwise, people will have to wait for the page's timeout
|
||||
self.page.unset_lock()
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""
|
||||
This is needed for black magic powered UpdateView's children
|
||||
"""
|
||||
return reverse("core:page", kwargs={"page_name": self.page._full_name})
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__dict__)
|
||||
|
||||
def __getattribute__(self, attr):
|
||||
if attr == "owner_group":
|
||||
return self.page.owner_group
|
||||
@ -1504,13 +1512,6 @@ class PageRev(models.Model):
|
||||
def can_be_edited_by(self, user):
|
||||
return self.page.can_be_edited_by(user)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.revision is None:
|
||||
self.revision = self.page.revisions.all().count() + 1
|
||||
super().save(*args, **kwargs)
|
||||
# Don't forget to unlock, otherwise, people will have to wait for the page's timeout
|
||||
self.page.unset_lock()
|
||||
|
||||
|
||||
class Notification(models.Model):
|
||||
user = models.ForeignKey(
|
||||
@ -1529,15 +1530,6 @@ class Notification(models.Model):
|
||||
return self.get_type_display() % self.param
|
||||
return self.get_type_display()
|
||||
|
||||
def callback(self):
|
||||
# Get the callback defined in settings to update existing
|
||||
# notifications
|
||||
mod_name, func_name = settings.SITH_PERMANENT_NOTIFICATIONS[self.type].rsplit(
|
||||
".", 1
|
||||
)
|
||||
mod = importlib.import_module(mod_name)
|
||||
getattr(mod, func_name)(self)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.id and self.type in settings.SITH_PERMANENT_NOTIFICATIONS:
|
||||
old_notif = self.user.notifications.filter(type=self.type).last()
|
||||
@ -1547,6 +1539,15 @@ class Notification(models.Model):
|
||||
return
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def callback(self):
|
||||
# Get the callback defined in settings to update existing
|
||||
# notifications
|
||||
mod_name, func_name = settings.SITH_PERMANENT_NOTIFICATIONS[self.type].rsplit(
|
||||
".", 1
|
||||
)
|
||||
mod = importlib.import_module(mod_name)
|
||||
getattr(mod, func_name)(self)
|
||||
|
||||
|
||||
class Gift(models.Model):
|
||||
label = models.CharField(_("label"), max_length=255)
|
||||
@ -1585,8 +1586,8 @@ class OperationLog(models.Model):
|
||||
_("operation type"), max_length=40, choices=settings.SITH_LOG_OPERATION_TYPE
|
||||
)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return user.is_root
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s - %s" % (self.operation_type, self.label, self.operator)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return user.is_root
|
||||
|
@ -93,7 +93,7 @@ def search_user(query):
|
||||
return []
|
||||
|
||||
|
||||
def search_club(query,* , as_json=False):
|
||||
def search_club(query, *, as_json=False):
|
||||
clubs = []
|
||||
if query:
|
||||
clubs = Club.objects.filter(name__icontains=query).all()
|
||||
|
@ -18,7 +18,15 @@ from counter.models import (
|
||||
class BillingInfoForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = BillingInfo
|
||||
exclude = ["customer"]
|
||||
fields = [
|
||||
"first_name",
|
||||
"last_name",
|
||||
"address_1",
|
||||
"address_2",
|
||||
"zip_code",
|
||||
"city",
|
||||
"country",
|
||||
]
|
||||
|
||||
|
||||
class StudentCardForm(forms.ModelForm):
|
||||
|
@ -62,6 +62,19 @@ class Customer(models.Model):
|
||||
def __str__(self):
|
||||
return "%s - %s" % (self.user.username, self.account_id)
|
||||
|
||||
def save(self, *args, allow_negative=False, is_selling=False, **kwargs):
|
||||
"""
|
||||
is_selling : tell if the current action is a selling
|
||||
allow_negative : ignored if not a selling. Allow a selling to put the account in negative
|
||||
Those two parameters avoid blocking the save method of a customer if his account is negative
|
||||
"""
|
||||
if self.amount < 0 and (is_selling and not allow_negative):
|
||||
raise ValidationError(_("Not enough money"))
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("core:user_account", kwargs={"user_id": self.user.pk})
|
||||
|
||||
@property
|
||||
def can_record(self):
|
||||
return self.recorded_products > -settings.SITH_ECOCUP_LIMIT
|
||||
@ -128,16 +141,6 @@ class Customer(models.Model):
|
||||
account = cls.objects.create(user=user, account_id=account_id)
|
||||
return account, True
|
||||
|
||||
def save(self, *args, allow_negative=False, is_selling=False, **kwargs):
|
||||
"""
|
||||
is_selling : tell if the current action is a selling
|
||||
allow_negative : ignored if not a selling. Allow a selling to put the account in negative
|
||||
Those two parameters avoid blocking the save method of a customer if his account is negative
|
||||
"""
|
||||
if self.amount < 0 and (is_selling and not allow_negative):
|
||||
raise ValidationError(_("Not enough money"))
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def recompute_amount(self):
|
||||
refillings = self.refillings.aggregate(sum=Sum(F("amount")))["sum"]
|
||||
self.amount = refillings if refillings is not None else 0
|
||||
@ -150,9 +153,6 @@ class Customer(models.Model):
|
||||
self.amount -= purchases
|
||||
self.save()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("core:user_account", kwargs={"user_id": self.user.pk})
|
||||
|
||||
def get_full_url(self):
|
||||
return "".join(["https://", settings.SITH_URL, self.get_absolute_url()])
|
||||
|
||||
@ -178,6 +178,9 @@ class BillingInfo(models.Model):
|
||||
city = models.CharField(_("City"), max_length=50)
|
||||
country = CountryField(blank_label=_("Country"))
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
def to_3dsv2_xml(self) -> str:
|
||||
"""
|
||||
Convert the data from this model into a xml usable
|
||||
@ -199,9 +202,6 @@ class BillingInfo(models.Model):
|
||||
xml = dict2xml(data, wrap="Billing", newlines=False)
|
||||
return '<?xml version="1.0" encoding="UTF-8" ?>' + xml
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
|
||||
class ProductType(models.Model):
|
||||
"""
|
||||
@ -222,6 +222,12 @@ class ProductType(models.Model):
|
||||
verbose_name = _("product type")
|
||||
ordering = ["-priority", "name"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:producttype_list")
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -232,12 +238,6 @@ class ProductType(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:producttype_list")
|
||||
|
||||
|
||||
class Product(models.Model):
|
||||
"""
|
||||
@ -282,6 +282,12 @@ class Product(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("product")
|
||||
|
||||
def __str__(self):
|
||||
return "%s (%s)" % (self.name, self.code)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:product_list")
|
||||
|
||||
@property
|
||||
def is_record_product(self):
|
||||
return settings.SITH_ECOCUP_CONS == self.id
|
||||
@ -302,9 +308,6 @@ class Product(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:product_list")
|
||||
|
||||
def can_be_sold_to(self, user: User) -> bool:
|
||||
"""
|
||||
Check if whether the user given in parameter has the right to buy
|
||||
@ -329,9 +332,6 @@ class Product(models.Model):
|
||||
def profit(self):
|
||||
return self.selling_price - self.purchase_price
|
||||
|
||||
def __str__(self):
|
||||
return "%s (%s)" % (self.name, self.code)
|
||||
|
||||
|
||||
class CounterQuerySet(models.QuerySet):
|
||||
def annotate_has_barman(self, user: User) -> CounterQuerySet:
|
||||
@ -388,13 +388,6 @@ class Counter(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("counter")
|
||||
|
||||
def __getattribute__(self, name):
|
||||
if name == "edit_groups":
|
||||
return Group.objects.filter(
|
||||
name=self.club.unix_name + settings.SITH_BOARD_SUFFIX
|
||||
).all()
|
||||
return object.__getattribute__(self, name)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@ -403,6 +396,13 @@ class Counter(models.Model):
|
||||
return reverse("eboutic:main")
|
||||
return reverse("counter:details", kwargs={"counter_id": self.id})
|
||||
|
||||
def __getattribute__(self, name):
|
||||
if name == "edit_groups":
|
||||
return Group.objects.filter(
|
||||
name=self.club.unix_name + settings.SITH_BOARD_SUFFIX
|
||||
).all()
|
||||
return object.__getattribute__(self, name)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
@ -629,16 +629,6 @@ class Refilling(models.Model):
|
||||
self.customer.user.get_display_name(),
|
||||
)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_owner(self.counter) and self.payment_method != "CARD"
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.customer.amount -= self.amount
|
||||
self.customer.save()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.date:
|
||||
self.date = timezone.now()
|
||||
@ -663,6 +653,16 @@ class Refilling(models.Model):
|
||||
).save()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_owner(self.counter) and self.payment_method != "CARD"
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.customer.amount -= self.amount
|
||||
self.customer.save()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class Selling(models.Model):
|
||||
"""
|
||||
@ -723,59 +723,6 @@ class Selling(models.Model):
|
||||
self.customer.user.get_display_name(),
|
||||
)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_owner(self.counter) and self.payment_method != "CARD"
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
if (
|
||||
not hasattr(self, "customer") or self.customer is None
|
||||
): # Customer can be set to Null
|
||||
return False
|
||||
return user == self.customer.user
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
if self.payment_method == "SITH_ACCOUNT":
|
||||
self.customer.amount += self.quantity * self.unit_price
|
||||
self.customer.save()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
def send_mail_customer(self):
|
||||
event = self.product.eticket.event_title or _("Unknown event")
|
||||
subject = _("Eticket bought for the event %(event)s") % {"event": event}
|
||||
message_html = _(
|
||||
"You bought an eticket for the event %(event)s.\nYou can download it directly from this link %(eticket)s.\nYou can also retrieve all your e-tickets on your account page %(url)s."
|
||||
) % {
|
||||
"event": event,
|
||||
"url": "".join(
|
||||
(
|
||||
'<a href="',
|
||||
self.customer.get_full_url(),
|
||||
'">',
|
||||
self.customer.get_full_url(),
|
||||
"</a>",
|
||||
)
|
||||
),
|
||||
"eticket": "".join(
|
||||
(
|
||||
'<a href="',
|
||||
self.get_eticket_full_url(),
|
||||
'">',
|
||||
self.get_eticket_full_url(),
|
||||
"</a>",
|
||||
)
|
||||
),
|
||||
}
|
||||
message_txt = _(
|
||||
"You bought an eticket for the event %(event)s.\nYou can download it directly from this link %(eticket)s.\nYou can also retrieve all your e-tickets on your account page %(url)s."
|
||||
) % {
|
||||
"event": event,
|
||||
"url": self.customer.get_full_url(),
|
||||
"eticket": self.get_eticket_full_url(),
|
||||
}
|
||||
self.customer.user.email_user(subject, message_txt, html_message=message_html)
|
||||
|
||||
def save(self, *args, allow_negative=False, **kwargs):
|
||||
"""
|
||||
allow_negative : Allow this selling to use more money than available for this user
|
||||
@ -858,6 +805,59 @@ class Selling(models.Model):
|
||||
except:
|
||||
pass
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_owner(self.counter) and self.payment_method != "CARD"
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
if (
|
||||
not hasattr(self, "customer") or self.customer is None
|
||||
): # Customer can be set to Null
|
||||
return False
|
||||
return user == self.customer.user
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
if self.payment_method == "SITH_ACCOUNT":
|
||||
self.customer.amount += self.quantity * self.unit_price
|
||||
self.customer.save()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
def send_mail_customer(self):
|
||||
event = self.product.eticket.event_title or _("Unknown event")
|
||||
subject = _("Eticket bought for the event %(event)s") % {"event": event}
|
||||
message_html = _(
|
||||
"You bought an eticket for the event %(event)s.\nYou can download it directly from this link %(eticket)s.\nYou can also retrieve all your e-tickets on your account page %(url)s."
|
||||
) % {
|
||||
"event": event,
|
||||
"url": "".join(
|
||||
(
|
||||
'<a href="',
|
||||
self.customer.get_full_url(),
|
||||
'">',
|
||||
self.customer.get_full_url(),
|
||||
"</a>",
|
||||
)
|
||||
),
|
||||
"eticket": "".join(
|
||||
(
|
||||
'<a href="',
|
||||
self.get_eticket_full_url(),
|
||||
'">',
|
||||
self.get_eticket_full_url(),
|
||||
"</a>",
|
||||
)
|
||||
),
|
||||
}
|
||||
message_txt = _(
|
||||
"You bought an eticket for the event %(event)s.\nYou can download it directly from this link %(eticket)s.\nYou can also retrieve all your e-tickets on your account page %(url)s."
|
||||
) % {
|
||||
"event": event,
|
||||
"url": self.customer.get_full_url(),
|
||||
"eticket": self.get_eticket_full_url(),
|
||||
}
|
||||
self.customer.user.email_user(subject, message_txt, html_message=message_html)
|
||||
|
||||
def get_eticket_full_url(self):
|
||||
eticket_url = reverse("counter:eticket_pdf", kwargs={"selling_id": self.id})
|
||||
return "".join(["https://", settings.SITH_URL, eticket_url])
|
||||
@ -926,6 +926,14 @@ class CashRegisterSummary(models.Model):
|
||||
def __str__(self):
|
||||
return "At %s by %s - Total: %s €" % (self.counter, self.user, self.get_total())
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.id:
|
||||
self.date = timezone.now()
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:cash_summary_list")
|
||||
|
||||
def __getattribute__(self, name):
|
||||
if name[:5] == "check":
|
||||
checks = self.items.filter(check=True).order_by("value").all()
|
||||
@ -978,14 +986,6 @@ class CashRegisterSummary(models.Model):
|
||||
t += it.quantity * it.value
|
||||
return t
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.id:
|
||||
self.date = timezone.now()
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:cash_summary_list")
|
||||
|
||||
|
||||
class CashRegisterSummaryItem(models.Model):
|
||||
cash_summary = models.ForeignKey(
|
||||
@ -1005,6 +1005,9 @@ class CashRegisterSummaryItem(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("cash register summary item")
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
||||
|
||||
class Eticket(models.Model):
|
||||
"""
|
||||
@ -1027,16 +1030,16 @@ class Eticket(models.Model):
|
||||
secret = models.CharField(_("secret"), max_length=64, unique=True)
|
||||
|
||||
def __str__(self):
|
||||
return "%s" % (self.product.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:eticket_list")
|
||||
return self.product.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.id:
|
||||
self.secret = base64.b64encode(os.urandom(32))
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("counter:eticket_list")
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -1064,6 +1067,21 @@ class StudentCard(models.Model):
|
||||
|
||||
UID_SIZE = 14
|
||||
|
||||
uid = models.CharField(
|
||||
_("uid"), max_length=UID_SIZE, unique=True, validators=[MinLengthValidator(4)]
|
||||
)
|
||||
customer = models.ForeignKey(
|
||||
Customer,
|
||||
related_name="student_cards",
|
||||
verbose_name=_("student cards"),
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.uid
|
||||
|
||||
@staticmethod
|
||||
def is_valid(uid):
|
||||
return (
|
||||
@ -1080,15 +1098,3 @@ class StudentCard(models.Model):
|
||||
if isinstance(obj, User):
|
||||
return StudentCard.can_create(self.customer, obj)
|
||||
return False
|
||||
|
||||
uid = models.CharField(
|
||||
_("uid"), max_length=14, unique=True, validators=[MinLengthValidator(4)]
|
||||
)
|
||||
customer = models.ForeignKey(
|
||||
Customer,
|
||||
related_name="student_cards",
|
||||
verbose_name=_("student cards"),
|
||||
null=False,
|
||||
blank=False,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
@ -56,6 +56,9 @@ class Basket(models.Model):
|
||||
)
|
||||
date = models.DateTimeField(_("date"), auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user}'s basket ({self.items.all().count()} items)"
|
||||
|
||||
def add_product(self, p: Product, q: int = 1):
|
||||
"""
|
||||
Given p an object of the Product model and q an integer,
|
||||
@ -207,9 +210,6 @@ class Basket(models.Model):
|
||||
data.append(("PBX_HMAC", pbx_hmac.hexdigest().upper()))
|
||||
return data
|
||||
|
||||
def __str__(self):
|
||||
return "%s's basket (%d items)" % (self.user, self.items.all().count())
|
||||
|
||||
|
||||
class Invoice(models.Model):
|
||||
"""
|
||||
@ -226,6 +226,9 @@ class Invoice(models.Model):
|
||||
date = models.DateTimeField(_("date"), auto_now=True)
|
||||
validated = models.BooleanField(_("validated"), default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user} - {self.get_total()} - {self.date}"
|
||||
|
||||
def get_total(self) -> float:
|
||||
total = self.items.aggregate(
|
||||
total=Sum(F("quantity") * F("product_unit_price"))
|
||||
@ -268,9 +271,6 @@ class Invoice(models.Model):
|
||||
self.validated = True
|
||||
self.save()
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s - %s" % (self.user, self.get_total(), self.date)
|
||||
|
||||
|
||||
class AbstractBaseItem(models.Model):
|
||||
product_id = models.IntegerField(_("product id"))
|
||||
|
@ -163,16 +163,16 @@ class ElectionList(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
return user.can_edit(self.election)
|
||||
|
||||
def delete(self):
|
||||
def delete(self, *args, **kwargs):
|
||||
for candidature in self.candidatures.all():
|
||||
candidature.delete()
|
||||
super().delete()
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class Candidature(models.Model):
|
||||
@ -201,6 +201,9 @@ class Candidature(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.role.title} : {self.user.username}"
|
||||
|
||||
def delete(self):
|
||||
for vote in self.votes.all():
|
||||
vote.delete()
|
||||
@ -209,9 +212,6 @@ class Candidature(models.Model):
|
||||
def can_be_edited_by(self, user):
|
||||
return (user == self.user) or user.can_edit(self.role.election)
|
||||
|
||||
def __str__(self):
|
||||
return "%s : %s" % (self.role.title, self.user.username)
|
||||
|
||||
|
||||
class Vote(models.Model):
|
||||
"""
|
||||
|
@ -14,7 +14,7 @@ class Migration(migrations.Migration):
|
||||
name="edit_groups",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
default=forum.models.Forum.get_default_edit_group,
|
||||
default=forum.models.get_default_edit_group,
|
||||
related_name="editable_forums",
|
||||
to="core.Group",
|
||||
),
|
||||
@ -24,7 +24,7 @@ class Migration(migrations.Migration):
|
||||
name="view_groups",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
default=forum.models.Forum.get_default_view_group,
|
||||
default=forum.models.get_default_view_group,
|
||||
related_name="viewable_forums",
|
||||
to="core.Group",
|
||||
),
|
||||
|
@ -20,6 +20,7 @@
|
||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
#
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from itertools import chain
|
||||
@ -37,6 +38,15 @@ from club.models import Club
|
||||
from core.models import Group, User
|
||||
|
||||
|
||||
# Those functions prevent generating migration upon settings changes
|
||||
def get_default_edit_group():
|
||||
return [settings.SITH_GROUP_OLD_SUBSCRIBERS_ID]
|
||||
|
||||
|
||||
def get_default_view_group():
|
||||
return [settings.SITH_GROUP_PUBLIC_ID]
|
||||
|
||||
|
||||
class Forum(models.Model):
|
||||
"""
|
||||
The Forum class, made as a tree to allow nice tidy organization
|
||||
@ -46,13 +56,6 @@ class Forum(models.Model):
|
||||
view_groups allows some groups to view a forum
|
||||
"""
|
||||
|
||||
# Those functions prevent generating migration upon settings changes
|
||||
def get_default_edit_group():
|
||||
return [settings.SITH_GROUP_OLD_SUBSCRIBERS_ID]
|
||||
|
||||
def get_default_view_group():
|
||||
return [settings.SITH_GROUP_PUBLIC_ID]
|
||||
|
||||
id = models.AutoField(primary_key=True, db_index=True)
|
||||
name = models.CharField(_("name"), max_length=64)
|
||||
description = models.CharField(_("description"), max_length=512, default="")
|
||||
@ -98,8 +101,8 @@ class Forum(models.Model):
|
||||
class Meta:
|
||||
ordering = ["number"]
|
||||
|
||||
def clean(self):
|
||||
self.check_loop()
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
copy_rights = False
|
||||
@ -109,6 +112,12 @@ class Forum(models.Model):
|
||||
if copy_rights:
|
||||
self.copy_rights()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("forum:view_forum", kwargs={"forum_id": self.id})
|
||||
|
||||
def clean(self):
|
||||
self.check_loop()
|
||||
|
||||
def set_topic_number(self):
|
||||
self._topic_number = self.get_topic_number()
|
||||
self.save()
|
||||
@ -166,11 +175,11 @@ class Forum(models.Model):
|
||||
return True
|
||||
try:
|
||||
m = Forum._club_memberships[self.id][user.id]
|
||||
except:
|
||||
except KeyError:
|
||||
m = self.owner_club.get_membership_for(user)
|
||||
try:
|
||||
Forum._club_memberships[self.id][user.id] = m
|
||||
except:
|
||||
except KeyError:
|
||||
Forum._club_memberships[self.id] = {}
|
||||
Forum._club_memberships[self.id][user.id] = m
|
||||
if m:
|
||||
@ -187,9 +196,6 @@ class Forum(models.Model):
|
||||
objs.append(cur)
|
||||
cur = cur.parent
|
||||
|
||||
def __str__(self):
|
||||
return "%s" % (self.name)
|
||||
|
||||
def get_full_name(self):
|
||||
return "/".join(
|
||||
chain.from_iterable(
|
||||
@ -197,9 +203,6 @@ class Forum(models.Model):
|
||||
)
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("forum:view_forum", kwargs={"forum_id": self.id})
|
||||
|
||||
@cached_property
|
||||
def parent_list(self):
|
||||
return self.get_parent_list()
|
||||
@ -256,11 +259,17 @@ class ForumTopic(models.Model):
|
||||
class Meta:
|
||||
ordering = ["-_last_message__date"]
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
self.forum.set_topic_number() # Recompute the cached value
|
||||
self.forum.set_last_message()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("forum:view_topic", kwargs={"topic_id": self.id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return self.forum.is_owned_by(user)
|
||||
|
||||
@ -270,23 +279,15 @@ class ForumTopic(models.Model):
|
||||
def can_be_viewed_by(self, user):
|
||||
return user.can_view(self.forum)
|
||||
|
||||
def __str__(self):
|
||||
return "%s" % (self.title)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("forum:view_topic", kwargs={"topic_id": self.id})
|
||||
|
||||
def get_first_unread_message(self, user):
|
||||
try:
|
||||
msg = (
|
||||
self.messages.exclude(readers=user)
|
||||
.filter(date__gte=user.forum_infos.last_read_date)
|
||||
.order_by("id")
|
||||
.first()
|
||||
)
|
||||
return msg
|
||||
except:
|
||||
def get_first_unread_message(self, user: User) -> ForumMessage | None:
|
||||
if not hasattr(user, "forum_infos"):
|
||||
return None
|
||||
return (
|
||||
self.messages.exclude(readers=user)
|
||||
.filter(date__gte=user.forum_infos.last_read_date)
|
||||
.order_by("id")
|
||||
.first()
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def last_message(self):
|
||||
@ -332,6 +333,9 @@ class ForumMessage(models.Model):
|
||||
self.topic._message_number = self.topic.messages.count()
|
||||
self.topic.save()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("forum:view_message", kwargs={"message_id": self.id})
|
||||
|
||||
def is_first_in_topic(self):
|
||||
return bool(self.id == self.topic.messages.order_by("date").first().id)
|
||||
|
||||
@ -356,9 +360,6 @@ class ForumMessage(models.Model):
|
||||
def can_be_moderated_by(self, user):
|
||||
return self.topic.forum.is_owned_by(user) or user.id == self.author.id
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("forum:view_message", kwargs={"message_id": self.id})
|
||||
|
||||
def get_url(self):
|
||||
return (
|
||||
self.topic.get_absolute_url()
|
||||
@ -378,11 +379,10 @@ class ForumMessage(models.Model):
|
||||
)
|
||||
|
||||
def mark_as_read(self, user):
|
||||
try: # Need the try/except because of AnonymousUser
|
||||
if not self.is_read(user):
|
||||
self.readers.add(user)
|
||||
except:
|
||||
pass
|
||||
if user.is_anonymous:
|
||||
return
|
||||
if not self.is_read(user):
|
||||
self.readers.add(user)
|
||||
|
||||
def is_read(self, user):
|
||||
return (self.date < user.forum_infos.last_read_date) or (
|
||||
@ -413,6 +413,9 @@ class ForumMessageMeta(models.Model):
|
||||
date = models.DateTimeField(_("date"), default=timezone.now)
|
||||
action = models.CharField(_("action"), choices=MESSAGE_META_ACTIONS, max_length=16)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.nick_name} ({self.date})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
self.message._deleted = self.message.is_deleted()
|
||||
|
@ -127,6 +127,9 @@ class GalaxyLane(models.Model):
|
||||
default=0,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.star1} -> {self.star2} ({self.distance})"
|
||||
|
||||
|
||||
class StarDict(TypedDict):
|
||||
id: int
|
||||
|
@ -37,6 +37,12 @@ class Launderette(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("Launderette")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("launderette:launderette_list")
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -63,12 +69,6 @@ class Launderette(models.Model):
|
||||
def can_be_viewed_by(self, user):
|
||||
return user.is_subscribed
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("launderette:launderette_list")
|
||||
|
||||
def get_machine_list(self):
|
||||
return Machine.objects.filter(launderette_id=self.id)
|
||||
|
||||
@ -98,6 +98,15 @@ class Machine(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _("Machine")
|
||||
|
||||
def __str__(self):
|
||||
return "%s %s" % (self._meta.verbose_name, self.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"launderette:launderette_admin",
|
||||
kwargs={"launderette_id": self.launderette.id},
|
||||
)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
@ -112,15 +121,6 @@ class Machine(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return "%s %s" % (self._meta.verbose_name, self.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"launderette:launderette_admin",
|
||||
kwargs={"launderette_id": self.launderette.id},
|
||||
)
|
||||
|
||||
|
||||
class Token(models.Model):
|
||||
name = models.CharField(_("name"), max_length=5)
|
||||
@ -148,6 +148,12 @@ class Token(models.Model):
|
||||
unique_together = ("name", "launderette", "type")
|
||||
ordering = ["type", "name"]
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
f"{self.__class__._meta.verbose_name} {self.get_type_display()} "
|
||||
f"#{self.name} ({self.launderette.name})"
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.name == "":
|
||||
raise DataError(_("Token name can not be blank"))
|
||||
@ -168,18 +174,6 @@ class Token(models.Model):
|
||||
return True
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
self.__class__._meta.verbose_name
|
||||
+ " "
|
||||
+ self.get_type_display()
|
||||
+ " #"
|
||||
+ self.name
|
||||
+ " ("
|
||||
+ self.launderette.name
|
||||
+ ")"
|
||||
)
|
||||
|
||||
def is_avaliable(self):
|
||||
if not self.borrow_date and not self.user:
|
||||
return True
|
||||
@ -214,9 +208,6 @@ class Slot(models.Model):
|
||||
verbose_name = _("Slot")
|
||||
ordering = ["start_date"]
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return user == self.user
|
||||
|
||||
def __str__(self):
|
||||
return "User: %s - Date: %s - Type: %s - Machine: %s - Token: %s" % (
|
||||
self.user,
|
||||
@ -225,3 +216,6 @@ class Slot(models.Model):
|
||||
self.machine.name,
|
||||
self.token,
|
||||
)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return user == self.user
|
||||
|
@ -141,6 +141,12 @@ class UV(models.Model):
|
||||
default=0,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.code
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("pedagogy:uv_detail", kwargs={"uv_id": self.id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Can be created by superuser, root or pedagogy admin user
|
||||
@ -160,9 +166,6 @@ class UV(models.Model):
|
||||
|
||||
return int(sum(comments.values_list(field, flat=True)) / comments.count())
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("pedagogy:uv_detail", kwargs={"uv_id": self.id})
|
||||
|
||||
def has_user_already_commented(self, user):
|
||||
"""
|
||||
Help prevent multiples comments from the same user
|
||||
@ -194,9 +197,6 @@ class UV(models.Model):
|
||||
def grade_work_load_average(self):
|
||||
return self.__grade_average_generic("grade_work_load")
|
||||
|
||||
def __str__(self):
|
||||
return self.code
|
||||
|
||||
|
||||
class UVComment(models.Model):
|
||||
"""
|
||||
@ -252,6 +252,14 @@ class UVComment(models.Model):
|
||||
)
|
||||
publish_date = models.DateTimeField(_("publish date"), blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.uv} - {self.author}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.publish_date is None:
|
||||
self.publish_date = timezone.now()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def is_owned_by(self, user):
|
||||
"""
|
||||
Is owned by a pedagogy admin, a superuser or the author himself
|
||||
@ -265,14 +273,6 @@ class UVComment(models.Model):
|
||||
"""
|
||||
return self.reports.exists()
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s" % (self.uv, self.author)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.publish_date is None:
|
||||
self.publish_date = timezone.now()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class UVResult(models.Model):
|
||||
"""
|
||||
@ -303,6 +303,9 @@ class UVResult(models.Model):
|
||||
validators=[validators.RegexValidator("[AP][0-9]{3}")],
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username} ; {self.uv.code} ; {self.grade}"
|
||||
|
||||
|
||||
class UVCommentReport(models.Model):
|
||||
"""
|
||||
@ -323,6 +326,9 @@ class UVCommentReport(models.Model):
|
||||
)
|
||||
reason = models.TextField(_("reason"))
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.reporter.username} : {self.reason}"
|
||||
|
||||
@cached_property
|
||||
def uv(self):
|
||||
return self.comment.uv
|
||||
|
@ -70,7 +70,19 @@ optional = true
|
||||
version = "1.4.25"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["I", "A", "F401", "UP008", "UP009"]
|
||||
select = [
|
||||
"I", # isort
|
||||
"B",
|
||||
"A", # shadowing of Python builtins
|
||||
"F401", # unused import
|
||||
"DJ", # django-specific rules,
|
||||
"UP008", # Use super() instead of super(__class__, self)
|
||||
"UP009" # utf-8 encoding declaration is unnecessary
|
||||
]
|
||||
|
||||
ignore = [
|
||||
"DJ001", # null=True in CharField/TextField. this one would require a migration
|
||||
]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
DJANGO_SETTINGS_MODULE = "sith.settings"
|
||||
|
@ -149,10 +149,10 @@ class ShoppingListItem(models.Model):
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s" % (self.name, self.shopping_lists.first())
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
return user.is_in_group(pk=settings.SITH_GROUP_COUNTER_ADMIN_ID)
|
||||
return f"{self.name} - {self.shopping_lists.first()}"
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("stock:shoppinglist_list")
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
return user.is_in_group(pk=settings.SITH_GROUP_COUNTER_ADMIN_ID)
|
||||
|
@ -22,6 +22,7 @@ from django.contrib.auth.forms import PasswordResetForm
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from core.models import User
|
||||
@ -65,26 +66,11 @@ class Subscription(models.Model):
|
||||
class Meta:
|
||||
ordering = ["subscription_start"]
|
||||
|
||||
def clean(self):
|
||||
try:
|
||||
for s in (
|
||||
Subscription.objects.filter(member=self.member)
|
||||
.exclude(pk=self.pk)
|
||||
.all()
|
||||
):
|
||||
if (
|
||||
s.is_valid_now()
|
||||
and s.subscription_end
|
||||
- timedelta(weeks=settings.SITH_SUBSCRIPTION_END)
|
||||
> date.today()
|
||||
):
|
||||
raise ValidationError(
|
||||
_("You can not subscribe many time for the same period")
|
||||
)
|
||||
except: # This should not happen, because the form should have handled the data before, but sadly, it still
|
||||
# calls the model validation :'(
|
||||
# TODO see SubscriptionForm's clean method
|
||||
raise ValidationError(_("Subscription error"))
|
||||
def __str__(self):
|
||||
if hasattr(self, "member") and self.member is not None:
|
||||
return f"{self.member.username} - {self.pk}"
|
||||
else:
|
||||
return f"No user - {self.pk}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save()
|
||||
@ -105,11 +91,20 @@ class Subscription(models.Model):
|
||||
def get_absolute_url(self):
|
||||
return reverse("core:user_edit", kwargs={"user_id": self.member.pk})
|
||||
|
||||
def __str__(self):
|
||||
if hasattr(self, "member") and self.member is not None:
|
||||
return self.member.username + " - " + str(self.pk)
|
||||
else:
|
||||
return "No user - " + str(self.pk)
|
||||
def clean(self):
|
||||
today = timezone.now().date()
|
||||
active_subscriptions = Subscription.objects.exclude(pk=self.pk).filter(
|
||||
subscription_start__gte=today, subscription_end__lte=today
|
||||
)
|
||||
for s in active_subscriptions:
|
||||
if (
|
||||
s.is_valid_now()
|
||||
and s.subscription_end - timedelta(weeks=settings.SITH_SUBSCRIPTION_END)
|
||||
> date.today()
|
||||
):
|
||||
raise ValidationError(
|
||||
_("You can not subscribe many time for the same period")
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def compute_start(d: date = None, duration: int = 1, user: User = None) -> date:
|
||||
|
@ -83,6 +83,9 @@ class Trombi(models.Model):
|
||||
def __str__(self):
|
||||
return str(self.club.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("trombi:detail", kwargs={"trombi_id": self.id})
|
||||
|
||||
def clean(self):
|
||||
if self.subscription_deadline > self.comments_deadline:
|
||||
raise ValidationError(
|
||||
@ -92,9 +95,6 @@ class Trombi(models.Model):
|
||||
)
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("trombi:detail", kwargs={"trombi_id": self.id})
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return user.can_edit(self.club)
|
||||
|
||||
@ -192,6 +192,9 @@ class TrombiComment(models.Model):
|
||||
content = models.TextField(_("content"), default="")
|
||||
is_moderated = models.BooleanField(_("is the comment moderated"), default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.author} : {self.content}"
|
||||
|
||||
def can_be_viewed_by(self, user):
|
||||
if user.id == self.target.user.id:
|
||||
return False
|
||||
@ -220,8 +223,8 @@ class TrombiClubMembership(models.Model):
|
||||
def __str__(self):
|
||||
return "%s - %s - %s (%s)" % (self.user, self.club, self.role, self.start)
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
return user.id == self.user.user.id or user.can_edit(self.user.trombi)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("trombi:profile")
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
return user.id == self.user.user.id or user.can_edit(self.user.trombi)
|
||||
|
Loading…
Reference in New Issue
Block a user