Use django-djconfig for kfet app.

Old configuration(/settings), based on Settings model, system is
deleted: SettingsForm, Settings.
New system use `django-djconfig` module.

- `kfet.config` module provides `kfet_config` to access configuration concerning
kfet app.
- Views, forms, models, etc now use this object to retrieve conf values.
- Views no longer add config values to context, instead templates use
  `kfet_config` provided by a new context_processor.
- Enhance list and update views of settings.
- Fix: settings can directly be used without having to visit a specific
  page...

Misc
- Delete some py2/3 imports
- Delete unused imports in kfet.models and kfet.views
- Some PEP8 compliance
This commit is contained in:
Aurélien Delobelle 2017-04-03 20:32:16 +02:00
parent a4a854bc50
commit 85caa6b058
16 changed files with 247 additions and 227 deletions

View file

@ -47,6 +47,7 @@ INSTALLED_APPS = (
'channels',
'widget_tweaks',
'custommail',
'djconfig',
)
MIDDLEWARE_CLASSES = (
@ -60,6 +61,7 @@ MIDDLEWARE_CLASSES = (
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'djconfig.middleware.DjConfigMiddleware',
)
ROOT_URLCONF = 'cof.urls'
@ -78,8 +80,10 @@ TEMPLATES = [
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'djconfig.context_processors.config',
'gestioncof.shared.context_processor',
'kfet.context_processors.auth',
'kfet.context_processors.config',
],
},
},

View file

@ -12,3 +12,9 @@ class KFetConfig(AppConfig):
def ready(self):
import kfet.signals
self.register_config()
def register_config(self):
import djconfig
from kfet.forms import KFetConfigForm
djconfig.register(KFetConfigForm)

25
kfet/config.py Normal file
View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from djconfig import config
class KFetConfig(object):
"""kfet app configuration.
Enhance dependency with backend used to store config.
Usable after DjConfig middleware was called.
"""
prefix = 'kfet_'
def __getattr__(self, key):
dj_key = '{}{}'.format(self.prefix, key)
return getattr(config, dj_key)
def list(self):
from kfet.forms import KFetConfigForm
return [(field.label, getattr(config, name), )
for name, field in KFetConfigForm.base_fields.items()]
kfet_config = KFetConfig()

View file

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import *
from django.contrib.auth.context_processors import PermWrapper
from kfet.config import kfet_config
def auth(request):
if hasattr(request, 'real_user'):
return {
@ -13,3 +12,7 @@ def auth(request):
'perms': PermWrapper(request.real_user),
}
return {}
def config(request):
return {'kfet_config': kfet_config}

View file

@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
from decimal import Decimal
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import MinLengthValidator
@ -8,12 +10,16 @@ from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.forms import modelformset_factory
from django.utils import timezone
from djconfig.forms import ConfigForm
from kfet.models import (
Account, Checkout, Article, OperationGroup, Operation,
CheckoutStatement, ArticleCategory, Settings, AccountNegative, Transfer,
CheckoutStatement, ArticleCategory, AccountNegative, Transfer,
TransferGroup, Supplier)
from gestioncof.models import CofProfile
# -----
# Widgets
# -----
@ -379,40 +385,42 @@ class AddcostForm(forms.Form):
self.cleaned_data['amount'] = 0
super(AddcostForm, self).clean()
# -----
# Settings forms
# -----
class SettingsForm(forms.ModelForm):
class Meta:
model = Settings
fields = ['value_decimal', 'value_account', 'value_duration']
def clean(self):
name = self.instance.name
value_decimal = self.cleaned_data.get('value_decimal')
value_account = self.cleaned_data.get('value_account')
value_duration = self.cleaned_data.get('value_duration')
class KFetConfigForm(ConfigForm):
type_decimal = ['SUBVENTION_COF', 'ADDCOST_AMOUNT', 'OVERDRAFT_AMOUNT']
type_account = ['ADDCOST_FOR']
type_duration = ['OVERDRAFT_DURATION', 'CANCEL_DURATION']
kfet_subvention_cof = forms.DecimalField(
label='Subvention COF', initial=Decimal('25'),
max_digits=6, decimal_places=2,
)
kfet_addcost_amount = forms.DecimalField(
label='Montant de la majoration', initial=Decimal('0'), required=False,
max_digits=6, decimal_places=2,
)
kfet_addcost_for = forms.ModelChoiceField(
label='Destinataire de la majoration', initial=None, required=False,
help_text='Laissez vide pour désactiver la majoration',
queryset=(Account.objects
.select_related('cofprofile', 'cofprofile__user')
.all()),
)
kfet_overdraft_duration = forms.DurationField(
label='Durée du découvert autorisé par défaut',
initial=timedelta(days=1),
)
kfet_overdraft_amount = forms.DecimalField(
label='Montant du découvert autorisé par défaut', initial=Decimal('20'),
max_digits=6, decimal_places=2,
)
kfet_cancel_duration = forms.DurationField(
label='Durée pour annuler une commande sans mot de passe',
initial=timedelta(minutes=5),
)
self.cleaned_data['name'] = name
if name in type_decimal:
if not value_decimal:
raise ValidationError('Renseignez une valeur décimale')
self.cleaned_data['value_account'] = None
self.cleaned_data['value_duration'] = None
elif name in type_account:
self.cleaned_data['value_decimal'] = None
self.cleaned_data['value_duration'] = None
elif name in type_duration:
if not value_duration:
raise ValidationError('Renseignez une durée')
self.cleaned_data['value_decimal'] = None
self.cleaned_data['value_account'] = None
super(SettingsForm, self).clean()
class FilterHistoryForm(forms.Form):
checkouts = forms.ModelMultipleChoiceField(queryset = Checkout.objects.all())

View file

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
from kfet.forms import KFetConfigForm
def adapt_settings(apps, schema_editor):
Settings = apps.get_model('kfet', 'Settings')
db_alias = schema_editor.connection.alias
obj = Settings.objects.using(db_alias)
cfg = {}
def try_get(new, old, type_field):
try:
value = getattr(obj.get(name=old), type_field)
cfg[new] = value
except Settings.DoesNotExist:
pass
try_get('kfet_subvention_cof', 'SUBVENTION_COF', 'value_decimal')
try_get('kfet_addcost_amount', 'ADDCOST_AMOUNT', 'value_decimal')
try_get('kfet_addcost_for', 'ADDCOST_FOR', 'value_account')
try_get('kfet_overdraft_duration', 'OVERDRAFT_DURATION', 'value_duration')
try_get('kfet_overdraft_amount', 'OVERDRAFT_AMOUNT', 'value_decimal')
try_get('kfet_cancel_duration', 'CANCEL_DURATION', 'value_duration')
cfg_form = KFetConfigForm(initial=cfg)
if cfg_form.is_valid():
cfg_form.save()
class Migration(migrations.Migration):
dependencies = [
('kfet', '0050_remove_checkout'),
('djconfig', '0001_initial'),
]
operations = [
migrations.RunPython(adapt_settings),
migrations.RemoveField(
model_name='settings',
name='value_account',
),
migrations.DeleteModel(
name='Settings',
),
]

View file

@ -1,12 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import *
from django.db import models
from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.validators import RegexValidator
from django.contrib.auth.models import User
from gestioncof.models import CofProfile
@ -15,11 +10,12 @@ from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible
from django.db import transaction
from django.db.models import F
from django.core.cache import cache
from datetime import date, timedelta
from datetime import date
import re
import hashlib
from kfet.config import kfet_config
def choices_length(choices):
return reduce(lambda m, choice: max(m, len(choice[0])), choices, 0)
@ -113,8 +109,8 @@ class Account(models.Model):
return data
def perms_to_perform_operation(self, amount):
overdraft_duration_max = Settings.OVERDRAFT_DURATION()
overdraft_amount_max = Settings.OVERDRAFT_AMOUNT()
overdraft_duration_max = kfet_config.overdraft_duration
overdraft_amount_max = kfet_config.overdraft_amount
perms = set()
stop_ope = False
# Checking is cash account
@ -620,116 +616,6 @@ class GlobalPermissions(models.Model):
('special_add_account', "Créer un compte avec une balance initiale")
)
class Settings(models.Model):
name = models.CharField(
max_length = 45,
unique = True,
db_index = True)
value_decimal = models.DecimalField(
max_digits = 6, decimal_places = 2,
blank = True, null = True, default = None)
value_account = models.ForeignKey(
Account, on_delete = models.PROTECT,
blank = True, null = True, default = None)
value_duration = models.DurationField(
blank = True, null = True, default = None)
@staticmethod
def setting_inst(name):
return Settings.objects.get(name=name)
@staticmethod
def SUBVENTION_COF():
subvention_cof = cache.get('SUBVENTION_COF')
if subvention_cof:
return subvention_cof
try:
subvention_cof = Settings.setting_inst("SUBVENTION_COF").value_decimal
except Settings.DoesNotExist:
subvention_cof = 0
cache.set('SUBVENTION_COF', subvention_cof)
return subvention_cof
@staticmethod
def ADDCOST_AMOUNT():
try:
return Settings.setting_inst("ADDCOST_AMOUNT").value_decimal
except Settings.DoesNotExist:
return 0
@staticmethod
def ADDCOST_FOR():
try:
return Settings.setting_inst("ADDCOST_FOR").value_account
except Settings.DoesNotExist:
return None;
@staticmethod
def OVERDRAFT_DURATION():
overdraft_duration = cache.get('OVERDRAFT_DURATION')
if overdraft_duration:
return overdraft_duration
try:
overdraft_duration = Settings.setting_inst("OVERDRAFT_DURATION").value_duration
except Settings.DoesNotExist:
overdraft_duration = timedelta()
cache.set('OVERDRAFT_DURATION', overdraft_duration)
return overdraft_duration
@staticmethod
def OVERDRAFT_AMOUNT():
overdraft_amount = cache.get('OVERDRAFT_AMOUNT')
if overdraft_amount:
return overdraft_amount
try:
overdraft_amount = Settings.setting_inst("OVERDRAFT_AMOUNT").value_decimal
except Settings.DoesNotExist:
overdraft_amount = 0
cache.set('OVERDRAFT_AMOUNT', overdraft_amount)
return overdraft_amount
@staticmethod
def CANCEL_DURATION():
cancel_duration = cache.get('CANCEL_DURATION')
if cancel_duration:
return cancel_duration
try:
cancel_duration = Settings.setting_inst("CANCEL_DURATION").value_duration
except Settings.DoesNotExist:
cancel_duration = timedelta()
cache.set('CANCEL_DURATION', cancel_duration)
return cancel_duration
@staticmethod
def create_missing():
s, created = Settings.objects.get_or_create(name='SUBVENTION_COF')
if created:
s.value_decimal = 25
s.save()
s, created = Settings.objects.get_or_create(name='ADDCOST_AMOUNT')
if created:
s.value_decimal = 0.5
s.save()
s, created = Settings.objects.get_or_create(name='ADDCOST_FOR')
s, created = Settings.objects.get_or_create(name='OVERDRAFT_DURATION')
if created:
s.value_duration = timedelta(days=1) # 24h
s.save()
s, created = Settings.objects.get_or_create(name='OVERDRAFT_AMOUNT')
if created:
s.value_decimal = 20
s.save()
s, created = Settings.objects.get_or_create(name='CANCEL_DURATION')
if created:
s.value_duration = timedelta(minutes=5) # 5min
s.save()
@staticmethod
def empty_cache():
cache.delete_many([
'SUBVENTION_COF', 'OVERDRAFT_DURATION', 'OVERDRAFT_AMOUNT',
'CANCEL_DURATION', 'ADDCOST_AMOUNT', 'ADDCOST_FOR',
])
class GenericTeamToken(models.Model):
token = models.CharField(max_length = 50, unique = True)

View file

@ -16,8 +16,8 @@
</div>
<div class="block">
<div class="line"><b>Découvert autorisé par défaut</b></div>
<div class="line">Montant: {{ settings.overdraft_amount }}€</div>
<div class="line">Pendant: {{ settings.overdraft_duration }}</div>
<div class="line">Montant: {{ kfet_config.overdraft_amount }}€</div>
<div class="line">Pendant: {{ kfet_config.overdraft_duration }}</div>
</div>
</div>
{% if perms.kfet.change_settings %}

View file

@ -95,7 +95,7 @@
<script type="text/javascript">
$(document).ready(function() {
settings = { 'subvention_cof': parseFloat({{ settings.subvention_cof|unlocalize }})}
settings = { 'subvention_cof': parseFloat({{ kfet_config.subvention_cof|unlocalize }})}
khistory = new KHistory({
display_trigramme: false,

View file

@ -60,7 +60,7 @@
<script type="text/javascript">
$(document).ready(function() {
settings = { 'subvention_cof': parseFloat({{ settings.subvention_cof|unlocalize }})}
settings = { 'subvention_cof': parseFloat({{ kfet_config.subvention_cof|unlocalize }})}
khistory = new KHistory();

View file

@ -5,20 +5,42 @@
{% block content %}
{% include 'kfet/base_messages.html' %}
<table>
<tr>
<td></td>
<td>Nom</td>
<td>Valeur</td>
</tr>
{% for setting in settings %}
<tr>
<td><a href="{% url 'kfet.settings.update' setting.pk %}">Modifier</a></td>
<td>{{ setting.name }}</td>
<td>{% firstof setting.value_decimal setting.value_duration setting.value_account %}</td>
</tr>
{% endfor %}
</table>
<div class="row">
<div class="col-sm-4 col-md-3 col-content-left">
<div class="content-left">
<div class="buttons">
<a class="btn btn-primary btn-lg" href="{% url 'kfet.settings.update' %}">
Modifier
</a>
</div>
</div>
</div>
<div class="col-sm-8 col-md-9 col-content-right">
{% include 'kfet/base_messages.html' %}
<div class="content-right">
<div class="content-right-block">
<h2>Valeurs</h2>
<div class="table-responsive">
<table class="table table-condensed">
<thead>
<tr>
<td>Nom</td>
<td>Valeur</td>
</tr>
</thead>
<tbody>
{% for key, value in kfet_config.list %}
<tr>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,14 +1,25 @@
{% extends 'kfet/base.html' %}
{% block title %}Modification de {{ settings.name }}{% endblock %}
{% block content-header-title %}Modification de {{ settings.name }}{% endblock %}
{% block title %}Modification des paramètres{% endblock %}
{% block content-header-title %}Modification des paramètres{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Mettre à jour">
</form>
{% include "kfet/base_messages.html" %}
<div class="row form-only">
<div class="col-sm-12 col-md-8 col-md-offset-2">
<div class="content-form">
<form submit="" method="post" class="form-horizontal">
{% csrf_token %}
{% include 'kfet/form_snippet.html' with form=form %}
{% if not perms.kfet.change_settings %}
{% include 'kfet/form_authentication_snippet.html' %}
{% endif %}
{% include 'kfet/form_submit_snippet.html' with value="Mettre à jour" %}
</form>
</div>
</div>
</div>
{% endblock %}

View file

@ -3,10 +3,11 @@
from django import template
from django.utils.html import escape
from django.utils.safestring import mark_safe
from kfet.models import Settings
from math import floor
import re
from kfet.config import kfet_config
register = template.Library()
@ -40,5 +41,5 @@ def highlight_clipper(clipper, q):
@register.filter()
def ukf(balance, is_cof):
grant = is_cof and (1 + Settings.SUBVENTION_COF() / 100) or 1
grant = is_cof and (1 + kfet_config.subvention_cof / 100) or 1
return floor(balance * 10 * grant)

View file

@ -200,7 +200,7 @@ urlpatterns = [
permission_required('kfet.change_settings')
(views.SettingsList.as_view()),
name='kfet.settings'),
url(r'^settings/(?P<pk>\d+)/edit$',
url(r'^settings/edit$',
permission_required('kfet.change_settings')
(views.SettingsUpdate.as_view()),
name='kfet.settings.update'),

View file

@ -22,9 +22,11 @@ from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.decorators import method_decorator
from gestioncof.models import CofProfile
from kfet.config import kfet_config
from kfet.decorators import teamkfet_required
from kfet.models import (
Account, Checkout, Article, Settings, AccountNegative,
Account, Checkout, Article, AccountNegative,
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
InventoryArticle, Order, OrderArticle, Operation, OperationGroup,
TransferGroup, Transfer)
@ -35,9 +37,9 @@ from kfet.forms import (
GroupForm, CheckoutForm, CheckoutRestrictForm, CheckoutStatementCreateForm,
CheckoutStatementUpdateForm, ArticleForm, ArticleRestrictForm,
KPsulOperationGroupForm, KPsulAccountForm, KPsulCheckoutForm,
KPsulOperationFormSet, AddcostForm, FilterHistoryForm, SettingsForm,
KPsulOperationFormSet, AddcostForm, FilterHistoryForm,
TransferFormSet, InventoryArticleForm, OrderArticleForm,
OrderArticleToInventoryForm
OrderArticleToInventoryForm, KFetConfigForm
)
from collections import defaultdict
from kfet import consumers
@ -346,12 +348,14 @@ def account_create_ajax(request, username=None, login_clipper=None,
'user_form' : forms['user_form'],
})
# Account - Read
@login_required
def account_read(request, trigramme):
try:
account = Account.objects.select_related('negative').get(trigramme=trigramme)
account = (Account.objects.select_related('negative')
.get(trigramme=trigramme))
except Account.DoesNotExist:
raise Http404
@ -361,16 +365,17 @@ def account_read(request, trigramme):
raise PermissionDenied
addcosts = (OperationGroup.objects
.filter(opes__addcost_for=account,opes__canceled_at=None)
.extra({'date':"date(at)"})
.values('date')
.annotate(sum_addcosts=Sum('opes__addcost_amount'))
.order_by('-date'))
.filter(opes__addcost_for=account,
opes__canceled_at=None)
.extra({'date': "date(at)"})
.values('date')
.annotate(sum_addcosts=Sum('opes__addcost_amount'))
.order_by('-date')
)
return render(request, "kfet/account_read.html", {
'account' : account,
'account': account,
'addcosts': addcosts,
'settings': { 'subvention_cof': Settings.SUBVENTION_COF() },
})
# Account - Update
@ -548,10 +553,6 @@ class AccountNegativeList(ListView):
def get_context_data(self, **kwargs):
context = super(AccountNegativeList, self).get_context_data(**kwargs)
context['settings'] = {
'overdraft_amount': Settings.OVERDRAFT_AMOUNT(),
'overdraft_duration': Settings.OVERDRAFT_DURATION(),
}
negs_sum = (AccountNegative.objects
.exclude(account__trigramme='#13')
.aggregate(
@ -870,16 +871,18 @@ def kpsul(request):
data['operation_formset'] = operation_formset
return render(request, 'kfet/kpsul.html', data)
@teamkfet_required
def kpsul_get_settings(request):
addcost_for = Settings.ADDCOST_FOR()
addcost_for = kfet_config.addcost_for
data = {
'subvention_cof': Settings.SUBVENTION_COF(),
'addcost_for' : addcost_for and addcost_for.trigramme or '',
'addcost_amount': Settings.ADDCOST_AMOUNT(),
'subvention_cof': kfet_config.subvention_cof,
'addcost_for': addcost_for and addcost_for.trigramme or '',
'addcost_amount': kfet_config.addcost_amount,
}
return JsonResponse(data)
@teamkfet_required
def account_read_json(request):
trigramme = request.POST.get('trigramme', '')
@ -919,37 +922,41 @@ def kpsul_checkout_data(request):
raise Http404
return JsonResponse(data)
@teamkfet_required
def kpsul_update_addcost(request):
addcost_form = AddcostForm(request.POST)
if not addcost_form.is_valid():
data = { 'errors': { 'addcost': list(addcost_form.errors) } }
data = {'errors': {'addcost': list(addcost_form.errors)}}
return JsonResponse(data, status=400)
required_perms = ['kfet.manage_addcosts']
if not request.user.has_perms(required_perms):
data = {
'errors': {
'missing_perms': get_missing_perms(required_perms, request.user)
'missing_perms': get_missing_perms(required_perms,
request.user),
}
}
return JsonResponse(data, status=403)
trigramme = addcost_form.cleaned_data['trigramme']
account = trigramme and Account.objects.get(trigramme=trigramme) or None
Settings.objects.filter(name='ADDCOST_FOR').update(value_account=account)
Settings.objects.filter(name='ADDCOST_AMOUNT').update(value_decimal=addcost_form.cleaned_data['amount'])
cache.delete('ADDCOST_FOR')
cache.delete('ADDCOST_AMOUNT')
amount = addcost_form.cleaned_data['amount']
cfg_form = KFetConfigForm(kfet_addcost_for=account,
kfet_addcost_amount=amount)
cfg_form.save()
data = {
'addcost': {
'for': trigramme and account.trigramme or None,
'amount': addcost_form.cleaned_data['amount'],
'amount': amount,
}
}
consumers.KPsul.group_send('kfet.kpsul', data)
return JsonResponse(data)
def get_missing_perms(required_perms, user):
missing_perms_codenames = [ (perm.split('.'))[1]
for perm in required_perms if not user.has_perm(perm)]
@ -984,10 +991,10 @@ def kpsul_perform_operations(request):
operations = operation_formset.save(commit = False)
# Retrieving COF grant
cof_grant = Settings.SUBVENTION_COF()
cof_grant = kfet_config.subvention_cof
# Retrieving addcosts data
addcost_amount = Settings.ADDCOST_AMOUNT()
addcost_for = Settings.ADDCOST_FOR()
addcost_amount = kfet_config.addcost_amount
addcost_for = kfet_config.addcost_for
# Initializing vars
required_perms = set() # Required perms to perform all operations
@ -1170,7 +1177,7 @@ def kpsul_cancel_operations(request):
opes = [] # Pas déjà annulée
required_perms = set()
stop_all = False
cancel_duration = Settings.CANCEL_DURATION()
cancel_duration = kfet_config.cancel_duration
to_accounts_balances = defaultdict(lambda:0) # Modifs à faire sur les balances des comptes
to_groups_amounts = defaultdict(lambda:0) # ------ sur les montants des groupes d'opé
to_checkouts_balances = defaultdict(lambda:0) # ------ sur les balances de caisses
@ -1397,34 +1404,28 @@ def kpsul_articles_data(request):
.filter(is_sold=True))
return JsonResponse({ 'articles': list(articles) })
@teamkfet_required
def history(request):
data = {
'filter_form': FilterHistoryForm(),
'settings': {
'subvention_cof': Settings.SUBVENTION_COF(),
}
}
return render(request, 'kfet/history.html', data)
# -----
# Settings views
# -----
class SettingsList(ListView):
model = Settings
context_object_name = 'settings'
class SettingsList(TemplateView):
template_name = 'kfet/settings.html'
def get_context_data(self, **kwargs):
Settings.create_missing()
return super(SettingsList, self).get_context_data(**kwargs)
class SettingsUpdate(SuccessMessageMixin, UpdateView):
model = Settings
form_class = SettingsForm
class SettingsUpdate(SuccessMessageMixin, FormView):
form_class = KFetConfigForm
template_name = 'kfet/settings_update.html'
success_message = 'Paramètre %(name)s mis à jour'
success_message = 'Paramètres mis à jour'
success_url = reverse_lazy('kfet.settings')
def form_valid(self, form):
@ -1432,9 +1433,9 @@ class SettingsUpdate(SuccessMessageMixin, UpdateView):
if not self.request.user.has_perm('kfet.change_settings'):
form.add_error(None, 'Permission refusée')
return self.form_invalid(form)
# Creating
Settings.empty_cache()
return super(SettingsUpdate, self).form_valid(form)
form.save()
return super().form_valid(form)
# -----
# Transfer views
@ -1560,7 +1561,7 @@ def cancel_transfers(request):
transfers = [] # Pas déjà annulée
required_perms = set()
stop_all = False
cancel_duration = Settings.CANCEL_DURATION()
cancel_duration = kfet_config.cancel_duration
to_accounts_balances = defaultdict(lambda:0) # Modifs à faire sur les balances des comptes
for transfer in transfers_all:
if transfer.canceled_at:

View file

@ -3,6 +3,7 @@ Django==1.8.*
django-autocomplete-light==2.3.3
django-autoslug==1.9.3
django-cas-ng==3.5.5
django-djconfig==0.5.3
django-grappelli==2.8.1
django-recaptcha==1.0.5
mysqlclient==1.3.7