From e455859e13c0c26a9e0f992932dfb8c03aeae703 Mon Sep 17 00:00:00 2001 From: Nanoy Date: Tue, 19 Feb 2019 08:26:54 +0100 Subject: [PATCH 1/6] Vue verify --- preferences/views.py | 2 +- users/models.py | 10 +++++++++- users/urls.py | 1 + users/views.py | 22 +++++++++++++++++++--- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/preferences/views.py b/preferences/views.py index e5a3f7a..5fd61a5 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -263,7 +263,7 @@ def get_config(request): """ Load the config and return it in a json format """ - gp,_ = GeneralPreferences.objects.get_or_create(pk=1) + gp,_ = GeneralPreferences.objects.get_or_create(pk=1).defer("statutes", "rules", "menu") data = json.dumps(model_to_dict(gp)) return HttpResponse(data, content_type='application/json') \ No newline at end of file diff --git a/users/models.py b/users/models.py index b586df7..2ae5c2c 100644 --- a/users/models.py +++ b/users/models.py @@ -75,14 +75,22 @@ class Profile(models.Model): debit = models.DecimalField(max_digits=7, decimal_places=2, default=0) school = models.ForeignKey(School, on_delete=models.PROTECT, blank=True, null=True) cotisationEnd = models.DateTimeField(blank=True, null=True) + date_verified = models.DateTimeField(blank=True, null=True) history = HistoricalRecords() + @property + def is_verified(self): + """ + Test if a user is verified + """ + return self.date_verified is not None + @property def is_adherent(self): """ Test if a user is adherent """ - if(self.cotisationEnd and self.cotisationEnd > timezone.now()): + if(self.is_verified and self.cotisationEnd and self.cotisationEnd > timezone.now()): return True else: return False diff --git a/users/urls.py b/users/urls.py index 2201cae..03f64e9 100644 --- a/users/urls.py +++ b/users/urls.py @@ -45,4 +45,5 @@ urlpatterns = [ path('allMenus//', views.all_menus, name="allMenus"), path('exportCSV', views.export_csv, name="exportCSV"), path('switchActivateUser/', views.switch_activate_user, name="switchActivateUser"), + path('verify/', views.verify, name="verify") ] diff --git a/users/views.py b/users/views.py index c2ce219..43e0644 100644 --- a/users/views.py +++ b/users/views.py @@ -20,6 +20,10 @@ from .models import CotisationHistory, WhiteListHistory, School from .forms import CreateUserForm, LoginForm, CreateGroupForm, EditGroupForm, SelectUserForm, GroupsEditForm, EditPasswordForm, addCotisationHistoryForm, addCotisationHistoryForm, addWhiteListHistoryForm, SelectNonAdminUserForm, SelectNonSuperUserForm, SchoolForm, ExportForm from gestion.models import Reload, Consumption, ConsumptionHistory, MenuHistory + +from django.contrib.auth.forms import SetPasswordForm + + @active_required def loginView(request): """ @@ -177,8 +181,6 @@ def profile(request, pk): if quantities_pre[k]/totQ >= 0.01: products.append(products_pre[k]) quantities.append(quantities_pre[k]) - print(products) - print(quantities) lastConsumptions = ConsumptionHistory.objects.filter(customer=user).order_by('-date')[:10] lastMenus = MenuHistory.objects.filter(customer=user).order_by('-date')[:10] return render(request, "users/profile.html", @@ -219,7 +221,6 @@ def createUser(request): form = CreateUserForm(request.POST or None) if(form.is_valid()): user = form.save(commit=False) - user.set_password(user.username) user.save() user.profile.school = form.cleaned_data['school'] user.save() @@ -512,6 +513,21 @@ def switch_activate_user(request, pk): user.save() messages.success(request, "Le statut de l'utilisateur a bien été changé") return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + +@active_required +def verify(request, pk): + user = get_object_or_404(User, pk=pk) + if(user.profile.is_verified): + messages.error(request, "L'utilisateur est déjà vérifié") + return redirect(reverse('users:login')) + form = SetPasswordForm(user, request.POST or None) + if(form.is_valid()): + form.save() + user.profile.date_verified = datetime.now() + user.save() + messages.success(request, "Le compte a bien été vérifié") + return redirect(reverse('users:login')) + return render(request, "users/verify.html", {"user": user, "form": form}) ########## Groups ########## From 9b71c5230254aec01886f1055e731c802df1831f Mon Sep 17 00:00:00 2001 From: Nanoy Date: Tue, 19 Feb 2019 08:27:25 +0100 Subject: [PATCH 2/6] Verify oubli --- users/migrations/0002_auto_20190218_2231.py | 23 ++++++++++++++ users/templates/users/verify.html | 33 +++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 users/migrations/0002_auto_20190218_2231.py create mode 100644 users/templates/users/verify.html diff --git a/users/migrations/0002_auto_20190218_2231.py b/users/migrations/0002_auto_20190218_2231.py new file mode 100644 index 0000000..338ab47 --- /dev/null +++ b/users/migrations/0002_auto_20190218_2231.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1 on 2019-02-18 21:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='historicalprofile', + name='date_verified', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='profile', + name='date_verified', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/users/templates/users/verify.html b/users/templates/users/verify.html new file mode 100644 index 0000000..627a964 --- /dev/null +++ b/users/templates/users/verify.html @@ -0,0 +1,33 @@ +{% extends 'base.html' %} +{% block entete %}Vérification du compte{% endblock %} +{% block navbar %} + +{% endblock %} +{% block content %} +
+
+

Vérification du compte de {{user}}

+
+
+
+ {% csrf_token %} + {{ form }} +
+ + En cliquant sur le bouton "Modifier mon mot de passe et accepter", vous : +
    +
  • attestez sur l'honneur que les informations fournies à l'association Coopé Technopôle Metz sont correctes et que vous n'avez jamais été enregistré dans l'association sous un autre nom / pseudonyme
  • +
  • joignez l'association de votre plein gré
  • +
  • vous engagez à respecter les statuts et le reglèment intérieur de l'association (envoyés par mail)
  • +
  • reconnaissez le but de l'assocation Coopé Technopôle Metz et vous attestez avoir pris conaissances des droits et des devoirs des membres de l'association
  • +
  • consentez à ce que les données fournies à l'association, ainsi que vos autres données de compte (débit, crédit, solde et historique des transactions) soient stockées dans le logiciel de gestion et accessibles par tout les membres actifs de l'association, en particulier par le comité de direction
  • +
+
+ +
+
+
+{{form.media}} +{% endblock %} From dedd30303a02adceda6ec246be35004f47d5af33 Mon Sep 17 00:00:00 2001 From: Nanoy Date: Thu, 21 Feb 2019 20:08:29 +0100 Subject: [PATCH 3/6] Meilleure inscription --- django_tex/core.py | 2 +- templates/form.html | 1 + users/models.py | 10 +--------- users/templates/users/verify.html | 33 ------------------------------- users/urls.py | 1 - users/views.py | 21 +------------------- 6 files changed, 4 insertions(+), 64 deletions(-) delete mode 100644 users/templates/users/verify.html diff --git a/django_tex/core.py b/django_tex/core.py index 1c4d409..676d813 100644 --- a/django_tex/core.py +++ b/django_tex/core.py @@ -16,7 +16,7 @@ def run_tex(source): with open(filename, 'x', encoding='utf-8') as f: f.write(source) latex_interpreter = getattr(settings, 'LATEX_INTERPRETER', DEFAULT_INTERPRETER) - latex_command = f'cd "{tempdir}" && {latex_interpreter} -interaction=batchmode {os.path.basename(filename)}' + latex_command = 'cd "{tempdir}" && {latex_interpreter} -interaction=batchmode {path}'.format(tempdir=tempdir, latex_interpreter=latex_interpreter, path=os.path.basename(filename)) process = run(latex_command, shell=True, stdout=PIPE, stderr=PIPE) try: if process.returncode == 1: diff --git a/templates/form.html b/templates/form.html index be760ba..8f49a3e 100644 --- a/templates/form.html +++ b/templates/form.html @@ -16,6 +16,7 @@ {% csrf_token %} {{ form }}
+ {{ extra_html | safe }} diff --git a/users/models.py b/users/models.py index 2ae5c2c..b586df7 100644 --- a/users/models.py +++ b/users/models.py @@ -75,22 +75,14 @@ class Profile(models.Model): debit = models.DecimalField(max_digits=7, decimal_places=2, default=0) school = models.ForeignKey(School, on_delete=models.PROTECT, blank=True, null=True) cotisationEnd = models.DateTimeField(blank=True, null=True) - date_verified = models.DateTimeField(blank=True, null=True) history = HistoricalRecords() - @property - def is_verified(self): - """ - Test if a user is verified - """ - return self.date_verified is not None - @property def is_adherent(self): """ Test if a user is adherent """ - if(self.is_verified and self.cotisationEnd and self.cotisationEnd > timezone.now()): + if(self.cotisationEnd and self.cotisationEnd > timezone.now()): return True else: return False diff --git a/users/templates/users/verify.html b/users/templates/users/verify.html deleted file mode 100644 index 627a964..0000000 --- a/users/templates/users/verify.html +++ /dev/null @@ -1,33 +0,0 @@ -{% extends 'base.html' %} -{% block entete %}Vérification du compte{% endblock %} -{% block navbar %} - -{% endblock %} -{% block content %} -
-
-

Vérification du compte de {{user}}

-
-
-
- {% csrf_token %} - {{ form }} -
- - En cliquant sur le bouton "Modifier mon mot de passe et accepter", vous : -
    -
  • attestez sur l'honneur que les informations fournies à l'association Coopé Technopôle Metz sont correctes et que vous n'avez jamais été enregistré dans l'association sous un autre nom / pseudonyme
  • -
  • joignez l'association de votre plein gré
  • -
  • vous engagez à respecter les statuts et le reglèment intérieur de l'association (envoyés par mail)
  • -
  • reconnaissez le but de l'assocation Coopé Technopôle Metz et vous attestez avoir pris conaissances des droits et des devoirs des membres de l'association
  • -
  • consentez à ce que les données fournies à l'association, ainsi que vos autres données de compte (débit, crédit, solde et historique des transactions) soient stockées dans le logiciel de gestion et accessibles par tout les membres actifs de l'association, en particulier par le comité de direction
  • -
-
- -
-
-
-{{form.media}} -{% endblock %} diff --git a/users/urls.py b/users/urls.py index 03f64e9..2201cae 100644 --- a/users/urls.py +++ b/users/urls.py @@ -45,5 +45,4 @@ urlpatterns = [ path('allMenus//', views.all_menus, name="allMenus"), path('exportCSV', views.export_csv, name="exportCSV"), path('switchActivateUser/', views.switch_activate_user, name="switchActivateUser"), - path('verify/', views.verify, name="verify") ] diff --git a/users/views.py b/users/views.py index 43e0644..33d57ca 100644 --- a/users/views.py +++ b/users/views.py @@ -20,10 +20,6 @@ from .models import CotisationHistory, WhiteListHistory, School from .forms import CreateUserForm, LoginForm, CreateGroupForm, EditGroupForm, SelectUserForm, GroupsEditForm, EditPasswordForm, addCotisationHistoryForm, addCotisationHistoryForm, addWhiteListHistoryForm, SelectNonAdminUserForm, SelectNonSuperUserForm, SchoolForm, ExportForm from gestion.models import Reload, Consumption, ConsumptionHistory, MenuHistory - -from django.contrib.auth.forms import SetPasswordForm - - @active_required def loginView(request): """ @@ -226,7 +222,7 @@ def createUser(request): user.save() messages.success(request, "L'utilisateur a bien été créé") return redirect(reverse('users:profile', kwargs={'pk':user.pk})) - return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form":form, "form_title":"Création d'un nouvel utilisateur", "form_button":"Créer l'utilisateur", "form_button_icon": "user-plus"}) + return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form":form, "form_title":"Création d'un nouvel utilisateur", "form_button":"Créer mon compte", "form_button_icon": "user-plus", 'extra_html': 'En cliquant sur le bouton "Créer mon compte", vous :
  • attestez sur l\'honneur que les informations fournies à l\'association Coopé Technopôle Metz sont correctes et que vous n\'avez jamais été enregistré dans l\'association sous un autre nom / pseudonyme
  • joignez l\'association de votre plein gré
  • vous engagez à respecter les statuts et le réglement intérieur de l\'association (envoyés par mail)
  • reconnaissez le but de l\'assocation Coopé Technopôle Metz et vous attestez avoir pris conaissances des droits et des devoirs des membres de l\'association
  • consentez à ce que les données fournies à l\'association, ainsi que vos autres données de compte (débit, crédit, solde et historique des transactions) soient stockées dans le logiciel de gestion et accessibles par tous les membres actifs de l\'association, en particulier par le comité de direction
'}) @active_required @login_required @@ -513,21 +509,6 @@ def switch_activate_user(request, pk): user.save() messages.success(request, "Le statut de l'utilisateur a bien été changé") return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) - -@active_required -def verify(request, pk): - user = get_object_or_404(User, pk=pk) - if(user.profile.is_verified): - messages.error(request, "L'utilisateur est déjà vérifié") - return redirect(reverse('users:login')) - form = SetPasswordForm(user, request.POST or None) - if(form.is_valid()): - form.save() - user.profile.date_verified = datetime.now() - user.save() - messages.success(request, "Le compte a bien été vérifié") - return redirect(reverse('users:login')) - return render(request, "users/verify.html", {"user": user, "form": form}) ########## Groups ########## From 3025ed6cf408746215269d1f84a98e71845b6152 Mon Sep 17 00:00:00 2001 From: Nanoy Date: Thu, 21 Feb 2019 20:08:47 +0100 Subject: [PATCH 4/6] Oubli de la migration --- users/migrations/0003_auto_20190219_1921.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 users/migrations/0003_auto_20190219_1921.py diff --git a/users/migrations/0003_auto_20190219_1921.py b/users/migrations/0003_auto_20190219_1921.py new file mode 100644 index 0000000..972914a --- /dev/null +++ b/users/migrations/0003_auto_20190219_1921.py @@ -0,0 +1,21 @@ +# Generated by Django 2.1 on 2019-02-19 18:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0002_auto_20190218_2231'), + ] + + operations = [ + migrations.RemoveField( + model_name='historicalprofile', + name='date_verified', + ), + migrations.RemoveField( + model_name='profile', + name='date_verified', + ), + ] From f9cea668041c0050b9d841b4cd9dd12df80b8464 Mon Sep 17 00:00:00 2001 From: Nanoy Date: Mon, 25 Feb 2019 11:13:42 +0100 Subject: [PATCH 5/6] =?UTF-8?q?R=C3=A9solution=20du=20probl=C3=A8me=20de?= =?UTF-8?q?=20Foulques?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gestion/models.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gestion/models.py b/gestion/models.py index 9921418..e608ff5 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -47,12 +47,11 @@ class Product(models.Model): def user_ranking(self, pk): user = User.objects.get(pk=pk) - consumptions = ConsumptionHistory.objects.filter(customer=user).filter(product=self) - # add menu - nb = 0 - for consumption in consumptions: - nb += consumption.quantity - return (user, nb) + consumptions = Consumption.objects.filter(customer=user).filter(product=self) + if consumptions: + return (user, consumptions[0].quantity) + else: + return (user, 0) @property def ranking(self): From 4bb8d00c901030a5f9ed7c92818fa80d2646c963 Mon Sep 17 00:00:00 2001 From: Nanoy Date: Tue, 26 Feb 2019 23:18:53 +0100 Subject: [PATCH 6/6] Suppression de cotisations, informations utilisateurs --- preferences/views.py | 9 ++- templates/form.html | 2 +- users/migrations/0004_auto_20190226_2313.py | 25 +++++++ users/models.py | 13 ---- users/templates/users/bulletin.tex | 70 ++++++++++++++++++++ users/templates/users/coope.png | Bin 0 -> 5143 bytes users/templates/users/profile.html | 9 +-- users/urls.py | 4 +- users/views.py | 45 ++++++------- 9 files changed, 131 insertions(+), 46 deletions(-) create mode 100644 users/migrations/0004_auto_20190226_2313.py create mode 100644 users/templates/users/bulletin.tex create mode 100644 users/templates/users/coope.png diff --git a/preferences/views.py b/preferences/views.py index 5fd61a5..06fc628 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -6,6 +6,7 @@ from django.urls import reverse from django.contrib.auth.decorators import login_required, permission_required from django.http import HttpResponse from django.forms.models import model_to_dict +from django.http import Http404 from coopeV3.acl import active_required @@ -263,7 +264,11 @@ def get_config(request): """ Load the config and return it in a json format """ - gp,_ = GeneralPreferences.objects.get_or_create(pk=1).defer("statutes", "rules", "menu") - data = json.dumps(model_to_dict(gp)) + gp, _ = GeneralPreferences.objects.defer("statutes", "rules", "menu").get_or_create(pk=1) + gp_dict = model_to_dict(gp) + del gp_dict["statutes"] + del gp_dict["rules"] + del gp_dict["menu"] + data = json.dumps(gp_dict) return HttpResponse(data, content_type='application/json') \ No newline at end of file diff --git a/templates/form.html b/templates/form.html index 8f49a3e..949eecd 100644 --- a/templates/form.html +++ b/templates/form.html @@ -16,7 +16,7 @@ {% csrf_token %} {{ form }}
- {{ extra_html | safe }} + {{ extra_html | safe }}

diff --git a/users/migrations/0004_auto_20190226_2313.py b/users/migrations/0004_auto_20190226_2313.py new file mode 100644 index 0000000..bb26d11 --- /dev/null +++ b/users/migrations/0004_auto_20190226_2313.py @@ -0,0 +1,25 @@ +# Generated by Django 2.1 on 2019-02-26 22:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_auto_20190219_1921'), + ] + + operations = [ + migrations.AlterModelOptions( + name='cotisationhistory', + options={'verbose_name': 'Historique cotisation'}, + ), + migrations.RemoveField( + model_name='cotisationhistory', + name='valid', + ), + migrations.RemoveField( + model_name='historicalcotisationhistory', + name='valid', + ), + ] diff --git a/users/models.py b/users/models.py index b586df7..214894b 100644 --- a/users/models.py +++ b/users/models.py @@ -26,18 +26,6 @@ class CotisationHistory(models.Model): """ class Meta: verbose_name = "Historique cotisation" - permissions = ( - ("validate_cotisationhistory", "Peut (in)valider les cotisations"), - ) - - WAITING = 0 - VALID = 1 - INVALID = 2 - VALIDATION_CHOICES = ( - (WAITING, 'En attente de validation'), - (VALID, 'Validée'), - (INVALID, 'Invalidée'), - ) user = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="Client") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant") duration = models.PositiveIntegerField(verbose_name="Durée") @@ -46,7 +34,6 @@ class CotisationHistory(models.Model): paymentMethod = models.ForeignKey(PaymentMethod, on_delete=models.PROTECT, verbose_name="Moyen de paiement") cotisation = models.ForeignKey(Cotisation, on_delete=models.PROTECT, verbose_name="Type de cotisation") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="cotisation_made") - valid = models.IntegerField(choices=VALIDATION_CHOICES, default=WAITING) history = HistoricalRecords() class WhiteListHistory(models.Model): diff --git a/users/templates/users/bulletin.tex b/users/templates/users/bulletin.tex new file mode 100644 index 0000000..6c70bf5 --- /dev/null +++ b/users/templates/users/bulletin.tex @@ -0,0 +1,70 @@ +\documentclass[a4paper, 12pt]{article} +\usepackage[utf8]{inputenc} +\usepackage[french]{babel} +\usepackage{eurosym} +\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry} +\usepackage{tabularx} +\usepackage{longtable} +\usepackage{tabu} +\usepackage{fancyhdr} +\usepackage{natbib} +\usepackage{graphicx} + +\setlength{\parindent}{0pt} + +\pagestyle{fancy} +\renewcommand{\headrulewidth}{0pt} +\fancyhead[C]{\includegraphics[scale=0.3]{ {{- path -}} }} + +\begin{document} +\vspace*{0.3\baselineskip} +\begin{center} +\huge{Bulletin d'adhésion à l'association Coopé Technopôle Metz} +\end{center} +\vspace*{\baselineskip} +Je soussigné(e), {{user.first_name}} {{user.last_name}}, +\begin{itemize} +\item atteste sur l'honneur que les informations fournies à l'association Coopé Technopôle Metz sont correctes et que je n'ai jamais été enregistré dans l'association sous un autre nom / pseudonyme +\item joins l'association de mon plein gré +\item m'engage à respecter les statuts et le réglement intérieur de l'association +\item reconnais le but de l'assocation Coopé Technopôle Metz et atteste avoir pris conaissances des droits et des devoirs des membres de l'association +\item consent à ce que les données fournies à l'association, ainsi que mes autres données de compte (débit, crédit, solde et historique des transactions) soient stockées dans le logiciel de gestion et accessibles par tous les membres actifs de l'association, en particulier par le comité de direction +\end{itemize} + +\begin{flushright} +Fait à Metz, le {{user.date_joined.strftime('%d/%m/%Y')}} +\end{flushright} +Ce bulletin a été validé électroniquement par {{user.first_name}} {{user.last_name}} le {{user.date_joined.strftime('%d/%m/%Y %H:%M:%S')}}, heure de Paris. + +\newpage + +\begin{center} +\huge{Historique des cotisations à l'association} +\end{center} +\vspace*{\baselineskip} +\begin{longtabu}{|c|X|X|X|X|X|} +\hline +\# & Date & Montant & Durée & Moyen de paiement & Date de fin\\ +\hline +{% for cotisation in cotisations %} +{{cotisation.pk}} & {{cotisation.paymentDate.strftime('%d/%M/%Y %H:%M')}} & {{cotisation.amount}} \euro{} & {{cotisation.duration}} jour(s)& {{cotisation.paymentMethod}} & {{cotisation.endDate.strftime('%d/%M/%Y %H:%M')}} \\ +\hline +{% endfor %} +\end{longtabu} + +\newpage +\begin{center} +\huge{Attestation d'adhésion} +\end{center} +\vspace*{\baselineskip} +Le comité de direction de la Coopé Technopôle Metz atteste avoir reçu les cotisations de la part de {{user.first_name}} {{user.last_name}}. {% if user.profile.is_adherent %}Le comité atteste aussi que {{user.first_name}} {{user.last_name}} est membre adhérent de l'association au {{now.strftime('%d/%m/%Y')}}.{% endif %} + +{% if user.is_staff %} +\vspace*{\baselineskip} +Le membre est jugé comme membre actif par le comité de direction. +{% endif %} + +\vspace*{\baselineskip} + +Cette attestation est délivrée pour jouir des droits qui lui sont dus. +\end{document} diff --git a/users/templates/users/coope.png b/users/templates/users/coope.png new file mode 100644 index 0000000000000000000000000000000000000000..f73fc591e1beaea0fd42b8e7c4454cc910ac41aa GIT binary patch literal 5143 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 FV1jd5&yD~9 literal 0 HcmV?d00001 diff --git a/users/templates/users/profile.html b/users/templates/users/profile.html index fcdb7bf..e369a31 100644 --- a/users/templates/users/profile.html +++ b/users/templates/users/profile.html @@ -51,7 +51,7 @@
@@ -227,7 +230,6 @@ Date de paiement Moyen de paiement Date de fin - État Modération @@ -239,8 +241,7 @@ {{cotisation.paymentDate}} {{cotisation.paymentMethod}} {{cotisation.endDate}} - {{cotisation.valid}} - {% if perms.users.validate_cotisationHistory %} Valider Invalider{% endif %} + {% if perms.users.delete_cotisationhistory %} Supprimer{% endif %} {% endfor %} diff --git a/users/urls.py b/users/urls.py index 2201cae..51532e8 100644 --- a/users/urls.py +++ b/users/urls.py @@ -33,8 +33,7 @@ urlpatterns = [ path('non-admin-users-autocomplete', views.NonAdminUserAutocomplete.as_view(), name="non-admin-users-autocomplete"), path('getUser/', views.getUser, name="getUser"), path('addCotisationHistory/', views.addCotisationHistory, name="addCotisationHistory"), - path('validateCotisationHistory/', views.validateCotisationHistory, name="validateCotisationHistory"), - path('invalidateCotisationHistory/', views.invalidateCotisationHistory, name="invalidateCotisationHistory"), + path('deleteCotisationHistory/', views.deleteCotisationHistory, name="deleteCotisationHistory"), path('addWhiteListHistory/', views.addWhiteListHistory, name="addWhiteListHistory"), path('schoolsIndex', views.schoolsIndex, name="schoolsIndex"), path('createSchool', views.createSchool, name="createSchool"), @@ -45,4 +44,5 @@ urlpatterns = [ path('allMenus//', views.all_menus, name="allMenus"), path('exportCSV', views.export_csv, name="exportCSV"), path('switchActivateUser/', views.switch_activate_user, name="switchActivateUser"), + path('genUserInfos/', views.gen_user_infos, name="genUserInfos"), ] diff --git a/users/views.py b/users/views.py index 33d57ca..8868a27 100644 --- a/users/views.py +++ b/users/views.py @@ -9,12 +9,16 @@ from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.contrib.auth.decorators import login_required, permission_required from django.forms.models import model_to_dict from django.utils import timezone +from django.conf import settings import simplejson as json from datetime import datetime, timedelta from dal import autocomplete import csv +import os + +from django_tex.views import render_to_pdf from coopeV3.acl import admin_required, superuser_required, self_or_has_perm, active_required from .models import CotisationHistory, WhiteListHistory, School from .forms import CreateUserForm, LoginForm, CreateGroupForm, EditGroupForm, SelectUserForm, GroupsEditForm, EditPasswordForm, addCotisationHistoryForm, addCotisationHistoryForm, addWhiteListHistoryForm, SelectNonAdminUserForm, SelectNonSuperUserForm, SchoolForm, ExportForm @@ -156,7 +160,7 @@ def profile(request, pk): """ user = get_object_or_404(User, pk=pk) self = request.user == user - cotisations = CotisationHistory.objects.filter(user=user) + cotisations = CotisationHistory.objects.filter(user=user).order_by('-paymentDate') whitelists = WhiteListHistory.objects.filter(user=user) reloads = Reload.objects.filter(customer=user).order_by('-date')[:5] consumptionsChart = Consumption.objects.filter(customer=user) @@ -509,7 +513,17 @@ def switch_activate_user(request, pk): user.save() messages.success(request, "Le statut de l'utilisateur a bien été changé") return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) - + +@active_required +@login_required +@permission_required('auth.view_user') +def gen_user_infos(request, pk): + user= get_object_or_404(User, pk=pk) + cotisations = CotisationHistory.objects.filter(user=user).order_by('-paymentDate') + now = datetime.now() + path = os.path.join(settings.BASE_DIR, "users/templates/users/coope.png") + return render_to_pdf(request, 'users/bulletin.tex', {"user": user, "now": now, "cotisations": cotisations, "path":path}, filename="bulletin_" + user.first_name + "_" + user.last_name + ".pdf") + ########## Groups ########## @active_required @@ -889,39 +903,22 @@ def addCotisationHistory(request, pk): @active_required @login_required -@permission_required('users.validate_cotisationhistory') -def validateCotisationHistory(request, pk): +@permission_required('users.delete_cotisationhistory') +def deleteCotisationHistory(request, pk): """ - Validate the requested :model:`users.CotisationHistory` + Delete the requested :model:`users.CotisationHistory` ``pk`` The primary key of the :model:`users.CotisationHistory` """ cotisationHistory = get_object_or_404(CotisationHistory, pk=pk) - cotisationHistory.valid = CotisationHistory.VALID - cotisationHistory.save() - messages.success(request, "La cotisation a bien été validée") - return HttpResponseRedirect(request.META.get('HTTP_REFERER')) - -@active_required -@login_required -@permission_required('users.validate_cotisationhistory') -def invalidateCotisationHistory(request, pk): - """ - Invalidate the requested :model:`users.CotisationHistory` - - ``pk`` - The primary key of the :model:`users.CotisationHistory` - """ - cotisationHistory = get_object_or_404(CotisationHistory, pk=pk) - cotisationHistory.valid = CotisationHistory.INVALID - cotisationHistory.save() user = cotisationHistory.user user.profile.cotisationEnd = user.profile.cotisationEnd - timedelta(days=cotisationHistory.duration) if(cotisationHistory.paymentMethod.affect_balance): user.profile.debit -= cotisationHistory.cotisation.amount user.save() - messages.success(request, "La cotisation a bien été invalidée") + cotisationHistory.delete() + messages.success(request, "La cotisation a bien été supprimée") return HttpResponseRedirect(request.META.get('HTTP_REFERER')) ########## Whitelist ##########