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

Format code

This commit is contained in:
Alexandre Iooss
2020-02-18 12:31:15 +01:00
parent 0d7db68372
commit f89d91e524
19 changed files with 262 additions and 167 deletions

View File

@ -25,7 +25,10 @@ class NoteAdmin(PolymorphicParentModelAdmin):
Parent regrouping all note types as children
"""
child_models = (NoteClub, NoteSpecial, NoteUser)
list_filter = (PolymorphicChildModelFilter, 'is_active',)
list_filter = (
PolymorphicChildModelFilter,
'is_active',
)
# Use a polymorphic list
list_display = ('pretty', 'balance', 'is_active')
@ -44,11 +47,12 @@ class NoteClubAdmin(PolymorphicChildModelAdmin):
"""
Child for a club note, see NoteAdmin
"""
inlines = (AliasInlines,)
inlines = (AliasInlines, )
# We can't change club after creation or the balance
readonly_fields = ('club', 'balance')
search_fields = ('club',)
search_fields = ('club', )
def has_add_permission(self, request):
"""
A club note should not be manually added
@ -67,7 +71,7 @@ class NoteSpecialAdmin(PolymorphicChildModelAdmin):
"""
Child for a special note, see NoteAdmin
"""
readonly_fields = ('balance',)
readonly_fields = ('balance', )
@admin.register(NoteUser)
@ -75,7 +79,7 @@ class NoteUserAdmin(PolymorphicChildModelAdmin):
"""
Child for an user note, see NoteAdmin
"""
inlines = (AliasInlines,)
inlines = (AliasInlines, )
# We can't change user after creation or the balance
readonly_fields = ('user', 'balance')
@ -101,7 +105,10 @@ class TransactionAdmin(admin.ModelAdmin):
list_display = ('created_at', 'poly_source', 'poly_destination',
'quantity', 'amount', 'transaction_type', 'valid')
list_filter = ('transaction_type', 'valid')
autocomplete_fields = ('source', 'destination',)
autocomplete_fields = (
'source',
'destination',
)
def poly_source(self, obj):
"""
@ -136,8 +143,8 @@ class TransactionTemplateAdmin(admin.ModelAdmin):
Admin customisation for TransactionTemplate
"""
list_display = ('name', 'poly_destination', 'amount', 'template_type')
list_filter = ('template_type',)
autocomplete_fields = ('destination',)
list_filter = ('template_type', )
autocomplete_fields = ('destination', )
def poly_destination(self, obj):
"""
@ -153,5 +160,5 @@ class TransactionCategoryAdmin(admin.ModelAdmin):
"""
Admin customisation for TransactionTemplate
"""
list_display = ('name',)
list_filter = ('name',)
list_display = ('name', )
list_filter = ('name', )

View File

@ -17,7 +17,10 @@ class NoteSerializer(serializers.ModelSerializer):
model = Note
fields = '__all__'
extra_kwargs = {
'url': {'view_name': 'project-detail', 'lookup_field': 'pk'},
'url': {
'view_name': 'project-detail',
'lookup_field': 'pk'
},
}
@ -69,6 +72,7 @@ class NotePolymorphicSerializer(PolymorphicSerializer):
NoteSpecial: NoteSpecialSerializer
}
class TransactionTemplateSerializer(serializers.ModelSerializer):
"""
REST API Serializer for Transaction templates.

View File

@ -69,7 +69,9 @@ class NotePolymorphicViewSet(viewsets.ModelViewSet):
queryset = Note.objects.all()
alias = self.request.query_params.get("alias", ".*")
queryset = queryset.filter(Q(alias__name__regex=alias) | Q(alias__normalized_name__regex=alias.lower()))
queryset = queryset.filter(
Q(alias__name__regex=alias)
| Q(alias__normalized_name__regex=alias.lower()))
note_type = self.request.query_params.get("type", None)
if note_type:
@ -79,7 +81,8 @@ class NotePolymorphicViewSet(viewsets.ModelViewSet):
elif "club" in l:
queryset = queryset.filter(polymorphic_ctype__model="noteclub")
elif "special" in l:
queryset = queryset.filter(polymorphic_ctype__model="notespecial")
queryset = queryset.filter(
polymorphic_ctype__model="notespecial")
else:
queryset = queryset.none()
@ -104,7 +107,8 @@ class AliasViewSet(viewsets.ModelViewSet):
queryset = Alias.objects.all()
alias = self.request.query_params.get("alias", ".*")
queryset = queryset.filter(Q(name__regex=alias) | Q(normalized_name__regex=alias.lower()))
queryset = queryset.filter(
Q(name__regex=alias) | Q(normalized_name__regex=alias.lower()))
note_id = self.request.query_params.get("note", None)
if note_id:
@ -114,11 +118,14 @@ class AliasViewSet(viewsets.ModelViewSet):
if note_type:
l = str(note_type).lower()
if "user" in l:
queryset = queryset.filter(note__polymorphic_ctype__model="noteuser")
queryset = queryset.filter(
note__polymorphic_ctype__model="noteuser")
elif "club" in l:
queryset = queryset.filter(note__polymorphic_ctype__model="noteclub")
queryset = queryset.filter(
note__polymorphic_ctype__model="noteclub")
elif "special" in l:
queryset = queryset.filter(note__polymorphic_ctype__model="notespecial")
queryset = queryset.filter(
note__polymorphic_ctype__model="notespecial")
else:
queryset = queryset.none()

View File

@ -20,9 +20,9 @@ class NoteConfig(AppConfig):
"""
post_save.connect(
signals.save_user_note,
sender=settings.AUTH_USER_MODEL
sender=settings.AUTH_USER_MODEL,
)
post_save.connect(
signals.save_club_note,
sender='member.Club'
sender='member.Club',
)

View File

@ -4,10 +4,11 @@ from dal import autocomplete, forward
from django import forms
from .models import Transaction, TransactionTemplate
class TransactionTemplateForm(forms.ModelForm):
class Meta:
model = TransactionTemplate
fields ='__all__'
fields = '__all__'
# Le champ de destination est remplacé par un champ d'auto-complétion.
# Quand des lettres sont tapées, une requête est envoyée sur l'API d'auto-complétion
@ -15,11 +16,14 @@ class TransactionTemplateForm(forms.ModelForm):
# Pour force le type d'une note, il faut rajouter le paramètre :
# forward=(forward.Const('TYPE', 'note_type') où TYPE est dans {user, club, special}
widgets = {
'destination': autocomplete.ModelSelect2(url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
}),
'destination':
autocomplete.ModelSelect2(
url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
},
),
}
@ -31,26 +35,38 @@ class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ('source', 'destination', 'reason', 'amount',)
fields = (
'source',
'destination',
'reason',
'amount',
)
# Voir ci-dessus
widgets = {
'source': autocomplete.ModelSelect2(url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
},),
'destination': autocomplete.ModelSelect2(url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
},),
'source':
autocomplete.ModelSelect2(
url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
},
),
'destination':
autocomplete.ModelSelect2(
url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
},
),
}
class ConsoForm(forms.ModelForm):
class ConsoForm(forms.ModelForm):
def save(self, commit=True):
button: TransactionTemplate = TransactionTemplate.objects.filter(name=self.data['button']).get()
button: TransactionTemplate = TransactionTemplate.objects.filter(
name=self.data['button']).get()
self.instance.destination = button.destination
self.instance.amount = button.amount
self.instance.transaction_type = 'bouton'
@ -59,15 +75,18 @@ class ConsoForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ('source',)
fields = ('source', )
# Le champ d'utilisateur est remplacé par un champ d'auto-complétion.
# Quand des lettres sont tapées, une requête est envoyée sur l'API d'auto-complétion
# et récupère les aliases de note valides
widgets = {
'source': autocomplete.ModelSelect2(url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
}),
'source':
autocomplete.ModelSelect2(
url='note:note_autocomplete',
attrs={
'data-placeholder': 'Note ...',
'data-minimum-input-length': 1,
},
),
}

View File

@ -10,7 +10,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 +33,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 +83,8 @@ class Note(PolymorphicModel):
"""
Verify alias (simulate save)
"""
aliases = Alias.objects.filter(normalized_name=Alias.normalize(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 +180,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 +208,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,8 +226,9 @@ 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

View File

@ -7,16 +7,19 @@ from .models.transactions import Transaction
class HistoryTable(tables.Table):
class Meta:
attrs = {'class':'table table-bordered table-condensed table-striped table-hover'}
attrs = {
'class':
'table table-bordered table-condensed table-striped table-hover'
}
model = Transaction
template_name = 'django_tables2/bootstrap.html'
sequence = ('...','total','valid')
sequence = ('...', 'total', 'valid')
total = tables.Column() #will use Transaction.total() !!
total = tables.Column() #will use Transaction.total() !!
def order_total(self, QuerySet, is_descending):
# needed for rendering
QuerySet = QuerySet.annotate(
total=F('amount') * F('quantity')
).order_by(('-' if is_descending else '') + 'total')
total=F('amount') *
F('quantity')).order_by(('-' if is_descending else '') + 'total')
return (QuerySet, True)

View File

@ -2,10 +2,17 @@ from django import template
def pretty_money(value):
if value%100 == 0:
return "{:s}{:d}".format("- " if value < 0 else "", abs(value) // 100)
if value % 100 == 0:
return "{:s}{:d}".format(
"- " if value < 0 else "",
abs(value) // 100,
)
else:
return "{:s}{:d}{:02d}".format("- " if value < 0 else "", abs(value) // 100, abs(value) % 100)
return "{:s}{:d}{:02d}".format(
"- " if value < 0 else "",
abs(value) // 100,
abs(value) % 100,
)
register = template.Library()

View File

@ -12,6 +12,7 @@ from django.views.generic import CreateView, ListView, DetailView, UpdateView
from .models import Note, Transaction, TransactionCategory, TransactionTemplate, Alias
from .forms import TransactionForm, TransactionTemplateForm, ConsoForm
class TransactionCreate(LoginRequiredMixin, CreateView):
"""
Show transfer page
@ -30,14 +31,13 @@ class TransactionCreate(LoginRequiredMixin, CreateView):
'to one or others')
return context
def get_form(self, form_class=None):
"""
If the user has no right to transfer funds, then it won't have the choice of the source of the transfer.
"""
form = super().get_form(form_class)
if False: # TODO: fix it with "if %user has no right to transfer funds"
if False: # TODO: fix it with "if %user has no right to transfer funds"
del form.fields['source']
return form
@ -46,7 +46,7 @@ class TransactionCreate(LoginRequiredMixin, CreateView):
"""
If the user has no right to transfer funds, then it will be the source of the transfer by default.
"""
if False: # TODO: fix it with "if %user has no right to transfer funds"
if False: # TODO: fix it with "if %user has no right to transfer funds"
form.instance.source = self.request.user.note
return super().form_valid(form)
@ -56,7 +56,6 @@ class NoteAutocomplete(autocomplete.Select2QuerySetView):
"""
Auto complete note by aliases
"""
def get_queryset(self):
"""
Quand une personne cherche un alias, une requête est envoyée sur l'API dédiée à l'auto-complétion.
@ -101,27 +100,30 @@ class NoteAutocomplete(autocomplete.Select2QuerySetView):
return str(result.note.pk)
class TransactionTemplateCreateView(LoginRequiredMixin,CreateView):
class TransactionTemplateCreateView(LoginRequiredMixin, CreateView):
"""
Create TransactionTemplate
"""
model = TransactionTemplate
form_class = TransactionTemplateForm
class TransactionTemplateListView(LoginRequiredMixin,ListView):
class TransactionTemplateListView(LoginRequiredMixin, ListView):
"""
List TransactionsTemplates
"""
model = TransactionTemplate
form_class = TransactionTemplateForm
class TransactionTemplateUpdateView(LoginRequiredMixin,UpdateView):
class TransactionTemplateUpdateView(LoginRequiredMixin, UpdateView):
"""
"""
model = TransactionTemplate
form_class = TransactionTemplateForm
class ConsoView(LoginRequiredMixin,CreateView):
class ConsoView(LoginRequiredMixin, CreateView):
"""
Consume
"""
@ -139,11 +141,14 @@ class ConsoView(LoginRequiredMixin,CreateView):
if 'template_type' not in self.kwargs.keys():
return context
template_type = TransactionCategory.objects.filter(name=self.kwargs.get('template_type')).get()
context['buttons'] = TransactionTemplate.objects.filter(template_type=template_type)
template_type = TransactionCategory.objects.filter(
name=self.kwargs.get('template_type')).get()
context['buttons'] = TransactionTemplate.objects.filter(
template_type=template_type)
context['title'] = template_type
return context
def get_success_url(self):
return reverse('note:consos',args=(self.kwargs.get('template_type'),))
return reverse('note:consos',
args=(self.kwargs.get('template_type'), ))