...
 
Commits (31)
......@@ -84,15 +84,13 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
return cleaned_data
class SelectUserArticleForm(FormRevMixin, Form):
class SelectArticleForm(FormRevMixin, Form):
"""
Form used to select an article during the creation of an invoice for a
member.
"""
article = forms.ModelChoiceField(
queryset=Article.objects.filter(
Q(type_user='All') | Q(type_user='Adherent')
),
queryset=Article.objects.none(),
label=_("Article"),
required=True
)
......@@ -104,31 +102,9 @@ class SelectUserArticleForm(FormRevMixin, Form):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(SelectUserArticleForm, self).__init__(*args, **kwargs)
self.fields['article'].queryset = Article.find_allowed_articles(user)
class SelectClubArticleForm(Form):
"""
Form used to select an article during the creation of an invoice for a
club.
"""
article = forms.ModelChoiceField(
queryset=Article.objects.filter(
Q(type_user='All') | Q(type_user='Club')
),
label=_("Article"),
required=True
)
quantity = forms.IntegerField(
label=_("Quantity"),
validators=[MinValueValidator(1)],
required=True
)
def __init__(self, user, *args, **kwargs):
super(SelectClubArticleForm, self).__init__(*args, **kwargs)
self.fields['article'].queryset = Article.find_allowed_articles(user)
target_user = kwargs.pop('target_user')
super(SelectArticleForm, self).__init__(*args, **kwargs)
self.fields['article'].queryset = Article.find_allowed_articles(user, target_user)
class CustomInvoiceForm(FormRevMixin, ModelForm):
......@@ -267,12 +243,12 @@ class RechargeForm(FormRevMixin, Form):
label=_("Payment method")
)
def __init__(self, *args, user=None, **kwargs):
def __init__(self, *args, user=None, user_source=None, **kwargs):
self.user = user
super(RechargeForm, self).__init__(*args, **kwargs)
self.fields['payment'].empty_label = \
_("Select a payment method")
self.fields['payment'].queryset = Paiement.find_allowed_payments(user).exclude(is_balance=True)
self.fields['payment'].queryset = Paiement.find_allowed_payments(user_source).exclude(is_balance=True)
def clean(self):
"""
......
......@@ -14,7 +14,9 @@ def reattribute_ids(apps, schema_editor):
BaseInvoice = apps.get_model('cotisations', 'BaseInvoice')
for f in Facture.objects.all():
base = BaseInvoice.objects.create(id=f.pk, date=f.date)
base = BaseInvoice.objects.create(id=f.pk)
base.date = f.date
base.save()
f.baseinvoice_ptr = base
f.save()
......
......@@ -222,7 +222,7 @@ class Facture(BaseInvoice):
return True, None
if len(Paiement.find_allowed_payments(user_request)) <= 0:
return False, _("There are no payment method which you can use.")
if len(Article.find_allowed_articles(user_request)) <= 0:
if len(Article.find_allowed_articles(user_request, user_request)) <= 0:
return False, _("There are no article that you can buy.")
return True, None
......@@ -595,15 +595,24 @@ class Article(RevMixin, AclMixin, models.Model):
)
@classmethod
def find_allowed_articles(cls, user):
"""Finds every allowed articles for an user.
def find_allowed_articles(cls, user, target_user):
"""Finds every allowed articles for an user, on a target user.
Args:
user: The user requesting articles.
target_user: The user to sell articles
"""
if target_user.is_class_club:
objects_pool = cls.objects.filter(
Q(type_user='All') | Q(type_user='Club')
)
else:
objects_pool = cls.objects.filter(
Q(type_user='All') | Q(type_user='Adherent')
)
if user.has_perm('cotisations.buy_every_article'):
return cls.objects.all()
return cls.objects.filter(available_for_everyone=True)
return objects_pool
return objects_pool.filter(available_for_everyone=True)
class Banque(RevMixin, AclMixin, models.Model):
......
......@@ -73,7 +73,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% can_delete facture %}
{% include 'buttons/suppr.html' with href='cotisations:del-facture' id=facture.id %}
{% acl_end %}
{% history_button facture text=True html_class=False %}
{% history_button facture %}
</td>
<td>
{% if facture.valid %}
......
# coding: utf-8
# 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.
......@@ -24,6 +25,7 @@ Module in charge of rendering some LaTex templates.
Used to generated PDF invoice.
"""
import tempfile
from subprocess import Popen, PIPE
import os
......
......@@ -75,8 +75,7 @@ from .forms import (
DelPaiementForm,
BanqueForm,
DelBanqueForm,
SelectUserArticleForm,
SelectClubArticleForm,
SelectArticleForm,
RechargeForm,
CustomInvoiceForm
)
......@@ -110,16 +109,10 @@ def new_facture(request, user, userid):
creation=True
)
if request.user.is_class_club:
article_formset = formset_factory(SelectClubArticleForm)(
request.POST or None,
form_kwargs={'user': request.user}
)
else:
article_formset = formset_factory(SelectUserArticleForm)(
request.POST or None,
form_kwargs={'user': request.user}
)
article_formset = formset_factory(SelectArticleForm)(
request.POST or None,
form_kwargs={'user': request.user, 'target_user': user}
)
if invoice_form.is_valid() and article_formset.is_valid():
new_invoice_instance = invoice_form.save(commit=False)
......@@ -199,16 +192,12 @@ def new_custom_invoice(request):
)
# Building the invocie form and the article formset
invoice_form = CustomInvoiceForm(request.POST or None)
if request.user.is_class_club:
articles_formset = formset_factory(SelectClubArticleForm)(
request.POST or None,
form_kwargs={'user': request.user}
)
else:
articles_formset = formset_factory(SelectUserArticleForm)(
request.POST or None,
form_kwargs={'user': request.user}
)
article_formset = formset_factory(SelectArticleForm)(
request.POST or None,
form_kwargs={'user': request.user, 'target_user': user}
)
if invoice_form.is_valid() and articles_formset.is_valid():
new_invoice_instance = invoice_form.save()
for art_item in articles_formset:
......@@ -838,7 +827,7 @@ def credit_solde(request, user, **_kwargs):
kwargs={'userid': user.id}
))
refill_form = RechargeForm(request.POST or None, user=request.user)
refill_form = RechargeForm(request.POST or None, user=user, user_source=request.user)
if refill_form.is_valid():
price = refill_form.cleaned_data['value']
invoice = Facture(user=user)
......@@ -865,7 +854,7 @@ def credit_solde(request, user, **_kwargs):
p = get_object_or_404(Paiement, is_balance=True)
return form({
'factureform': refill_form,
'balance': request.user.solde,
'balance': user.solde,
'title': _("Refill your balance"),
'action_name': _("Pay"),
'max_balance': p.payment_method.maximum_balance,
......
......@@ -110,11 +110,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<td>{{ v.datetime }}</td>
<td>
{% blocktrans with username=v.username number=v.version.object.number name=v.version.object.name %}{{ username }} has sold {{ number }}x {{ name }} to{% endblocktrans %}
<a href="{% url 'users:profil' v.version.object.facture.user_id %}">{{ v.version.object.facture.user.get_username }}</a>
{% blocktrans with username=v.username number=v.version.object.number name=v.version.object.name %}{{ username }} has sold {{ number }}x {{ name }}{% endblocktrans %}
{% with invoice=v.version.object.facture %}
{% if invoice|is_facture %}
{% trans " to" %}
<a href="{% url 'users:profil' v.version.object.facture.facture.user_id %}">{{ v.version.object.facture.facture.user.get_username }}</a>
{% if v.version.object.iscotisation %}
(<i>{% blocktrans with duration=v.version.object.duration %}+{{ duration }} months{% endblocktrans %}</i>)
{% endif %}
{% endif %}
{% endwith %}
</td>
{% can_edit_history %}
<td>
......
......@@ -19,7 +19,7 @@
#
# 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.
# 51 Franklin Street, Fifth Floor, Boston, MA 021}10-1301 USA.
"""logs.templatetags.logs_extra
A templatetag to get the class name for a given object
"""
......@@ -34,6 +34,10 @@ def classname(obj):
""" Returns the object class name """
return obj.__class__.__name__
@register.filter
def is_facture(baseinvoice):
"""Returns True if a baseinvoice has a `Facture` child."""
return hasattr(baseinvoice, 'facture')
@register.inclusion_tag('buttons/history.html')
def history_button(instance, text=False, html_class=True):
......
......@@ -52,7 +52,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td colspan="4">
{% trans "No name" as tr_no_name %}
{% trans "View the profile" as tr_view_the_profile %}
<b>{{ machine.name|default:'<i>tr_no_name</i>' }}</b> <i class="fa-angle-right"></i>
<b>{{ machine.name|default:tr_no_name }}</b> <i class="fa-angle-right"></i>
<a href="{% url 'users:profil' userid=machine.user.id %}" title=tr_view_the_profile>
<i class="fa fa-user"></i> {{ machine.user }}
</a>
......
......@@ -153,7 +153,7 @@ def generate_ipv4_choices(form_obj):
"""
f_ipv4 = form_obj.fields['ipv4']
used_mtype_id = []
choices = '{"":[{key:"",value:'+_("Select a machine type first.},")
choices = '{"":[{key:"",value:"'+_("Select a machine type first.") + '"}'
mtype_id = -1
for ip in (f_ipv4.queryset
......
......@@ -124,7 +124,8 @@ class EditGeneralOptionForm(ModelForm):
prefix=prefix,
**kwargs
)
self.fields['general_message'].label = _("General message")
self.fields['general_message_fr'].label = _("General message in French")
self.fields['general_message_en'].label = _("General message in English")
self.fields['search_display_page'].label = _("Number of results"
" displayed when"
" searching")
......@@ -167,9 +168,6 @@ class EditAssoOptionForm(ModelForm):
self.fields['pseudo'].label = _("Usual name")
self.fields['utilisateur_asso'].label = _("Account used for editing"
" from /admin")
self.fields['payment'].label = _("Payment")
self.fields['payment_id'].label = _("Payment ID")
self.fields['payment_pass'].label = _("Payment password")
self.fields['description'].label = _("Description")
......
......@@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-08-15 16:11+0200\n"
"POT-Creation-Date: 2018-08-23 15:03+0200\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
......@@ -185,12 +185,56 @@ msgstr "Historique de %(object)s"
msgid "Home"
msgstr "Accueil"
#: templates/re2o/index.html:33
#: templates/re2o/index.html:34
#, python-format
msgid "Welcome to %(name_website)s!"
msgstr "Bienvenue sur %(name_website)s !"
msgid "Welcome to %(name_website)s"
msgstr "Bienvenue sur %(name_website)s"
#: templates/re2o/index.html:47
#: templates/re2o/index.html:43 templates/re2o/index.html:45
msgid "Registration"
msgstr "Inscription"
#: templates/re2o/index.html:44
msgid ""
"If you don't have an account yet and you want to access the Internet and the "
"organisation's services, create your own personal account."
msgstr ""
"Si vous n'avez pas encore de compte et que vous voulez accéder à Internet et "
"aux services de l'association, créez votre espace personnel."
#: templates/re2o/index.html:55 templates/re2o/index.html:57
msgid "Logging in"
msgstr "Identification"
#: templates/re2o/index.html:56
msgid ""
"If you already have an account, log in. You can manage your subscription to "
"the organisation, your machines and all your services."
msgstr ""
"Si vous avez déjà un compte, identifiez-vous. Vous pouvez gérer votre "
"cotisation à l'association, vos machines et tous vos services."
#: templates/re2o/index.html:68
msgid "My profile"
msgstr "Mon profil"
#: templates/re2o/index.html:69
msgid ""
"To manage your subscription, your machines and all your services, access "
"your profile."
msgstr ""
"Pour gérer votre cotisation, vos machines et tous vos services, accéder à "
"votre profil."
#: templates/re2o/index.html:70
msgid "Access my profile"
msgstr "Accéder à mon profil"
#: templates/re2o/index.html:79
msgid "Services of the organisation"
msgstr "Serices de l'association"
#: templates/re2o/index.html:93
msgid "Go there"
msgstr "Accéder"
......
......@@ -30,8 +30,54 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}{% trans "Home" %}{% endblock %}
{% block content %}
<h1>{% blocktrans %}Welcome to {{ name_website }}!{% endblocktrans %}</h1>
<div class="panel-heading">
<h2>{% blocktrans %}Welcome to {{ name_website }}{% endblocktrans %}</h2>
</div>
{% if not request.user.is_authenticated %}
<div class="row">
{% if var_sa %}
<div class="col-sm-6 col-md-6">
<div class="col-12">
<div class="thumbnail">
<div class="caption">
<h3>{% trans "Registration" %}</h3>
<p>{% trans "If you don't have an account yet and you want to access the Internet and the organisation's services, create your own personal account." %}</p>
<p><a href="{% url 'users:new-user' %}" class="btn btn-primary" role="button">{% trans "Registration" %}</a></p>
</div>
</div>
</div>
</div>
{% endif %}
<div class="col-sm-6 col-md-6">
<div class="col-12">
<div class="thumbnail">
<div class="caption">
<h3>{% trans "Logging in" %}</h3>
<p>{% trans "If you already have an account, log in. You can manage your subscription to the organisation, your machines and all your services." %}</p>
<p><a href="{% url 'login' %}" class="btn btn-primary" role="button">{% trans "Logging in" %}</a></p>
</div>
</div>
</div>
</div>
{% else %}
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="col-12">
<div class="thumbnail">
<div class="caption">
<h3>{% trans "My profile" %}</h3>
<p>{% trans "To manage your subscription, your machines and all your services, access your profile." %}</p>
<p><a href="{% url 'users:mon-profil' %}" class="btn btn-primary" role="button">{% trans "Access my profile" %}</a></p>
</div>
</div>
</div>
</div>
{% endif %}
</div>
<div class="panel-heading">
<h2>{% trans "Services of the organisation" %}</h2>
</div>
<div class="row">
{% for service_list in services_urls %}
<div class="col-sm-6 col-md-4">
......
......@@ -316,6 +316,9 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
self.fields['room'].label = _("Room")
self.fields['room'].empty_label = _("No room")
self.fields['school'].empty_label = _("Select a school")
self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.")
if 'shell' in self.fields:
self.fields['shell'].empty_label = _("Default shell")
def clean_email(self):
if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get('email'):
......@@ -334,9 +337,9 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
'email',
'school',
'comment',
'telephone',
'room',
'shell',
'telephone',
'gpg_fingerprint'
]
......
This diff is collapsed.
......@@ -49,10 +49,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<i class="text-danger">{% blocktrans with end_ban=users.end_ban|date:"SHORT_DATE_FORMAT" %}End of the ban: {{ end_ban }}{% endblocktrans %}</i>
</div>
</div>
{% elif not users.is_adherent %}
{% elif not users.has_access %}
<div class="panel panel-danger">
<div class="panel-heading dashboard">{% trans "No connection" %}</div>
<div class="panel-body dashboard">
<div class="panel-body dashboard">
{% can_create Facture %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}">
<i class="fas fa-sign-in-alt"></i> {% trans "Pay for a connection" %}
......@@ -64,9 +64,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</div>
{% else %}
<div class="panel panel-success">
<div class="panel-heading dashboard">{% trans "Connection" %}</div>
<div class="panel-heading dashboard">{% blocktrans with end_connection=users.end_access|date:"SHORT_DATE_FORMAT" %}Connection (until {{ end_connection }} ){% endblocktrans %}</div>
<div class="panel-body dashboard">
<i class="text-success">{% blocktrans with end_connection=user.end_adhesion|date:"SHORT_DATE_FORMAT" %}End of connection: {{ end_connection }}{% endblocktrans %}</i>
{% can_create Facture %}
<a class="btn btn-success btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}">
<i class="fas fa-sign-in-alt"></i> {% trans "Extend the connection period" %}
</a>
{% acl_end %}
</div>
</div>
{% endif %}
......@@ -89,7 +93,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if nb_machines %}
<div class="panel panel-info">
<div class="panel-heading dashboard" data-parent="#accordion" data-toggle="collapse" data-target="#collapse3">
<i class="fa fa-desktop"></i>{% trans " Machines" %}<span class="badge">{{ nb_machines }}</span>
<i class="fa fa-desktop"></i>{% trans " Machines" %} <span class="badge"> {{ nb_machines }}</span>
</div>
<div class="panel-body dashboard">
<a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:new-machine' users.id %}">
......