From 8c6d56b27c405bf4cf81140a55fb1550b26cc030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Tue, 30 May 2017 20:44:30 +0200 Subject: [PATCH 1/3] Add Wagtail CMS for kfet app. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit K-Fêt - Integrate wagtail to serve "static" pages of old K-Fêt website - Fixture "kfetcms/kfet_wagtail_17_05" contains a copy of old website (as in May 2017). - Media files can be got until end of June 17 at http://partage.eleves.ens.fr//files/604e6dea2ceebc66b1936c6b3f911744/kfet_media.tar.gz Login/logout - Update package django_cas_ng to last version. - Clean COFCASBackend. - Change CAS version to 3 (version used on eleves.ens). This enables the logout redirection (for CAS ofc). - Add messages and clean existing ones on login/logout (for both outsider and cas users). Misc - Update settings to bypass an incompability between debug-toolbar and wagtailmenus packages. - Better management of dev/test-specific urls (if debug-toolbar wasn't in INSTALLED_APPS, media files were not served). - UI improvements. --- README.md | 2 +- cof/settings/common.py | 28 + cof/settings/dev.py | 20 + cof/urls.py | 14 +- gestioncof/__init__.py | 1 + gestioncof/apps.py | 8 + gestioncof/shared.py | 58 +- gestioncof/signals.py | 23 + gestioncof/templates/home.html | 4 +- gestioncof/views.py | 29 +- kfet/cms/__init__.py | 1 + kfet/cms/apps.py | 7 + kfet/cms/context_processors.py | 20 + kfet/cms/fixtures/kfet_wagtail_17_05.json | 1565 +++++++++++++++++ .../management/commands/kfet_loadwagtail.py | 35 + kfet/cms/migrations/0001_initial.py | 75 + kfet/cms/migrations/__init__.py | 0 kfet/cms/models.py | 165 ++ kfet/cms/static/kfetcms/css/index.css | 155 ++ kfet/cms/templates/kfetcms/base.html | 68 + kfet/cms/templates/kfetcms/carte.html | 46 + kfet/cms/templates/kfetcms/equipe.html | 67 + kfet/management/commands/loadkfetdevdata.py | 6 + kfet/models.py | 10 +- kfet/signals.py | 12 +- kfet/static/kfet/css/footer.css | 19 + kfet/static/kfet/css/history.css | 5 +- kfet/static/kfet/css/home.css | 74 +- kfet/static/kfet/css/index.css | 274 ++- kfet/static/kfet/css/jconfirm-kfet.css | 5 +- kfet/static/kfet/css/kpsul.css | 33 +- kfet/static/kfet/css/nav.css | 117 +- kfet/static/kfet/img/favicon.png | Bin 0 -> 3606 bytes kfet/static/kfet/js/statistic.js | 1 - kfet/templates/kfet/account.html | 33 +- kfet/templates/kfet/account_group.html | 8 +- kfet/templates/kfet/account_negative.html | 14 +- kfet/templates/kfet/account_read.html | 4 + kfet/templates/kfet/account_update.html | 6 + kfet/templates/kfet/article.html | 19 +- kfet/templates/kfet/article_read.html | 57 +- kfet/templates/kfet/base.html | 27 +- kfet/templates/kfet/base_col_1.html | 4 +- kfet/templates/kfet/base_col_2.html | 4 +- kfet/templates/kfet/base_footer.html | 17 + kfet/templates/kfet/base_messages.html | 18 +- kfet/templates/kfet/base_nav.html | 147 +- kfet/templates/kfet/category.html | 8 +- kfet/templates/kfet/checkout.html | 15 +- kfet/templates/kfet/checkout_read.html | 13 +- kfet/templates/kfet/home.html | 59 - kfet/templates/kfet/inventory.html | 13 +- kfet/templates/kfet/inventory_create.html | 4 +- kfet/templates/kfet/inventory_read.html | 6 +- kfet/templates/kfet/kpsul.html | 32 +- kfet/templates/kfet/left_account.html | 39 +- kfet/templates/kfet/left_checkout.html | 17 +- kfet/templates/kfet/nav_item.html | 18 + kfet/templates/kfet/order.html | 14 +- kfet/templates/kfet/order_create.html | 4 +- kfet/templates/kfet/order_read.html | 23 +- kfet/templates/kfet/order_to_inventory.html | 10 +- kfet/templates/kfet/settings.html | 4 +- kfet/templates/kfet/transfers.html | 4 +- kfet/urls.py | 7 +- kfet/views.py | 57 +- requirements.txt | 4 +- 67 files changed, 3038 insertions(+), 618 deletions(-) create mode 100644 gestioncof/apps.py create mode 100644 gestioncof/signals.py create mode 100644 kfet/cms/__init__.py create mode 100644 kfet/cms/apps.py create mode 100644 kfet/cms/context_processors.py create mode 100644 kfet/cms/fixtures/kfet_wagtail_17_05.json create mode 100644 kfet/cms/management/commands/kfet_loadwagtail.py create mode 100644 kfet/cms/migrations/0001_initial.py create mode 100644 kfet/cms/migrations/__init__.py create mode 100644 kfet/cms/models.py create mode 100644 kfet/cms/static/kfetcms/css/index.css create mode 100644 kfet/cms/templates/kfetcms/base.html create mode 100644 kfet/cms/templates/kfetcms/carte.html create mode 100644 kfet/cms/templates/kfetcms/equipe.html create mode 100644 kfet/static/kfet/css/footer.css create mode 100644 kfet/static/kfet/img/favicon.png delete mode 100644 kfet/templates/kfet/home.html create mode 100644 kfet/templates/kfet/nav_item.html diff --git a/README.md b/README.md index 1a3d575e..b6017577 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ Charger les mails indispensables au bon fonctionnement de GestioCOF : Une base de donnée pré-remplie est disponible en lançant les commandes : - python manage.py loaddata gestion sites accounts groups articles + python manage.py loaddata gestion sites articles python manage.py loaddevdata Vous êtes prêts à développer ! Lancer GestioCOF en faisant diff --git a/cof/settings/common.py b/cof/settings/common.py index 261760d6..f7c7bba6 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -56,6 +56,22 @@ INSTALLED_APPS = [ 'widget_tweaks', 'custommail', 'djconfig', + 'wagtail.wagtailforms', + 'wagtail.wagtailredirects', + 'wagtail.wagtailembeds', + 'wagtail.wagtailsites', + 'wagtail.wagtailusers', + 'wagtail.wagtailsnippets', + 'wagtail.wagtaildocs', + 'wagtail.wagtailimages', + 'wagtail.wagtailsearch', + 'wagtail.wagtailadmin', + 'wagtail.wagtailcore', + 'wagtail.contrib.modeladmin', + 'wagtailmenus', + 'modelcluster', + 'taggit', + 'kfet.cms', ] MIDDLEWARE_CLASSES = [ @@ -69,6 +85,8 @@ MIDDLEWARE_CLASSES = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'djconfig.middleware.DjConfigMiddleware', + 'wagtail.wagtailcore.middleware.SiteMiddleware', + 'wagtail.wagtailredirects.middleware.RedirectMiddleware', ] ROOT_URLCONF = 'cof.urls' @@ -87,6 +105,7 @@ TEMPLATES = [ 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', + 'wagtailmenus.context_processors.wagtailmenus', 'djconfig.context_processors.config', 'gestioncof.shared.context_processor', 'kfet.context_processors.auth', @@ -143,9 +162,12 @@ LOGIN_URL = "cof-login" LOGIN_REDIRECT_URL = "home" CAS_SERVER_URL = 'https://cas.eleves.ens.fr/' +CAS_VERSION = '3' +CAS_LOGIN_MSG = None CAS_IGNORE_REFERER = True CAS_REDIRECT_URL = '/' CAS_EMAIL_FORMAT = "%s@clipper.ens.fr" + AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'gestioncof.shared.COFCASBackend', @@ -171,3 +193,9 @@ CHANNEL_LAYERS = { } FORMAT_MODULE_PATH = 'cof.locale' + +# Wagtail settings + +WAGTAIL_SITE_NAME = 'GestioCOF' +WAGTAIL_ENABLE_UPDATE_CHECK = False +TAGGIT_CASE_INSENSITIVE = True diff --git a/cof/settings/dev.py b/cof/settings/dev.py index a3a17f99..ffd34c7d 100644 --- a/cof/settings/dev.py +++ b/cof/settings/dev.py @@ -28,6 +28,26 @@ MEDIA_URL = '/media/' # Debug tool bar # --- +# "Versions" panel of django-debug-toolbar <=1.8 is not compatible with +# wagtailmenus. +# See https://github.com/jazzband/django-debug-toolbar/issues/922 +# TODO: Bug should be fixed in ddt 1.9 (not released yet). When fixed, this +# declaration may be removed. +DEBUG_TOOLBAR_PANELS = [ + 'debug_toolbar.panels.timer.TimerPanel', + 'debug_toolbar.panels.settings.SettingsPanel', + 'debug_toolbar.panels.headers.HeadersPanel', + 'debug_toolbar.panels.request.RequestPanel', + 'debug_toolbar.panels.sql.SQLPanel', + 'debug_toolbar.panels.staticfiles.StaticFilesPanel', + 'debug_toolbar.panels.templates.TemplatesPanel', + 'debug_toolbar.panels.cache.CachePanel', + 'debug_toolbar.panels.signals.SignalsPanel', + 'debug_toolbar.panels.logging.LoggingPanel', + 'debug_toolbar.panels.redirects.RedirectsPanel', +] + + def show_toolbar(request): """ On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar diff --git a/cof/urls.py b/cof/urls.py index 06b1087a..886070e9 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -14,6 +14,10 @@ from django.views.generic.base import TemplateView from django.contrib.auth import views as django_views from django_cas_ng import views as django_cas_views +from wagtail.wagtailadmin import urls as wagtailadmin_urls +from wagtail.wagtailcore import urls as wagtail_urls +from wagtail.wagtaildocs import urls as wagtaildocs_urls + from gestioncof import views as gestioncof_views, csv_views from gestioncof.urls import export_patterns, petitcours_patterns, \ surveys_patterns, events_patterns, calendar_patterns, \ @@ -48,7 +52,7 @@ urlpatterns = [ url(r'^outsider/login$', gestioncof_views.login_ext), url(r'^outsider/logout$', django_views.logout, {'next_page': 'home'}), url(r'^login$', gestioncof_views.login, name="cof-login"), - url(r'^logout$', gestioncof_views.logout), + url(r'^logout$', gestioncof_views.logout, name="cof-logout"), # Infos persos url(r'^profile$', gestioncof_views.profile), url(r'^outsider/password-change$', django_views.password_change), @@ -82,6 +86,8 @@ urlpatterns = [ url(r'^utile_cof/diff_cof$', gestioncof_views.liste_diffcof), url(r'^utile_bda/bda_revente$', gestioncof_views.liste_bdarevente), url(r'^k-fet/', include('kfet.urls')), + url(r'^cms/', include(wagtailadmin_urls)), + url(r'^documents/', include(wagtaildocs_urls)), ] if 'debug_toolbar' in settings.INSTALLED_APPS: @@ -90,7 +96,13 @@ if 'debug_toolbar' in settings.INSTALLED_APPS: url(r'^__debug__/', include(debug_toolbar.urls)), ] +if settings.DEBUG: # Si on est en production, MEDIA_ROOT est servi par Apache. # Il faut dire à Django de servir MEDIA_ROOT lui-même en développement. urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + +# Wagtail for uncatched +urlpatterns += [ + url(r'', include(wagtail_urls)), +] diff --git a/gestioncof/__init__.py b/gestioncof/__init__.py index e69de29b..b77fdb94 100644 --- a/gestioncof/__init__.py +++ b/gestioncof/__init__.py @@ -0,0 +1 @@ +default_app_config = 'gestioncof.apps.GestioncofConfig' diff --git a/gestioncof/apps.py b/gestioncof/apps.py new file mode 100644 index 00000000..6e24b050 --- /dev/null +++ b/gestioncof/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class GestioncofConfig(AppConfig): + name = 'gestioncof' + + def ready(self): + import gestioncof.signals diff --git a/gestioncof/shared.py b/gestioncof/shared.py index e4180b49..fabcacb9 100644 --- a/gestioncof/shared.py +++ b/gestioncof/shared.py @@ -1,62 +1,26 @@ -from django.contrib.sites.models import Site from django.conf import settings +from django.contrib.sites.models import Site + from django_cas_ng.backends import CASBackend -from django_cas_ng.utils import get_cas_client -from django.contrib.auth import get_user_model from gestioncof.models import CofProfile -User = get_user_model() - class COFCASBackend(CASBackend): - def authenticate_cas(self, ticket, service, request): - """Verifies CAS ticket and gets or creates User object""" - - client = get_cas_client(service_url=service) - username, attributes, _ = client.verify_ticket(ticket) - if attributes: - request.session['attributes'] = attributes - if not username: - return None + def clean_username(self, username): # Le CAS de l'ENS accepte les logins avec des espaces au début # et à la fin, ainsi qu’avec une casse variable. On normalise pour # éviter les doublons. - username = username.strip().lower() + return username.strip().lower() - profiles = CofProfile.objects.filter(login_clipper=username) - if len(profiles) > 0: - profile = profiles.order_by('-is_cof')[0] - user = profile.user - return user - try: - user = User.objects.get(username=username) - except User.DoesNotExist: - # user will have an "unusable" password - user = User.objects.create_user(username, '') - user.save() - return user - - def authenticate(self, ticket, service, request): - """Authenticates CAS ticket and retrieves user data""" - user = self.authenticate_cas(ticket, service, request) - if user is None: - return user - try: - profile = user.profile - except CofProfile.DoesNotExist: - profile, created = CofProfile.objects.get_or_create(user=user) - profile.save() - if not profile.login_clipper: - profile.login_clipper = user.username - profile.save() - if not user.email: - user.email = settings.CAS_EMAIL_FORMAT % profile.login_clipper - user.save() - if profile.is_buro and not user.is_staff: - user.is_staff = True - user.save() + def configure_user(self, user): + # cannot use "defaults" arg + profile, _ = CofProfile.objects.get_or_create(user=user) + profile.login_clipper = user.username + profile.save() + user.email = settings.CAS_EMAIL_FORMAT % profile.login_clipper + user.save() return user diff --git a/gestioncof/signals.py b/gestioncof/signals.py new file mode 100644 index 00000000..11cb55fc --- /dev/null +++ b/gestioncof/signals.py @@ -0,0 +1,23 @@ +from django.contrib import messages +from django.contrib.auth.signals import user_logged_in +from django.dispatch import receiver +from django.utils.translation import ugettext_lazy as _ + +from django_cas_ng.signals import cas_user_authenticated + + +@receiver(user_logged_in) +def messages_on_out_login(request, user, **kwargs): + if user.backend.startswith('django.contrib.auth'): + msg = _('Connexion à GestioCOF réussie. Bienvenue {}.').format( + user.get_short_name(), + ) + messages.success(request, msg) + + +@receiver(cas_user_authenticated) +def mesagges_on_cas_login(request, user, **kwargs): + msg = _('Connexion à GestioCOF par CAS réussie. Bienvenue {}.').format( + user.get_short_name(), + ) + messages.success(request, msg) diff --git a/gestioncof/templates/home.html b/gestioncof/templates/home.html index 5f783a48..acc04f30 100644 --- a/gestioncof/templates/home.html +++ b/gestioncof/templates/home.html @@ -1,4 +1,5 @@ {% extends "gestioncof/base_header.html" %} +{% load wagtailcore_tags %} {% block homelink %} {% endblock %} @@ -55,7 +56,8 @@

K-Fêt

+{% if perms.kfet.manage_perms or perms.kfet.view_negs %} +
{% if perms.kfet.manage_perms %} + {% endif %} {% if perms.kfet.view_negs %} + {% endif %}
+{% endif %} {% endblock %} @@ -26,16 +39,15 @@

Liste des comptes

- +
- - + - - + + - + @@ -43,15 +55,14 @@ - - + - + {% endfor %} diff --git a/kfet/templates/kfet/account_group.html b/kfet/templates/kfet/account_group.html index 96508aa4..e7243258 100644 --- a/kfet/templates/kfet/account_group.html +++ b/kfet/templates/kfet/account_group.html @@ -5,7 +5,7 @@ {% block fixed-content %} -
+ @@ -40,7 +40,11 @@

Comptes

diff --git a/kfet/templates/kfet/account_negative.html b/kfet/templates/kfet/account_negative.html index e92f3f70..741ad9dd 100644 --- a/kfet/templates/kfet/account_negative.html +++ b/kfet/templates/kfet/account_negative.html @@ -18,7 +18,7 @@ {% if perms.kfet.change_settings %} -
+ {% endif %} @@ -30,14 +30,13 @@

Liste des comptes en négatifs

-
TrigrammeTri. NomBalanceCOFBalanceCOF DptPromoPromo
- + {{ account.trigramme }} {{ account.trigramme }} {{ account.name }} {{ account.balance }}€{{ account.is_cof|yesno:"Oui,Non" }}{{ account.is_cof|yesno }} {{ account.departement }}{{ account.promo|default_if_none:'' }}{{ account.promo|default_if_none:'' }}
+
- - + - - + + @@ -49,10 +48,9 @@ -
TriTri. NomBalanceRéelleBalanceRéelle Début Découvert autorisé Jusqu'au
- + {{ neg.account.trigramme }} {{ neg.account.trigramme }} {{ neg.account.name }} {{ neg.account.balance|floatformat:2 }}€ diff --git a/kfet/templates/kfet/account_read.html b/kfet/templates/kfet/account_read.html index 282e035f..fc8babc5 100644 --- a/kfet/templates/kfet/account_read.html +++ b/kfet/templates/kfet/account_read.html @@ -44,6 +44,10 @@ $(document).ready(function() { {% endif %} {% endblock %} +{% block footer %} +{% include "kfet/base_footer.html" %} +{% endblock %} + {% block fixed-content %} {% include "kfet/left_account.html" %} {% endblock %} diff --git a/kfet/templates/kfet/account_update.html b/kfet/templates/kfet/account_update.html index 86c27b48..47a043a4 100644 --- a/kfet/templates/kfet/account_update.html +++ b/kfet/templates/kfet/account_update.html @@ -20,6 +20,12 @@ {% endif %} {% endblock %} +{% block footer %} +{% if not account.user.is_team %} +{% include "kfet/base_footer.html" %} +{% endif %} +{% endblock %} + {% block main-class %}content-form{% endblock %} {% block main-content %} diff --git a/kfet/templates/kfet/article.html b/kfet/templates/kfet/article.html index 398ef658..86bdc518 100644 --- a/kfet/templates/kfet/article.html +++ b/kfet/templates/kfet/article.html @@ -9,13 +9,18 @@
{{ articles|length }}
article{{ articles|length|pluralize }}
-
+ {% endblock %} @@ -24,10 +29,9 @@

Liste des articles

- +
- @@ -40,16 +44,15 @@ {% for article in articles %} {% ifchanged article.category %} - + {% endifchanged %} - - diff --git a/kfet/templates/kfet/article_read.html b/kfet/templates/kfet/article_read.html index 134fb104..8cd84ded 100644 --- a/kfet/templates/kfet/article_read.html +++ b/kfet/templates/kfet/article_read.html @@ -14,6 +14,14 @@
{{ article.name }}
{{ article.category }}
+
Prix (hors réduc.): {{ article.price }}€
Stock: {{ article.stock }}
@@ -21,11 +29,6 @@
Affiché: {{ article.hidden | yesno:"Non,Oui" }}
- {% endblock %} @@ -36,29 +39,35 @@

Inventaires

-
Nom Prix Stock
{{ article.category.name }}{{ article.category.name }}
+ - + {{ article.name }} {{ article.name }} {{ article.price }}€ {{ article.stock }} {{ article.is_sold | yesno:"En vente,Non vendu"}}
- - - - - - - - - {% for inventoryart in inventoryarts %} - - - - - - {% endfor %} - -
DateStockErreur
{{ inventoryart.inventory.at }}{{ inventoryart.stock_new }}{{ inventoryart.stock_error }}
+
+ + + + + + + + + + {% for inventoryart in inventoryarts %} + + + + + + {% endfor %} + +
DateStockErreur
+ + {{ inventoryart.inventory.at }} + + {{ inventoryart.stock_new }}{{ inventoryart.stock_error }}
+

Prix fournisseurs

- +
diff --git a/kfet/templates/kfet/base.html b/kfet/templates/kfet/base.html index da37abae..b18ee719 100644 --- a/kfet/templates/kfet/base.html +++ b/kfet/templates/kfet/base.html @@ -1,4 +1,5 @@ {% load staticfiles %} +{% load menu_tags %} @@ -7,9 +8,13 @@ {% block title %}{% endblock %} | K-Fêt - ENS Ulm + + + + {# CSS #} - + @@ -28,18 +33,26 @@ - {% include "kfet/base_nav.html" %} + {% main_menu template="kfet/base_nav.html" %}
{% block header %} -
-
-

{% block header-title %}{% endblock %}

+ {% if not page or not page.no_header %} +
+
+

+ {% block header-title %}{% endblock %} +

+
-
+ {% endif %} {% endblock %} + {% block content %}{% endblock %} - {% include "kfet/base_footer.html" %} + + {% block footer %} + {% endblock footer %}
+
diff --git a/kfet/templates/kfet/base_col_1.html b/kfet/templates/kfet/base_col_1.html index a4c26b82..6bd6dd5c 100644 --- a/kfet/templates/kfet/base_col_1.html +++ b/kfet/templates/kfet/base_col_1.html @@ -1,5 +1,7 @@ {% extends "kfet/base.html" %} +{% block header-class %}text-center{% endblock %} + {% block content %}
@@ -9,6 +11,6 @@ {% block main-content %}{% endblock %}
-
+
{% endblock %} diff --git a/kfet/templates/kfet/base_col_2.html b/kfet/templates/kfet/base_col_2.html index 58c36d14..2a1f8cd4 100644 --- a/kfet/templates/kfet/base_col_2.html +++ b/kfet/templates/kfet/base_col_2.html @@ -3,12 +3,12 @@ {% block content %}
-
+
{% block fixed-content %}{% endblock %}
-
+
{% include "kfet/base_messages.html" %}
{% block main-content %}{% endblock %} diff --git a/kfet/templates/kfet/base_footer.html b/kfet/templates/kfet/base_footer.html index e69de29b..be524139 100644 --- a/kfet/templates/kfet/base_footer.html +++ b/kfet/templates/kfet/base_footer.html @@ -0,0 +1,17 @@ +{% load wagtailcore_tags %} + +{% with "k-fet@ens.fr" as kfet_mail %} + + + +{% endwith %} diff --git a/kfet/templates/kfet/base_messages.html b/kfet/templates/kfet/base_messages.html index 66b67162..5dd68e69 100644 --- a/kfet/templates/kfet/base_messages.html +++ b/kfet/templates/kfet/base_messages.html @@ -1,16 +1,12 @@ {% if messages %} -
+
{% for message in messages %} -
-
- - {% if 'safe' in message.tags %} - {{ message|safe }} - {% else %} - {{ message }} - {% endif %} -
-
+
+ + {{ message }} +
{% endfor %}
{% endif %} diff --git a/kfet/templates/kfet/base_nav.html b/kfet/templates/kfet/base_nav.html index 273cdc0b..629b41da 100644 --- a/kfet/templates/kfet/base_nav.html +++ b/kfet/templates/kfet/base_nav.html @@ -1,70 +1,107 @@ -{% load staticfiles %} +{% load static %} +{% load wagtailcore_tags %} - {% endblock %} +{# Footer #} + {% block footer %} {% include "kfet/base_footer.html" %} {% endblock %} diff --git a/kfet/cms/templates/kfetcms/block_menu.html b/kfet/cms/templates/kfetcms/block_menu.html new file mode 100644 index 00000000..382a7770 --- /dev/null +++ b/kfet/cms/templates/kfetcms/block_menu.html @@ -0,0 +1,11 @@ +{% load static %} + +{% if pressions %} + {% include "kfetcms/block_menu_category.html" with title="Pressions du moment" articles=pressions class="carte-inverted" %} +{% endif %} + +{% regroup articles by category as categories %} + +{% for category in categories %} + {% include "kfetcms/block_menu_category.html" with title=category.grouper.name articles=category.list %} +{% endfor %} diff --git a/kfet/cms/templates/kfetcms/block_menu_category.html b/kfet/cms/templates/kfetcms/block_menu_category.html new file mode 100644 index 00000000..ef7d4ce0 --- /dev/null +++ b/kfet/cms/templates/kfetcms/block_menu_category.html @@ -0,0 +1,12 @@ +
+

{{ title }}

+
    + {% for article in articles %} +
  • +
    + {{ article.name }} + {{ article.price_ukf }} UKF +
  • + {% endfor %} +
+
diff --git a/kfet/cms/templates/kfetcms/equipe.html b/kfet/cms/templates/kfetcms/block_teamgroup.html similarity index 51% rename from kfet/cms/templates/kfetcms/equipe.html rename to kfet/cms/templates/kfetcms/block_teamgroup.html index 2295957f..fab43d68 100644 --- a/kfet/cms/templates/kfetcms/equipe.html +++ b/kfet/cms/templates/kfetcms/block_teamgroup.html @@ -1,27 +1,32 @@ -{% extends "kfetcms/base.html" %} -{% load wagtailcore_tags %} -{% load wagtailimages_tags %} +{% load wagtailcore_tags wagtailimages_tags %} -{% block block1-content %} -{% for group_block in page.team_groups.all %} -

{{ group_block.title }}

-
- {{ group_block.content|richtext }} -
+{% with groupteam=value len=value.members|length %} -{% with members=group_block.group.members.all %} -{% with len=members|length %} - -{% if len > 0 %}
{% if len == 2 %}
{% endif %} - {% for member in members %} -
+ {% for member in groupteam.members %} +
{% image member.photo max-200x500 %}
@@ -35,10 +40,10 @@
{% endfor %} - {% if group_block.show_only != None and len > group_block.show_only %} + {% if groupteam.show_only != None and len > groupteam.show_only %}
-{% endif %} {% endwith %} -{% endwith %} - -{% endfor %} - -{% endblock %} diff --git a/kfet/cms/templates/kfetcms/carte.html b/kfet/cms/templates/kfetcms/carte.html deleted file mode 100644 index 3a32624b..00000000 --- a/kfet/cms/templates/kfetcms/carte.html +++ /dev/null @@ -1,46 +0,0 @@ -{% extends "kfetcms/base.html" %} -{% load static %} -{% load kfet_tags %} - -{% block extra_head %} -{{ block.super }} - -{% endblock %} - -{% block col-size %}column-sm-2 column-md-3{% endblock %} - -{% block block3-content %} - -{% if pressions %} -
-

Pressions du moment

-
    - {% for article in pressions %} -
  • -
    - {{ article.name }} - {{ article.price | ukf:False}} UKF -
  • - {% endfor %} -
-
-{% endif %} - -{% regroup articles by category as categories %} - -{% for category in categories %} -
-

{{ category.grouper.name }}

-
    - {% for article in category.list %} -
  • -
    - {{ article.name }} - {{ article.price | ukf:False}} UKF -
  • - {% endfor %} -
-
-{% endfor %} - -{% endblock %} diff --git a/kfet/forms.py b/kfet/forms.py index 95e97d56..85391992 100644 --- a/kfet/forms.py +++ b/kfet/forms.py @@ -25,18 +25,22 @@ from gestioncof.models import CofProfile # ----- class DateTimeWidget(forms.DateTimeInput): - def __init__(self, attrs = None): - super(DateTimeWidget, self).__init__(attrs) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) self.attrs['format'] = '%Y-%m-%d %H:%M' + class Media: css = { - 'all': ('kfet/css/bootstrap-datetimepicker.min.css',) - } - js = ( - 'kfet/js/moment.js', - 'kfet/js/moment-fr.js', - 'kfet/js/bootstrap-datetimepicker.min.js', - ) + 'all': ('kfet/css/bootstrap-datetimepicker.min.css',) + } + js = ( + 'kfet/js/moment.js', + 'kfet/js/moment-fr.js', + 'kfet/js/moment-timezone-with-data-2010-2020.js', + 'kfet/js/bootstrap-datetimepicker.min.js', + ) + + # ----- # Account forms # ----- @@ -459,8 +463,11 @@ class KFetConfigForm(ConfigForm): class FilterHistoryForm(forms.Form): - checkouts = forms.ModelMultipleChoiceField(queryset = Checkout.objects.all()) - accounts = forms.ModelMultipleChoiceField(queryset = Account.objects.all()) + checkouts = forms.ModelMultipleChoiceField(queryset=Checkout.objects.all()) + accounts = forms.ModelMultipleChoiceField(queryset=Account.objects.all()) + from_date = forms.DateTimeField(widget=DateTimeWidget) + to_date = forms.DateTimeField(widget=DateTimeWidget) + # ----- # Transfer forms diff --git a/kfet/models.py b/kfet/models.py index eb33daf7..162d1e90 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -14,7 +14,8 @@ from datetime import date import re import hashlib -from kfet.config import kfet_config +from .config import kfet_config +from .utils import to_ukf def choices_length(choices): return reduce(lambda m, choice: max(m, len(choice[0])), choices, 0) @@ -102,6 +103,10 @@ class Account(models.Model): return self.cofprofile.is_cof # Propriétés supplémentaires + @property + def balance_ukf(self): + return to_ukf(self.balance, is_cof=self.is_cof) + @property def real_balance(self): if hasattr(self, 'negative') and self.negative.balance_offset: @@ -309,6 +314,10 @@ class AccountNegative(models.Model): ('view_negs', 'Voir la liste des négatifs'), ) + @property + def until_default(self): + return self.start + kfet_config.overdraft_duration + class Checkout(models.Model): created_by = models.ForeignKey( @@ -461,6 +470,10 @@ class Article(models.Model): def get_absolute_url(self): return reverse('kfet.article.read', kwargs={'pk': self.pk}) + def price_ukf(self): + return to_ukf(self.price) + + class ArticleRule(models.Model): article_on = models.OneToOneField( Article, on_delete = models.PROTECT, diff --git a/kfet/signals.py b/kfet/signals.py index 6bbbbbb0..374e0dca 100644 --- a/kfet/signals.py +++ b/kfet/signals.py @@ -4,7 +4,7 @@ from django.contrib import messages from django.contrib.auth.signals import user_logged_in from django.core.urlresolvers import reverse from django.dispatch import receiver -from django.utils.html import mark_safe +from django.utils.safestring import mark_safe @receiver(user_logged_in) diff --git a/kfet/static/kfet/css/base/buttons.css b/kfet/static/kfet/css/base/buttons.css new file mode 100644 index 00000000..e7498022 --- /dev/null +++ b/kfet/static/kfet/css/base/buttons.css @@ -0,0 +1,88 @@ +/* General ------------------------- */ + +.btn { + border: 0; + outline: none !important; + + transition: background-color, border, color, opacity; + transition-duration: 0.15s; + + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + + font-family: "Roboto Slab"; +} + +.btn, .btn-lg, .btn-group-lg>.btn { + border-radius:0; +} + + +/* Default ------------------------- */ + +.btn-default { + background-color: transparent !important; + color: #555; +} + +.btn-default:hover, +.btn-default.focus, .btn-default:focus { + color: #c8102e; +} + +.btn-default[disabled]:hover, .btn-default.disabled:hover { + color: inherit !important; +} + + +/* Primary ------------------------- */ + +.btn-primary { + background-color:#c63b52; + color:#FFF; +} + +.btn-primary:hover, +.btn-primary.focus, .btn-primary:focus, +.btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, +.btn-primary:active.focus, .btn-primary:active:focus, .btn-primary:active:hover { + background-color:#c8102e; + color:#FFF; +} + + +/* Primary + White background ------ */ + +.btn-primary-w { + background: white; + color: black; +} + +.btn-primary-w:hover { + background: #c63b52; + color: white; +} + +.btn-primary-w.focus, .btn-primary-w:focus, +.btn-primary-w.active.focus, .btn-primary-w.active:focus, .btn-primary-w.active:hover, +.btn-primary-w:active.focus, .btn-primary-w:active:focus, .btn-primary-w:active:hover { + background: #c8102e; + color: white; +} + + +/* Nav ----------------------------- */ + +.btn-nav { + background-color: transparent !important; + color: inherit; + border-bottom: 1px solid #ddd; +} + +.btn-nav:hover, +.btn-nav.focus, .btn-nav:focus, +.btn-nav.active.focus, .btn-nav.active:focus, .btn-nav.active:hover, +.btn-nav:active.focus, .btn-nav:active:focus, .btn-nav:active:hover { + border-bottom: 1px solid #c8102e; +} diff --git a/kfet/static/kfet/css/base/fixed.css b/kfet/static/kfet/css/base/fixed.css new file mode 100644 index 00000000..d198c50f --- /dev/null +++ b/kfet/static/kfet/css/base/fixed.css @@ -0,0 +1,151 @@ +.fixed > * + * { + margin-top: 15px; +} + + +/* Aside --------------------------- */ + +/* Aside - Block */ + +aside { + background: white; + padding: 15px; +} + +aside > * + * { + margin-top: 15px; +} + +/* Aside - Misc */ + +aside .glyphicon-question-sign { + font-size: 0.8; +} + +aside h4 { + font-weight: bold; +} + +/* Aside - Heading */ + +aside .heading { + font-family: "Roboto Slab"; + font-size: 25px; + font-weight: bold; + line-height: 1.1; + text-align: center; +} + +aside .heading .big { + font-size: 2em; +} + +aside .heading .sub { + font-size: 0.7em; + font-weight: normal; +} + +@media (min-width: 992px) { + aside .heading { + font-size: 32px; + line-height: 1.3; + } +} + +/* Aside - Buttons */ + +aside .buttons { + margin-left: -15px; + margin-right: -15px; +} + +aside .buttons > * { + flex: 0 1 auto !important; +} + + +/* Aside - Text */ + +aside .text { + line-height: 1.3; + font-size: 14px; +} + +@media (min-width: 992px) { + aside .text { + line-height: 1.6; + font-size: 16px; + } +} + +aside .text ul { + margin-bottom: 0; +} + + +/* Buttons ------------------------- */ + +.fixed .buttons { + display: flex; + flex-flow: row wrap; + justify-content: center; + + text-align: center; +} + +.fixed .buttons > * { + flex: 0 1 auto; + overflow: hidden; +} + +.fixed .buttons > .solo { + flex: 1 100%; +} + +@media (min-width: 768px) { + .fixed .buttons > * { + flex: 1 auto; + } + + .fixed .buttons > .full > * { + width: 100%; + } +} + +.fixed .buttons .btn { + padding: 8px 12px; +} + +@media (min-width: 992px) { + .fixed .buttons .btn { + font-size: 16px; + } +} + + +/* Tabs ---------------------------- */ + +.fixed .tabs-buttons { + margin-bottom: -5px; +} + +.fixed .tabs-buttons > * { + margin-bottom: 5px; +} + +.fixed .tabs-buttons .glyphicon-chevron-right { + margin-left: 5px; + line-height: 1.4; + color: white; +} + +@media (min-width: 768px) { + .fixed .tabs-buttons { + text-align: right; + justify-content: flex-end; + } + + .fixed .tabs-buttons > * { + flex: 1 100%; + } +} diff --git a/kfet/static/kfet/css/footer.css b/kfet/static/kfet/css/base/footer.css similarity index 85% rename from kfet/static/kfet/css/footer.css rename to kfet/static/kfet/css/base/footer.css index 5e8d1474..abdf98ed 100644 --- a/kfet/static/kfet/css/footer.css +++ b/kfet/static/kfet/css/base/footer.css @@ -10,10 +10,9 @@ } .footer a { - color: inherit; + color: inherit !important; } .footer a:hover, .footer a:focus { - color: inherit; text-decoration: underline; } diff --git a/kfet/static/kfet/css/base/main.css b/kfet/static/kfet/css/base/main.css new file mode 100644 index 00000000..2ebc90d8 --- /dev/null +++ b/kfet/static/kfet/css/base/main.css @@ -0,0 +1,138 @@ +/* Global layout ------------------- */ + +.main-col, .fixed-col { + padding: 0 0 15px; +} + +@media (min-width: 768px) { + .fixed-col { + position: sticky; + top: 35px; + padding-top: 15px; + } + + .fixed-col + .main-col { + padding: 15px 0 15px 15px; + } +} + +@media (min-width: 992px) { + .main-col { + padding: 15px; + } +} + +.main-col-mult { + column-gap: 45px; +} + +.main-bg { + background: white; +} + +.main-padding { + padding: 15px; +} + +@media (min-width: 768px) { + .main-padding { + padding: 30px; + } +} + + +/* Section ------------------------- */ + +section { + margin-bottom: 15px; + position:relative; +} + +section:last-child { + margin-bottom: 0; +} + + +/* Section - Elements -------------- */ + +section > * { + background: white; + padding: 15px; +} + +section > .full, +section > table, +section > .table-responsive { + padding: 0 !important; + margin-left: 0 !important; + margin-right: 0 !important; +} + +section .full { + margin-left: -15px; + margin-right: -15px; +} + +@media (min-width: 992px) { + section > * { + padding: 30px; + } + + section .full { + margin-left: -30px; + margin-right: -30px; + } +} + +section .row > div:last-child { + margin-bottom: 0 !important; +} + +@media (max-width: 768px) { + section .row > div { + margin-bottom: 10px; + } +} + +@media (max-width: 1200px) { + section .row > div { + margin-bottom: 20px; + } +} + +section ul ul { + padding-left: 30px; +} + +/* Titles & Heading */ + +section h2, +section .heading { + background: transparent; + margin: 20px 15px 15px; + padding: 0; + border-bottom: 3px solid #c8102e; + font-family: "Roboto Slab"; + font-size: 40px; + line-height: 1.1; +} + +section h3 { + border-bottom: 2px solid #c8102e; + margin: 0 0 10px; + padding: 10px 0 10px; + font-size: 25px; + font-weight: bold; +} + +section .heading .buttons { + opacity: 0.7; + top: 10px; + float: right; +} + +section h2:first-child, +section h3:first-child { + padding-top: 0; + margin-top: 0; +} diff --git a/kfet/static/kfet/css/base/messages.css b/kfet/static/kfet/css/base/messages.css new file mode 100644 index 00000000..268f514d --- /dev/null +++ b/kfet/static/kfet/css/base/messages.css @@ -0,0 +1,36 @@ +.messages .alert { + padding:10px 15px; + margin:0; + border:0; + border-radius:0; +} + +.messages .alert:last-child { + margin-bottom: 15px; +} + +.messages .alert .close { + top:0; + right:0; +} + +.messages .alert-info { + color:inherit; + background-color:#ccc; +} + +.messages .alert-error { + color: white; + background-color: #c63b52; +} + +.messages .alert-success { + color: white; + background: #3d9947; +} + +.messages a { + font-weight: bold; + text-decoration: none; +} + diff --git a/kfet/static/kfet/css/base/misc.css b/kfet/static/kfet/css/base/misc.css new file mode 100644 index 00000000..9b09edae --- /dev/null +++ b/kfet/static/kfet/css/base/misc.css @@ -0,0 +1,107 @@ +/* General ------------------------- */ + +body { + margin-top:50px; + font-family:Roboto; + background:#ddd; +} + +.glyphicon + span, span + .glyphicon { + margin-left: 10px; +} + +/* Titles */ + +h1,h2,h3,h4,h5,h6 { + font-family:"Roboto Slab"; +} + +/* Links */ + +a { + color:#C8202E; +} + +a:focus, a:hover { + color:#C8102E; +} + +/* Inputs */ + +:focus { + outline:none; +} + +textarea { + font-family:'Roboto Mono'; + border-radius:0 !important; +} + +/* Lists */ + +ul, ol { + padding-left: 30px; +} + +ul { + list-style-type: square; +} + +/* Tables */ + +.table { + margin-bottom:0; + border-bottom:1px solid #ddd; + width:100%; + background-color: #FFF; +} + +.table td { + vertical-align:middle !important; +} + +.table td.no-padding { + padding:0; +} + +.table thead { + background:#c8102e; + color:#fff; + font-weight:bold; + font-size:16px; +} + +.table thead td { + padding:8px !important; +} + +.table tr.section { + background: #c63b52 !important; + color:#fff; + font-weight:bold; +} + +.table tr.section td { + border-top:0; + font-size:16px; + padding:8px 30px; +} + +.table tr.more td { + padding: 0; +} + +.table-responsive { + border: 0; + margin-bottom: 0; +} + +/* Toggle on hover ----------------- */ + +.toggle:not(:hover) .hover { + display: none; +} + +.toggle:hover .base { + display: none; +} diff --git a/kfet/static/kfet/css/nav.css b/kfet/static/kfet/css/base/nav.css similarity index 100% rename from kfet/static/kfet/css/nav.css rename to kfet/static/kfet/css/base/nav.css diff --git a/kfet/static/kfet/css/index.css b/kfet/static/kfet/css/index.css index 04fbaeb1..8e28cce0 100644 --- a/kfet/static/kfet/css/index.css +++ b/kfet/static/kfet/css/index.css @@ -1,306 +1,64 @@ -@import url("nav.css"); -@import url("footer.css"); +/* Libs */ +@import url("libs/columns.css"); + +/* Libs customizations */ +@import url("libs/jconfirm-kfet.css"); +@import url("libs/multiple-select-kfet.css"); + +/* Base */ +@import url("base/misc.css"); +@import url("base/buttons.css"); + +/* Blocks */ +@import url("base/main.css"); +@import url("base/nav.css"); +@import url("base/messages.css"); +@import url("base/fixed.css"); +@import url("base/footer.css"); + +/* Components */ @import url("kpsul.css"); -@import url("jconfirm-kfet.css"); @import url("history.css"); -body { - margin-top:50px; - font-family:Roboto; - background:#ddd; + + +.header { + padding: 15px 20px; + + background-color: rgba(200,16,46,1); + color: #FFF; } -h1,h2,h3,h4,h5,h6 { - font-family:"Roboto Slab"; -} - -a { - color:#C8202E; -} - -a:focus, a:hover { - color:#C8102E; -} - -:focus { - outline:none; -} - -textarea { - font-family:'Roboto Mono'; - border-radius:0 !important; -} - -.glyphicon + span, span + .glyphicon { - margin-left: 10px; -} - -.table { - margin-bottom:0; - border-bottom:1px solid #ddd; - width:100%; - background-color: #FFF; -} - -.table td { - vertical-align:middle !important; -} - -.table td.no-padding { - padding:0; -} - -.table thead { - background:#c8102e; - color:#fff; - font-weight:bold; - font-size:16px; -} - -.table thead td { - padding:8px !important; -} - -.table tr.section { - background:#c8102e; - color:#fff; - font-weight:bold; -} - -.table tr.section td { - border-top:0; - font-size:16px; - padding:8px 30px; -} - -.table-hover > tbody > tr.section:hover { - background:#c8102e; -} - -.table-responsive { - border: 0; - margin-bottom: 0; -} - -.btn { - border: 0; - - transition: background-color, color; - transition-duration: 0.15s; - - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - - font-family: "Roboto Slab"; -} - -.btn, .btn-lg, .btn-group-lg>.btn { - border-radius:0; -} - -.btn-primary { - background-color:#c63b52; - color:#FFF; - border:0; -} - -.btn-primary:hover, -.btn-primary.focus, .btn-primary:focus, -.btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, -.btn-primary:active.focus, .btn-primary:active:focus, .btn-primary:active:hover, -.nav-pills>li.active>a, .nav-pills>li.active>a:focus, .nav-pills>li.active>a:hover { - outline: 0; - background-color:#bf0f2c; - background-color:#c8102e; - color:#FFF; -} - -.btn-primary[disabled]:hover, -.btn-primary[disabled]:focus { - background-color: #000; - color: #666; -} - -.nav-pills>li>a { - border-radius:0; -} - -.nav-pills>li>a:focus, .nav-pills>li>a:hover { - outline: 0; - background-color:rgba(200,16,46,1); - color:#FFF; -} - -.header-row { - background-color:rgba(200,16,46,1); - color:#FFF; -} - -.page-header { - border:0; - padding:0; - margin:15px 20px; - font-weight:bold; +.header h1 { + padding: 0; + margin: 0; + font-weight: bold; } .nopadding { padding: 0 !important; } -.col-content-left, .col-content-right { - padding:0; -} - - -@media (min-width: 768px) { - .col-content-left { - position: sticky; - top:50px; - margin-bottom: 15px; - } -} - -.content-left-top { - background:#fff; - padding:15px; -} - -@media (min-width: 1200px) { - .content-left-top { - padding: 30px; - } -} - -.content-left .btn-lg { - font-size: 16px; -} - -.btn-actions { - margin: 0 -15px; -} - -.btn-actions .btn { - color: inherit; -} - -.btn-actions .btn:not([disabled]):hover, .btn-actions .btn:not([disabled]):focus { - color: #c8102e; -} - -.content-left-top.frozen-account { +.frozen-account { background:#5072e0; color:#fff; } -.content-left .block { - padding-top:15px; + +.main .table a:not(.btn) { + color: inherit; } -.content-left .block .line { - font-size:16px; - line-height:30px; +.main .table a:not(.btn):focus , +.main .table a:not(.btn):hover { + color: #C81022; } -.content-left .line.line-big { - font-family:"Roboto Slab"; - font-size:60px; - font-weight:bold; - text-align:center; - overflow:hidden; -} - -.content-left .line.line-bigsub { - font-size:25px; - font-weight:bold; - text-align:center; -} - -.content-left .line.balance { - font-size:45px; - text-align:center; -} - -@media (min-width: 1200px) { - .content-left .line.line-big { - margin-top: -15px; - } -} - -@media (min-width: 768px) { - .content-right { - margin: 15px; - } -} - -.content-right-block { - margin-top: 15px; - position:relative; -} - -.content-right-block > *:not(.buttons-title) { - background: #fff; -} - -.content-right-block > h2 { - background: transparent !important; -} - -.content-right-block .buttons-title { - position:absolute; - top:8px; - right:20px; -} - -.content-right-block > div.row { - margin:0; -} - -.content-right-block h2 { - margin:20px 20px 15px; - padding-bottom:5px; - border-bottom:3px solid #c8102e; - font-size:40px; -} - -.content-right-block h3 { - border-bottom: 1px solid #c8102e; - margin: 0px 15px 15px; - padding: 20px 20px 10px; - font-size:25px; -} - -.content-right-block a:not(.btn) { - color:#000; -} - -.content-right-block a:not(.btn):focus , -.content-right-block a:not(.btn):hover { - color:#C81022; -} /* * Pages tableaux seuls */ -.content-center > *:not(.content-right-block) { - background: #fff; -} - -@media (min-width: 992px) { - .content-center { - margin: 15px 0; - } - - .column-row { - margin-top: 15px; - margin-bottom: 15px; - } -} - -.content-center tbody tr:not(.section) td { - padding:0px 5px; -} .table .form-control { padding: 1px 12px ; @@ -313,6 +71,10 @@ textarea { background: #f5f5f5; } +.table-condensed-input tbody tr:not(.section) td { + padding:0px 5px; +} + .table-condensed input.form-control { margin: 0 !important; border-top: 0; @@ -320,19 +82,34 @@ textarea { border-radius: 0; } -.content-center .auth-form { - margin:15px; +.auth-form { + padding: 15px 0; + background: #d86c7e; + color: white; +} + +.auth-form.form-horizontal { + padding: 0; + margin: 0; +} + +.auth-form .form-group { + margin-bottom: 0; +} + +.auth-form input { + box-shadow: none !important; + background: transparent; + color: white; + border: 0 !important; + border-radius: 0; + border-bottom: 1px solid white !important; } /* * Pages formulaires seuls */ -.content-form { - background-color: #fff; - padding: 15px; -} - .account_create #id_trigramme { display:block; width:200px; @@ -395,40 +172,48 @@ textarea { padding:5px 20px; } -/* - * Messages +/* Account autocomplete window */ + +#account_results ul { + list-style-type:none; + background:rgba(255,255,255,0.9); + padding:0; +} + +#account_results li { + display:block; + padding:5px 20px; + height:100%; + width:100%; +} + +#account_results .hilight { + background:rgba(200,16,46,0.9); + color:#fff; + text-decoration:none; +} + +/** + * Stats (graphs) */ -.messages .alert { - padding:10px 15px; - margin:0; - border:0; - border-radius:0; +.stat-nav { + margin-bottom: 10px; + font-family: Roboto; } -.messages .alert .close { - top:0; - right:0; +.stat-nav li { + float: left; } -.messages .alert-info { - color:inherit; - background-color:#ccc; +.stat-nav a { + opacity: 0.6; + font-family: Roboto; } -.messages .alert-error { - color: white; - background-color: #c63b52; -} - -.messages .alert-success { - color: white; - background: #3d9947; -} - -.messages a { - font-weight: bold; - text-decoration: none; +.stat-nav a:hover, +.stat-nav a.focus, .stat-nav a:focus { + opacity: 1; } /* @@ -488,57 +273,10 @@ thead .tooltip { height: 100px; } -/* - * Responsive Columns - */ - -.unbreakable { - display:inline-block; - width: 100%; -} - -.column-xs-1, .column-sm-1, .column-md-1, .column-lg-1, -.column-xs-2, .column-sm-2, .column-md-2, .column-lg-2, -.column-xs-3, .column-sm-3, .column-md-3, .column-lg-3, -.column-xs-4, .column-sm-4, .column-md-4, .column-lg-4, -.column-xs-5, .column-sm-5, .column-md-5, .column-lg-5 { - column-count: 1; - column-gap: 0; -} - -.column-xs-1 { column-count: 1; } -.column-xs-2 { column-count: 2; } -.column-xs-3 { column-count: 3; } -.column-xs-4 { column-count: 4; } -.column-xs-5 { column-count: 5; } - -@media (min-width: 768px) { - .column-sm-1 { column-count: 1; } - .column-sm-2 { column-count: 2; } - .column-sm-3 { column-count: 3; } - .column-sm-4 { column-count: 4; } - .column-sm-5 { column-count: 5; } -} - -@media (min-width: 992px) { - .column-md-1 { column-count: 1; } - .column-md-2 { column-count: 2; } - .column-md-3 { column-count: 3; } - .column-md-4 { column-count: 4; } - .column-md-5 { column-count: 5; } -} - -@media (min-width: 1200px) { - .column-lg-1 { column-count: 1; } - .column-lg-2 { column-count: 2; } - .column-lg-3 { column-count: 3; } - .column-lg-4 { column-count: 4; } - .column-lg-5 { column-count: 5; } -} /* Inventaires */ -#inventoryform input[type=number] { +.table-condensed-input input[type=number] { text-align: center; } @@ -557,18 +295,6 @@ thead .tooltip { margin: 0 auto; } -/* Multiple select customizations */ - -.ms-choice { - height: 34px !important; - line-height: 34px !important; - border: 1px solid #ccc !important; - box-shadow: inset 0 1px 1px rgba(0,0,0,.075) !important; -} - -.ms-choice > div { - top: 4px !important; -} /* Checkbox select multiple */ diff --git a/kfet/static/kfet/css/libs/columns.css b/kfet/static/kfet/css/libs/columns.css new file mode 100644 index 00000000..34591061 --- /dev/null +++ b/kfet/static/kfet/css/libs/columns.css @@ -0,0 +1,43 @@ +.unbreakable { + display:inline-block; + width: 100%; +} + +.column-xs-1, .column-sm-1, .column-md-1, .column-lg-1, +.column-xs-2, .column-sm-2, .column-md-2, .column-lg-2, +.column-xs-3, .column-sm-3, .column-md-3, .column-lg-3, +.column-xs-4, .column-sm-4, .column-md-4, .column-lg-4, +.column-xs-5, .column-sm-5, .column-md-5, .column-lg-5 { + column-count: 1; +} + +.column-xs-1 { column-count: 1; } +.column-xs-2 { column-count: 2; } +.column-xs-3 { column-count: 3; } +.column-xs-4 { column-count: 4; } +.column-xs-5 { column-count: 5; } + +@media (min-width: 768px) { + .column-sm-1 { column-count: 1; } + .column-sm-2 { column-count: 2; } + .column-sm-3 { column-count: 3; } + .column-sm-4 { column-count: 4; } + .column-sm-5 { column-count: 5; } +} + +@media (min-width: 992px) { + .column-md-1 { column-count: 1; } + .column-md-2 { column-count: 2; } + .column-md-3 { column-count: 3; } + .column-md-4 { column-count: 4; } + .column-md-5 { column-count: 5; } +} + +@media (min-width: 1200px) { + .column-lg-1 { column-count: 1; } + .column-lg-2 { column-count: 2; } + .column-lg-3 { column-count: 3; } + .column-lg-4 { column-count: 4; } + .column-lg-5 { column-count: 5; } +} + diff --git a/kfet/static/kfet/css/jconfirm-kfet.css b/kfet/static/kfet/css/libs/jconfirm-kfet.css similarity index 81% rename from kfet/static/kfet/css/jconfirm-kfet.css rename to kfet/static/kfet/css/libs/jconfirm-kfet.css index 1e05a816..d2803434 100644 --- a/kfet/static/kfet/css/jconfirm-kfet.css +++ b/kfet/static/kfet/css/libs/jconfirm-kfet.css @@ -49,7 +49,7 @@ } .jconfirm .jconfirm-box .buttons button { - width:40px; + min-width:40px; height:100%; margin:0; margin:0 !important; @@ -85,24 +85,3 @@ padding-right: 50px; padding-left: 50px; } - -/* Account autocomplete window */ - -#account_results ul { - list-style-type:none; - background:rgba(255,255,255,0.9); - padding:0; -} - -#account_results li { - display:block; - padding:5px 20px; - height:100%; - width:100%; -} - -#account_results .hilight { - background:rgba(200,16,46,0.9); - color:#fff; - text-decoration:none; -} diff --git a/kfet/static/kfet/css/libs/multiple-select-kfet.css b/kfet/static/kfet/css/libs/multiple-select-kfet.css new file mode 100644 index 00000000..145968d3 --- /dev/null +++ b/kfet/static/kfet/css/libs/multiple-select-kfet.css @@ -0,0 +1,14 @@ +/** + * Multiple Select plugin customizations + */ + +.ms-choice { + height: 34px !important; + line-height: 34px !important; + border: 1px solid #ccc !important; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075) !important; +} + +.ms-choice > div { + top: 4px !important; +} diff --git a/kfet/static/kfet/js/kfet.js b/kfet/static/kfet/js/kfet.js index 72ae675a..c977d534 100644 --- a/kfet/static/kfet/js/kfet.js +++ b/kfet/static/kfet/js/kfet.js @@ -30,7 +30,7 @@ class KfetWebsocket { constructor(data) { $.extend(this, this.constructor.defaults, data); } - + get url() { var websocket_protocol = window.location.protocol == 'https:' ? 'wss' : 'ws'; var location_host = window.location.host; @@ -184,3 +184,13 @@ function requestAuth(data, callback, focus_next = null) { }); } + + +/** + * Setup jquery-confirm + */ + +jconfirm.defaults = { + confirmButton: '', + cancelButton: '' +}; diff --git a/kfet/static/kfet/js/statistic.js b/kfet/static/kfet/js/statistic.js index d185b604..9baa08c4 100644 --- a/kfet/static/kfet/js/statistic.js +++ b/kfet/static/kfet/js/statistic.js @@ -7,7 +7,7 @@ var self = this; var element = $(target); - var content = $("
"); + var content = $("
"); var buttons; function dictToArray (dict, start) { @@ -153,9 +153,8 @@ // initialize the interface function initialize (data) { // creates the bar with the buttons - buttons = $("
", - {class: "btn-group btn-group-justified", - role: "group", + buttons = $("
Date
@@ -68,6 +66,6 @@
-
+ {% endblock %} diff --git a/kfet/templates/kfet/account_create.html b/kfet/templates/kfet/account_create.html index b9e050b4..59fc1d56 100644 --- a/kfet/templates/kfet/account_create.html +++ b/kfet/templates/kfet/account_create.html @@ -1,4 +1,4 @@ -{% extends "kfet/base_col_1.html" %} +{% extends "kfet/base_form.html" %} {% load staticfiles %} {% block title %}Nouveau compte{% endblock %} @@ -8,9 +8,7 @@ {% endblock %} -{% block main-class %}content-form{% endblock %} - -{% block main-content %} +{% block main %}
-

Les mots contenant des caractères non alphanumériques seront ignorés

@@ -62,7 +59,6 @@ // et de ladisponibilité du trigramme choisi $('#id_trigramme').on('input', function() { var trigramme = $('#id_trigramme').val().toUpperCase(); - var container = '#trigramme_valid'; var pattern = /^[^a-z]{3}$/; if (!(trigramme.match(pattern))) { diff --git a/kfet/templates/kfet/account_create_special.html b/kfet/templates/kfet/account_create_special.html index e7a14f87..ecd6ac22 100644 --- a/kfet/templates/kfet/account_create_special.html +++ b/kfet/templates/kfet/account_create_special.html @@ -10,7 +10,7 @@ {% block main-class %}content-form{% endblock %} -{% block main-content %} +{% block main %} {% csrf_token %} diff --git a/kfet/templates/kfet/account_group.html b/kfet/templates/kfet/account_group.html index e7243258..6663bc0e 100644 --- a/kfet/templates/kfet/account_group.html +++ b/kfet/templates/kfet/account_group.html @@ -3,53 +3,59 @@ {% block title %}Groupes de comptes{% endblock %} {% block header-title %}Groupes de comptes{% endblock %} -{% block fixed-content %} +{% block fixed %} -
- Créer un groupe + {% endblock %} -{% block main-content %} +{% block main %} {% for group in groups %} -
-
- - - +
+
+ {{ group.name }} +
-

{{ group.name }}

-
-
-

Permissions

+
+

Comptes

+
+ +
+

Permissions

+
{% regroup group.permissions.all by content_type as grouped_perms %}
    {% for perms_group in grouped_perms %} -
  • {{ perms_group.grouper|title }} -
      - {% for perm in perms_group.list %} -
    • {{ perm.name }}
    • - {% endfor %} +
    • + {{ perms_group.grouper|title }} +
        + {% for perm in perms_group.list %} +
      • {{ perm.name }}
      • + {% endfor %}
      - {% endfor %} -
    -
-
-

Comptes

-
-
+
{% endfor %} {% endblock %} diff --git a/kfet/templates/kfet/account_group_form.html b/kfet/templates/kfet/account_group_form.html index 45c3ac5b..90e3aa36 100644 --- a/kfet/templates/kfet/account_group_form.html +++ b/kfet/templates/kfet/account_group_form.html @@ -1,4 +1,4 @@ -{% extends 'kfet/base_col_1.html' %} +{% extends 'kfet/base_form.html' %} {% load staticfiles %} {% load widget_tweaks %} @@ -10,9 +10,7 @@ {% block title %}Permissions - Édition{% endblock %} {% block header-title %}Modification des permissions{% endblock %} -{% block main-class %}content-form{% endblock %} - -{% block main-content %} +{% block main %} {% csrf_token %} @@ -23,8 +21,12 @@ K-Fêt {{ form.name|add_class:"form-control" }}
- {% if form.name.errors %}{{ form.name.errors }}{% endif %} - {% if form.name.help_text %}{{ form.name.help_text }}{% endif %} + {% if form.name.errors %} + {{ form.name.errors }} + {% endif %} + {% if form.name.help_text %} + {{ form.name.help_text }} + {% endif %}
{% include "kfet/form_field_snippet.html" with field=form.permissions %} diff --git a/kfet/templates/kfet/account_negative.html b/kfet/templates/kfet/account_negative.html index 741ad9dd..066cb832 100644 --- a/kfet/templates/kfet/account_negative.html +++ b/kfet/templates/kfet/account_negative.html @@ -1,72 +1,76 @@ {% extends "kfet/base_col_2.html" %} {% block title %}Comptes - Négatifs{% endblock %} -{% block header-title %}Comptes en négatifs{% endblock %} +{% block header-title %}Comptes en négatif{% endblock %} -{% block fixed-content %} +{% block fixed %} -
-
{{ negatives|length }}
-
compte{{ negatives|length|pluralize }} en négatif
-
-
Total: {{ negatives_sum|floatformat:2 }}€
+ + {% if perms.kfet.change_settings %} -
- Modifier les valeurs par défaut +
+
+
{% endif %} {% endblock %} -{% block main-content %} +{% block main %} -
-

Liste des comptes en négatifs

-
- - - - - - - - - - - - - - - {% for neg in negatives %} - - - - - - - - - - - {% endfor %} - -
Tri.NomBalanceRéelleDébutDécouvert autoriséJusqu'auBalance offset
- - {{ neg.account.trigramme }} - - {{ neg.account.name }}{{ neg.account.balance|floatformat:2 }}€ - {% if neg.balance_offset %} - {{ neg.account.real_balance|floatformat:2 }}€ - {% endif %} - {{ neg.start|date:'d/m/Y H:i:s'}}{{ neg.authz_overdraft_amount|default_if_none:'' }}{{ neg.authz_overdrafy_until|default_if_none:'' }}{{ neg.balance_offset|default_if_none:'' }}
-
+
+ + + + + + + + + + + + + + + {% for neg in negatives %} + + + + + + + + + + + {% endfor %} + +
Tri.NomBalanceRéelleDébutDécouvert autoriséJusqu'auBalance offset
+ + {{ neg.account.trigramme }} + + {{ neg.account.name }}{{ neg.account.balance|floatformat:2 }}€ + {% if neg.balance_offset %} + {{ neg.account.real_balance|floatformat:2 }}€ + {% endif %} + {{ neg.start|date:'d/m/Y H:i:s'}}{{ neg.authz_overdraft_amount|default_if_none:'' }}{{ neg.authz_overdrafy_until|default_if_none:'' }}{{ neg.balance_offset|default_if_none:'' }}
{% endblock %} diff --git a/kfet/templates/kfet/account_read.html b/kfet/templates/kfet/account_read.html index fc8babc5..15238b64 100644 --- a/kfet/templates/kfet/account_read.html +++ b/kfet/templates/kfet/account_read.html @@ -48,38 +48,43 @@ $(document).ready(function() { {% include "kfet/base_footer.html" %} {% endblock %} -{% block fixed-content %} +{% block fixed %} {% include "kfet/left_account.html" %} {% endblock %} -{% block main-content %} +{% block main %}
+ {% if account.user == request.user %} -
-

Statistiques

-
-

Ma balance

-
-

Ma consommation

-
-
-
+
+
+
+

Ma balance

+
+

Ma consommation

+
+
+
+
{% endif %} -
- {% if addcosts %} -

Gagné des majorations

-
-
    - {% for addcost in addcosts %} -
  • {{ addcost.date|date:'l j F' }}: +{{ addcost.sum_addcosts }}€
  • - {% endfor %} -
-
- {% endif %} -

Historique

-
-
+ +
+
+ {% if addcosts %} +

Gagné des majorations

+
+
    + {% for addcost in addcosts %} +
  • {{ addcost.date|date:'l j F' }}: +{{ addcost.sum_addcosts }}€
  • + {% endfor %} +
+
+ {% endif %} +
+
+
+
@@ -9,96 +9,104 @@ {% block title %}Article - {{ article.name }}{% endblock %} {% block header-title %}Informations sur l'article {{ article.name }}{% endblock %} -{% block fixed-content %} +{% block fixed %} -
-
{{ article.name }}
-
{{ article.category }}
-
- + + + {% endblock %} -{% block main-content %} +{% block main %} -
-

Historique

-
-
-

Inventaires

-
- - - - - - - - - - {% for inventoryart in inventoryarts %} - - - - - - {% endfor %} - -
DateStockErreur
- - {{ inventoryart.inventory.at }} - - {{ inventoryart.stock_new }}{{ inventoryart.stock_error }}
-
-
-
-

Prix fournisseurs

-
- - - - - - - - - - - - {% for supplierart in supplierarts %} - - - - - - - - {% endfor %} - -
DateFournisseurHTTVADroits
{{ supplierart.at }}{{ supplierart.supplier.name }}{{ supplierart.price_HT }}{{ supplierart.TVA }}{{ supplierart.rights }}
-
-
-
-
-
-

Statistiques

+
+ +
+ +
+
+
+
+ +

Inventaires récents

+
+ {% include "kfet/article_inventories_snippet.html" with inventoryarts=inventoryarts|slice:5 %} +
+ +
+
+ +

Derniers prix fournisseurs

+
+ {% include "kfet/article_suppliers_snippet.html" with supplierarts=supplierarts|slice:5 %} +
+ +
+
+
+
+ +

Ventes

+
+ +
+ +
+
+ {% include "kfet/article_inventories_snippet.html" %} +
+
+ +
+
+ {% include "kfet/article_suppliers_snippet.html" %} +
+
+
diff --git a/kfet/templates/kfet/article_suppliers_snippet.html b/kfet/templates/kfet/article_suppliers_snippet.html new file mode 100644 index 00000000..bd5970fd --- /dev/null +++ b/kfet/templates/kfet/article_suppliers_snippet.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + {% for supplierart in supplierarts %} + + + + + + + + {% endfor %} + +
DateFournisseurHTTVADroits
{{ supplierart.at }}{{ supplierart.supplier.name }}{{ supplierart.price_HT|default_if_none:"" }}{{ supplierart.TVA|default_if_none:"" }}{{ supplierart.rights|default_if_none:"" }}
diff --git a/kfet/templates/kfet/article_update.html b/kfet/templates/kfet/article_update.html index d451df94..3f09e48e 100644 --- a/kfet/templates/kfet/article_update.html +++ b/kfet/templates/kfet/article_update.html @@ -1,12 +1,10 @@ -{% extends "kfet/base_col_1.html" %} +{% extends "kfet/base_form.html" %} {% block title %}{{ article.name }} - Édition{% endblock %} {% block header-title %}Édition de l'article {{ article.name }}{% endblock %} -{% block main-class %}content-form{% endblock %} +{% block main %} -{% block main-content %} - -{% include "kfet/base_form.html" with authz=perms.kfet.change_article submit_text="Mettre à jour"%} +{% include "kfet/form_full_snippet.html" with authz=perms.kfet.change_article submit_text="Mettre à jour"%} {% endblock %} diff --git a/kfet/templates/kfet/base.html b/kfet/templates/kfet/base.html index b18ee719..ecd69c3d 100644 --- a/kfet/templates/kfet/base.html +++ b/kfet/templates/kfet/base.html @@ -1,5 +1,4 @@ -{% load staticfiles %} -{% load menu_tags %} +{% load static menu_tags %} @@ -33,17 +32,17 @@ - {% main_menu template="kfet/base_nav.html" %} + {% flat_menu "kfet-nav" template="kfet/base_nav.html" apply_active_classes=True %}
{% block header %} {% if not page or not page.no_header %} -
-
-

+
+
+

{% block header-title %}{% endblock %}

-

+ {% endif %} {% endblock %} diff --git a/kfet/templates/kfet/base_col_1.html b/kfet/templates/kfet/base_col_1.html index 6bd6dd5c..03fea5e7 100644 --- a/kfet/templates/kfet/base_col_1.html +++ b/kfet/templates/kfet/base_col_1.html @@ -4,11 +4,11 @@ {% block content %} -
-
+
+
{% include "kfet/base_messages.html" %} -
- {% block main-content %}{% endblock %} +
+ {% block main %}{% endblock %}
diff --git a/kfet/templates/kfet/base_col_2.html b/kfet/templates/kfet/base_col_2.html index 2a1f8cd4..d0ac45b7 100644 --- a/kfet/templates/kfet/base_col_2.html +++ b/kfet/templates/kfet/base_col_2.html @@ -2,16 +2,16 @@ {% block content %} -
-
-
- {% block fixed-content %}{% endblock %} +
+
+
+ {% block fixed %}{% endblock %}
-
+
{% include "kfet/base_messages.html" %} -
- {% block main-content %}{% endblock %} +
+ {% block main %}{% endblock %}
diff --git a/kfet/templates/kfet/base_col_mult.html b/kfet/templates/kfet/base_col_mult.html new file mode 100644 index 00000000..e5bafc19 --- /dev/null +++ b/kfet/templates/kfet/base_col_mult.html @@ -0,0 +1,18 @@ +{% extends "kfet/base.html" %} + +{% block header-class %}text-center{% endblock %} + +{% block content %} + +
+
+ {% include "kfet/base_messages.html" %} +
+
+ {% block main %}{% endblock %} +
+
+
+
+ +{% endblock %} diff --git a/kfet/templates/kfet/base_footer.html b/kfet/templates/kfet/base_footer.html index be524139..c5333476 100644 --- a/kfet/templates/kfet/base_footer.html +++ b/kfet/templates/kfet/base_footer.html @@ -2,7 +2,7 @@ {% with "k-fet@ens.fr" as kfet_mail %} -