8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-24 20:33:11 +00:00

[Printer] Can create digicode, and display list of available digicodes. Maybe create a specific app

This commit is contained in:
Maxime Bombar 2018-11-17 15:29:02 +01:00 committed by root
parent 490b26006b
commit cef89570f1
11 changed files with 282 additions and 35 deletions

View file

@ -21,6 +21,7 @@ from users.models import User
from .models import ( from .models import (
JobWithOptions, JobWithOptions,
Digicode,
) )
@ -66,3 +67,15 @@ class PrintAgainForm(JobWithOptionsForm):
'format', 'format',
'count', 'count',
] ]
class CreateCodeForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
# user = kwargs.get('user')
super(CreateCodeForm, self).__init__(*args, prefix=prefix, **kwargs)
class Meta:
model = Digicode
fields = [
"user",
]

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-11-17 13:29+0100\n" "POT-Creation-Date: 2018-11-17 15:15+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -22,83 +22,92 @@ msgstr ""
msgid "You don't have the right to view Printer application." msgid "You don't have the right to view Printer application."
msgstr "Vous n'avez pas le droit de voir l'application d'impression" msgstr "Vous n'avez pas le droit de voir l'application d'impression"
#: printer/forms.py:33 #: printer/forms.py:34
msgid "Print As" msgid "Print As"
msgstr "Imprimer en tant que" msgstr "Imprimer en tant que"
#: printer/models.py:87 #: printer/models.py:83
#, fuzzy
msgid "This is not your digicode !"
msgstr "Ceci n'est pas votre tache"
#: printer/models.py:89
msgid "You can't generate a digicode"
msgstr "Vous ne pouvez pas créer un digicode"
#: printer/models.py:103
msgid "This is not your print operation task" msgid "This is not your print operation task"
msgstr "Ceci n'est pas votre tache" msgstr "Ceci n'est pas votre tache"
#: printer/models.py:124 #: printer/models.py:140
msgid "Pending" msgid "Pending"
msgstr "En attente" msgstr "En attente"
#: printer/models.py:125 #: printer/models.py:141
msgid "Printable" msgid "Printable"
msgstr "Imprimable" msgstr "Imprimable"
#: printer/models.py:126 #: printer/models.py:142
msgid "Running" msgid "Running"
msgstr "En cours..." msgstr "En cours..."
#: printer/models.py:127 #: printer/models.py:143
msgid "Cancelled" msgid "Cancelled"
msgstr "Annulée" msgstr "Annulée"
#: printer/models.py:128 #: printer/models.py:144
msgid "Finished" msgid "Finished"
msgstr "Terminée" msgstr "Terminée"
#: printer/models.py:140 #: printer/models.py:156
msgid "File" msgid "File"
msgstr "Fichier" msgstr "Fichier"
#: printer/models.py:145 printer/templates/printer/aff_jobs.html:35 #: printer/models.py:161 printer/templates/printer/aff_jobs.html:35
msgid "File Name" msgid "File Name"
msgstr "Nom du fichier" msgstr "Nom du fichier"
#: printer/models.py:152 printer/templates/printer/aff_jobs.html:38 #: printer/models.py:168 printer/templates/printer/aff_jobs.html:38
msgid "Status" msgid "Status"
msgstr "Status" msgstr "Status"
#: printer/models.py:161 #: printer/models.py:177
msgid "Print as" msgid "Print as"
msgstr "Imprimer en tant que" msgstr "Imprimer en tant que"
#: printer/models.py:166 printer/templates/printer/aff_jobs.html:40 #: printer/models.py:182 printer/templates/printer/aff_jobs.html:40
msgid "Price" msgid "Price"
msgstr "Prix" msgstr "Prix"
#: printer/models.py:174 #: printer/models.py:190
msgid "Format" msgid "Format"
msgstr "Format" msgstr "Format"
#: printer/models.py:180 printer/settings.py:25 #: printer/models.py:196 printer/settings.py:25
msgid "Color" msgid "Color"
msgstr "Couleur" msgstr "Couleur"
#: printer/models.py:186 #: printer/models.py:202
msgid "Disposition" msgid "Disposition"
msgstr "Disposition" msgstr "Disposition"
#: printer/models.py:190 #: printer/models.py:206
msgid "Count" msgid "Count"
msgstr "Nombre" msgstr "Nombre"
#: printer/models.py:196 #: printer/models.py:212
msgid "Stapling" msgid "Stapling"
msgstr "Agrafage" msgstr "Agrafage"
#: printer/models.py:202 #: printer/models.py:218
msgid "Perforation" msgid "Perforation"
msgstr "Perforation" msgstr "Perforation"
#: printer/models.py:243 #: printer/models.py:259
msgid "This is not your print job" msgid "This is not your print job"
msgstr "Ceci n'est pas votre tache" msgstr "Ceci n'est pas votre tache"
#: printer/models.py:251 #: printer/models.py:267
msgid "This is not your print operation job" msgid "This is not your print operation job"
msgstr "Ceci n'est pas votre tâche" msgstr "Ceci n'est pas votre tâche"
@ -170,6 +179,18 @@ msgstr "Quatre trous à gauche"
msgid "Four right sided holes" msgid "Four right sided holes"
msgstr "Quatre trous à droite" msgstr "Quatre trous à droite"
#: printer/templates/printer/aff_digicodes.html:36
msgid "User"
msgstr "L'utilisateur"
#: printer/templates/printer/aff_digicodes.html:37
msgid "Code"
msgstr "Digicode"
#: printer/templates/printer/aff_digicodes.html:38
msgid "Created on"
msgstr "Créé le"
#: printer/templates/printer/aff_jobs.html:36 #: printer/templates/printer/aff_jobs.html:36
msgid "By user" msgid "By user"
msgstr "Par" msgstr "Par"
@ -190,10 +211,21 @@ msgstr "Imprimer à nouveau"
msgid "for" msgid "for"
msgstr "pour" msgstr "pour"
#: printer/templates/printer/create_code.html:15
msgid "Create digicode for"
msgstr "Créer un digicode pour"
#: printer/templates/printer/index_digicodes.html:28
#: printer/templates/printer/index_jobs.html:28 #: printer/templates/printer/index_jobs.html:28
msgid "Printer" msgid "Printer"
msgstr "Imprimer" msgstr "Imprimer"
#: printer/templates/printer/index_digicodes.html:31
#, fuzzy
#| msgid "List of jobs"
msgid "List of codes"
msgstr "Liste des taches"
#: printer/templates/printer/index_jobs.html:31 #: printer/templates/printer/index_jobs.html:31
#: printer/templates/printer/sidebar.html:34 #: printer/templates/printer/sidebar.html:34
msgid "List of jobs" msgid "List of jobs"
@ -236,6 +268,16 @@ msgstr "Désolé, l'imprimante est actuellement hors-service..."
msgid "Print document" msgid "Print document"
msgstr "Imprimer un document" msgstr "Imprimer un document"
#: printer/templates/printer/sidebar.html:38
#, fuzzy
#| msgid "List of jobs"
msgid "List of digicodes"
msgstr "Liste des taches"
#: printer/templates/printer/sidebar.html:43
msgid "Create Digicode"
msgstr "Créer un digicode"
#: printer/validators.py:48 #: printer/validators.py:48
#, python-format #, python-format
msgid "" msgid ""
@ -253,14 +295,18 @@ msgstr ""
"Le fichier a une taille de %(size)s. La taille maximum autorisée est " "Le fichier a une taille de %(size)s. La taille maximum autorisée est "
"%(max_size)s." "%(max_size)s."
#: printer/views.py:89 #: printer/views.py:104
msgid "Next" msgid "Next"
msgstr "Suivant" msgstr "Suivant"
#: printer/views.py:121 printer/views.py:147 #: printer/views.py:136 printer/views.py:162
msgid "Print" msgid "Print"
msgstr "Imprimer" msgstr "Imprimer"
#: printer/views.py:176 #: printer/views.py:191
msgid "You are not allowed to print" msgid "You are not allowed to print"
msgstr "Vous n'êtes pas autorisé à imprimer" msgstr "Vous n'êtes pas autorisé à imprimer"
#: printer/views.py:263
msgid "Create Code"
msgstr "Créer un digicode"

View file

@ -53,7 +53,7 @@ def user_printing_path(instance, filename):
return 'printings/user_{0}/{1}'.format(instance.user.id, unidecode.unidecode(filename)) return 'printings/user_{0}/{1}'.format(instance.user.id, unidecode.unidecode(filename))
class Digicode(RevMixin, models.Model): class Digicode(RevMixin, models.Model, AclMixin, FieldPermissionModelMixin):
""" """
This is a model to represent a digicode, maybe should be an external app. This is a model to represent a digicode, maybe should be an external app.
""" """
@ -74,6 +74,22 @@ class Digicode(RevMixin, models.Model):
digicode.save() digicode.save()
return (str(code) + '#') return (str(code) + '#')
def can_view(self, user_request, *args, **kwargs):
if user_request.has_perm('printer.view_Digicode'):
return True, None
elif user_request == self.user:
return True, None
else:
return False, _("This is not your digicode !")
def can_create(user_request, *args, **kwargs):
if user_request.has_perm('printer.create_Digicode'):
return True, None
else:
return False, _("You can't generate a digicode")
class PrintOperation(RevMixin, AclMixin, models.Model): class PrintOperation(RevMixin, AclMixin, models.Model):
"""Abstract printing operation""" """Abstract printing operation"""
user = models.ForeignKey('users.User', on_delete=models.PROTECT) user = models.ForeignKey('users.User', on_delete=models.PROTECT)
@ -262,4 +278,3 @@ class JobWithOptions(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self._update_price() self._update_price()
super(JobWithOptions, self).save(*args, **kwargs) super(JobWithOptions, self).save(*args, **kwargs)

View file

@ -0,0 +1,57 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2018 Gabriel Détraz
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load acl %}
{% load logs_extra %}
{% load i18n %}
<div class="table-responsive">
{% if digicodes_list.paginator %}
{% include "pagination.html" with list=digicodes_list %}
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "User" %}</th>
<th>{% trans "Code" %}</th>
<th>{% trans "Created on" %}</th>
</tr>
</thead>
{% for digicode in digicodes_list %}
{% can_view digicode %}
<tr>
<td>{{ digicode.user }}</td>
{% with code=digicode.code %}
<td>{{ code }}#</td>
{% endwith %}
<td>{{ digicode.created }}</td>
</tr>
{% acl_end %}
{% endfor %}
</table>
{% if digicodes_list.paginator %}
{% include "pagination.html" with list=digicodes_list %}
{% endif %}
</div>

View file

@ -0,0 +1,20 @@
{% extends "printer/sidebar.html" %}
{% load staticfiles %}
{% load i18n %}
{% load bootstrap3 %}
{% load massive_bootstrap_form %}
{% block title %}Printing interface{% endblock %}
{% block content %}
{% bootstrap_form_errors codeform %}
<form class="form" method="post">
{% csrf_token %}
<h3>{% trans "Create digicode for" %}</h3>
{% massive_bootstrap_form codeform 'user' %}
{% bootstrap_button action_name button_type="submit" icon="ok" button_class="btn-succes" %}
</form>
{% endblock %}

View file

@ -0,0 +1,33 @@
{% extends "printer/sidebar.html" %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2018 Gabriel Détraz
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load bootstrap3 %}
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Printer" %}{% endblock %}
{% block content %}
<h2>{% trans "List of codes" %}</h2>
{% include "printer/aff_digicodes.html" with digicodes_list=digicodes_list %}
{% endblock %}

View file

@ -33,4 +33,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<i class="fa fa-list-ul"></i> <i class="fa fa-list-ul"></i>
{% trans "List of jobs" %} {% trans "List of jobs" %}
</a> </a>
<a class="list-group-item list-group-item-info" href="{% url "printer:index-digicodes" %}">
<i class="fa fa-list-ul"></i>
{% trans "List of digicodes" %}
</a>
{% can_create digicode %}
<a class="list-group-item list-group-item-success" href="{% url "printer:create-digicode" %}">
<i class="fa fa-plus"></i>
{% trans "Create Digicode" %}
</a>
{% acl_end %}
{% endblock %} {% endblock %}

View file

@ -15,6 +15,9 @@ urlpatterns = [
url(r'^new_job/$', views.new_job, name="new-job"), url(r'^new_job/$', views.new_job, name="new-job"),
url(r'^print_job/(?P<printoperationid>[0-9]+)$', views.print_job, name='print-job'), url(r'^print_job/(?P<printoperationid>[0-9]+)$', views.print_job, name='print-job'),
url(r'^index_jobs/$', views.index_jobs, name="index-jobs"), url(r'^index_jobs/$', views.index_jobs, name="index-jobs"),
url(r'^index_digicodes/$', views.index_digicodes, name="index-digicodes"),
url(r'^print_job_again/(?P<jobwithoptionsid>[0-9]+)$', views.print_job_again, name='print-job-again'), url(r'^print_job_again/(?P<jobwithoptionsid>[0-9]+)$', views.print_job_again, name='print-job-again'),
url(r'^create_digicode/', views.create_code, name='create-digicode'),
] ]

View file

@ -6,6 +6,8 @@ Author : Maxime Bombar <bombar@crans.org>.
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
from django.urls import reverse from django.urls import reverse
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.forms import modelformset_factory, formset_factory from django.forms import modelformset_factory, formset_factory
@ -20,13 +22,26 @@ from . import settings
from .utils import pdfinfo, send_mail_printer, printer_enabled from .utils import pdfinfo, send_mail_printer, printer_enabled
from re2o.acl import (
can_create,
can_edit,
can_delete_set,
can_delete,
can_view,
can_view_all,
can_change
)
from .models import ( from .models import (
JobWithOptions, JobWithOptions,
PrintOperation PrintOperation,
Digicode
) )
from .forms import ( from .forms import (
JobWithOptionsForm, JobWithOptionsForm,
PrintAgainForm PrintAgainForm,
CreateCodeForm,
) )
from preferences.models import GeneralOption from preferences.models import GeneralOption
@ -203,10 +218,7 @@ def payment(request, jobs):
success=1 success=1
if success: if success:
send_mail_printer(request.user) send_mail_printer(request.user)
return redirect(reverse( return redirect(reverse('printer:index-digicodes',))
'users:profil',
kwargs={'userid': str(request.user.id)}
))
@login_required @login_required
def index_jobs(request): def index_jobs(request):
@ -217,3 +229,39 @@ def index_jobs(request):
.order_by('starttime').reverse() .order_by('starttime').reverse()
jobs_list = re2o_paginator(request, jobs, pagination_number) jobs_list = re2o_paginator(request, jobs, pagination_number)
return render(request, 'printer/index_jobs.html', {'jobs_list': jobs_list}) return render(request, 'printer/index_jobs.html', {'jobs_list': jobs_list})
@login_required
def index_digicodes(request):
"""Display available digicodes"""
pagination_number = GeneralOption.get_cached_value('pagination_number')
digicodes = Digicode.objects.filter(created__gte=(datetime.datetime.now()
-datetime.timedelta(3)))
digicodes_list = re2o_paginator(request, digicodes, pagination_number)
return render(request,
'printer/index_digicodes.html',
{'digicodes_list': digicodes_list},
)
@can_create(Digicode)
@login_required
def create_code(request):
"""Generate a digicode"""
code = CreateCodeForm(
request.POST or None,
# form_kwargs={'user': request.user},
user = request.user,
)
if code.is_valid():
user = code.cleaned_data['user']
Digicode._gen_code(user)
return redirect(reverse('printer:index-digicodes',))
return form(
{
'codeform': code,
'action_name': _("Create Code"),
},
'printer/create_code.html',
request
)

View file

@ -107,6 +107,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="glyphicon glyphicon-print"></i> {% trans "Printer" %}<span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="glyphicon glyphicon-print"></i> {% trans "Printer" %}<span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="{% url "printer:new-job" %}"><i class="fa fa-print"></i> {% trans "Print" %}</a></li> <li><a href="{% url "printer:new-job" %}"><i class="fa fa-print"></i> {% trans "Print" %}</a></li>
<li><a href="{% url "printer:index-digicodes" %}"><i class="fa fa-calculator"></i> {% trans "Digicodes" %}</a></li>
</ul> </ul>
</li> </li>
{% endif %} {% endif %}