1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-21 09:58:23 +02:00

Merge branch 'master' into import_nk15

This commit is contained in:
Pierre-antoine Comby
2020-02-22 16:34:17 +01:00
68 changed files with 2147 additions and 830 deletions

View File

@ -1,14 +1,13 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .notes import Alias, Note, NoteClub, NoteSpecial, NoteUser
from .transactions import MembershipTransaction, Transaction, \
TransactionTemplate
TransactionCategory, TransactionTemplate
__all__ = [
# Notes
'Alias', 'Note', 'NoteClub', 'NoteSpecial', 'NoteUser',
# Transactions
'MembershipTransaction', 'Transaction', 'TransactionTemplate',
'MembershipTransaction', 'Transaction', 'TransactionCategory', 'TransactionTemplate',
]

View File

@ -1,5 +1,4 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import unicodedata
@ -10,7 +9,6 @@ from django.core.validators import RegexValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
from polymorphic.models import PolymorphicModel
"""
Defines each note types
"""
@ -34,8 +32,7 @@ class Note(PolymorphicModel):
default=True,
help_text=_(
'Designates whether this note should be treated as active. '
'Unselect this instead of deleting notes.'
),
'Unselect this instead of deleting notes.'),
)
display_image = models.ImageField(
verbose_name=_('display image'),
@ -85,7 +82,8 @@ class Note(PolymorphicModel):
"""
Verify alias (simulate save)
"""
aliases = Alias.objects.filter(name=str(self))
aliases = Alias.objects.filter(
normalized_name=Alias.normalize(str(self)))
if aliases.exists():
# Alias exists, so check if it is linked to this note
if aliases.first().note != self:
@ -181,15 +179,15 @@ class Alias(models.Model):
validators=[
RegexValidator(
regex=settings.ALIAS_VALIDATOR_REGEX,
message=_('Invalid alias')
message=_('Invalid alias'),
)
] if settings.ALIAS_VALIDATOR_REGEX else []
] if settings.ALIAS_VALIDATOR_REGEX else [],
)
normalized_name = models.CharField(
max_length=255,
unique=True,
default='',
editable=False
editable=False,
)
note = models.ForeignKey(
Note,
@ -209,11 +207,9 @@ class Alias(models.Model):
Normalizes a string: removes most diacritics and does casefolding
"""
return ''.join(
char
for char in unicodedata.normalize('NFKD', string.casefold())
char for char in unicodedata.normalize('NFKD', string.casefold())
if all(not unicodedata.category(char).startswith(cat)
for cat in {'M', 'P', 'Z', 'C'})
).casefold()
for cat in {'M', 'P', 'Z', 'C'})).casefold()
def save(self, *args, **kwargs):
"""
@ -229,7 +225,13 @@ class Alias(models.Model):
raise ValidationError(_('Alias too long.'))
try:
if self != Alias.objects.get(normalized_name=normalized_name):
raise ValidationError(_('An alias with a similar name '
'already exists.'))
raise ValidationError(
_('An alias with a similar name '
'already exists.'))
except Alias.DoesNotExist:
pass
def delete(self, using=None, keep_parents=False):
if self.name == str(self.note):
raise ValidationError(_("You can't delete your main alias."))
return super().delete(using, keep_parents)

View File

@ -1,5 +1,4 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.db import models
@ -7,16 +6,36 @@ from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from .notes import Note,NoteClub
from .notes import Note, NoteClub
"""
Defines transactions
"""
class TransactionCategory(models.Model):
"""
Defined a recurrent transaction category
Example: food, softs, ...
"""
name = models.CharField(
verbose_name=_("name"),
max_length=31,
unique=True,
)
class Meta:
verbose_name = _("transaction category")
verbose_name_plural = _("transaction categories")
def __str__(self):
return str(self.name)
class TransactionTemplate(models.Model):
"""
Defined a reccurent transaction
Defined a recurrent transaction
associated to selling something (a burger, a beer, ...)
"""
@ -35,9 +54,11 @@ class TransactionTemplate(models.Model):
verbose_name=_('amount'),
help_text=_('in centimes'),
)
template_type = models.CharField(
template_type = models.ForeignKey(
TransactionCategory,
on_delete=models.PROTECT,
verbose_name=_('type'),
max_length=31
max_length=31,
)
description = models.CharField(
@ -50,7 +71,7 @@ class TransactionTemplate(models.Model):
verbose_name_plural = _("transaction templates")
def get_absolute_url(self):
return reverse('note:template_update',args=(self.pk,))
return reverse('note:template_update', args=(self.pk, ))
class Transaction(models.Model):
@ -83,9 +104,7 @@ class Transaction(models.Model):
verbose_name=_('quantity'),
default=1,
)
amount = models.PositiveIntegerField(
verbose_name=_('amount'),
)
amount = models.PositiveIntegerField(verbose_name=_('amount'), )
transaction_type = models.CharField(
verbose_name=_('type'),
max_length=31,
@ -127,7 +146,7 @@ class Transaction(models.Model):
@property
def total(self):
return self.amount*self.quantity
return self.amount * self.quantity
class MembershipTransaction(Transaction):