8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-23 07:23:46 +00:00

Merge branch 'add_deposit_app' into 'dev'

feat: Create deposits app

See merge request re2o/re2o!622
This commit is contained in:
nanoy 2021-08-07 22:28:19 +00:00
commit 71e219735b
23 changed files with 1634 additions and 0 deletions

0
deposits/__init__.py Normal file
View file

41
deposits/admin.py Normal file
View file

@ -0,0 +1,41 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
"""
Deposit admin model
"""
from django.contrib import admin
from reversion.admin import VersionAdmin
from .models import Deposit, DepositItem
class DepositAdmin(VersionAdmin):
pass
class DepositItemAdmin(VersionAdmin):
pass
admin.site.register(Deposit, DepositAdmin)
admin.site.register(DepositItem, DepositItemAdmin)

27
deposits/apps.py Normal file
View file

@ -0,0 +1,27 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
from django.apps import AppConfig
class DepositsConfig(AppConfig):
"""Configuration of the optional deposits app."""
name = "deposits"

89
deposits/forms.py Normal file
View file

@ -0,0 +1,89 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
"""
Deposit form
"""
from django import forms
from django.forms import Form, ModelForm
from django.utils.translation import ugettext_lazy as _
from re2o.mixins import FormRevMixin
from .models import Deposit, DepositItem
class DepositForm(FormRevMixin, ModelForm):
"""
Form used to manage and create an invoice and its fields.
"""
def __init__(self, *args, creation=False, **kwargs):
user = kwargs.pop("user")
super(DepositForm, self).__init__(*args, **kwargs)
# Set the fields' label to handle translation
self.fields["item"].label = _("Deposit item")
self.fields["payment_method"].label = _("Payment method")
self.fields["returned"].label = _("Deposit returned")
if creation:
# During creation, we only need to select the item and payment
# method, no need to add the "returned" checkbox
self.fields = {
"item": self.fields["item"],
"payment_method": self.fields["payment_method"],
}
class Meta:
model = Deposit
fields = ("item", "payment_method", "returned")
class DepositItemForm(FormRevMixin, ModelForm):
"""
Form used to create a deposit item.
"""
class Meta:
model = DepositItem
fields = "__all__"
class DelDepositItemForm(FormRevMixin, Form):
"""
Form used to delete one or more of the currently available deposit items.
The user must choose the one to delete by checking the boxes.
"""
deposit_items = forms.ModelMultipleChoiceField(
queryset=DepositItem.objects.none(),
label=_("Current deposit items"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelDepositItemForm, self).__init__(*args, **kwargs)
if instances:
self.fields["deposit_items"].queryset = instances
else:
self.fields["deposit_items"].queryset = DepositItem.objects.all()

View file

@ -0,0 +1,293 @@
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-07 23:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: deposits/forms.py:44 deposits/templates/deposits/aff_deposit_item.html:31
#: deposits/views.py:301
msgid "Deposit item"
msgstr "Article (caution)"
#: deposits/forms.py:45 deposits/templates/deposits/aff_deposits.html:48
#: deposits/views.py:272
msgid "Payment method"
msgstr "Moyen de paiement"
#: deposits/forms.py:46
msgid "Deposit returned"
msgstr "Caution rendue"
#: deposits/forms.py:79
msgid "Current deposit items"
msgstr "Articles sous cautions actuels"
#: deposits/models.py:52
msgid "date"
msgstr "date"
#: deposits/models.py:53
msgid "returned"
msgstr "rendue"
#: deposits/models.py:55 deposits/models.py:140
msgid "deposit amount"
msgstr "montant de la caution"
#: deposits/models.py:60 deposits/views.py:116
msgid "deposit"
msgstr "caution"
#: deposits/models.py:61
msgid "deposits"
msgstr "cautions"
#: deposits/models.py:70
#, python-brace-format
msgid "Deposit from {name} for {item} at {date}, returned"
msgstr "Caution de {name} pour {item} à {date}, rendue"
#: deposits/models.py:77
#, python-brace-format
msgid "Deposit from {name} for {item} at {date}, not yet returned"
msgstr "Caution de {name} pour {item} à {date}, pas encore rendue"
#: deposits/models.py:105
msgid "You don't have the right to view other deposits than yours."
msgstr "Vous n'avez pas le droit de voir les cautions d'autres utilisateurs."
#: deposits/models.py:117
msgid "You don't have the right to view the list of deposits."
msgstr "Vous n'avez pas le droit de voir la liste des cautions."
#: deposits/models.py:137
msgid "designation"
msgstr "désignation"
#: deposits/models.py:145
msgid "deposit item"
msgstr "article (caution)"
#: deposits/models.py:146
msgid "deposit items"
msgstr "articles (cautions)"
#: deposits/templates/deposits/aff_deposit_item.html:32
#: deposits/templates/deposits/aff_deposits.html:44 deposits/views.py:276
#: deposits/views.py:305 deposits/views.py:338
msgid "Amount"
msgstr "Montant"
#: deposits/templates/deposits/aff_deposits.html:36
msgid "User"
msgstr "Utilisateur"
#: deposits/templates/deposits/aff_deposits.html:40
msgid "Item"
msgstr "Article (caution)"
#: deposits/templates/deposits/aff_deposits.html:52
msgid "Date"
msgstr "Date"
#: deposits/templates/deposits/aff_deposits.html:56
msgid "Returned"
msgstr "Rendue"
#: deposits/templates/deposits/aff_profil.html:29
#: deposits/templates/deposits/navbar.html:25
msgid "Deposits"
msgstr "Cautions"
#: deposits/templates/deposits/aff_profil.html:36
msgid "Add a deposit"
msgstr "Ajouter une caution"
#: deposits/templates/deposits/aff_profil.html:44
msgid "No deposit"
msgstr "Pas de caution"
#: deposits/templates/deposits/delete.html:27
msgid "Deletion of deposit items"
msgstr "Suppression d'articles sous caution"
#: deposits/templates/deposits/delete.html:34
#, python-format
msgid ""
"Warning: are you sure you really want to delete this %(objet_name)s object "
"( %(objet)s )?"
msgstr ""
"Attention: voulez-vous vraiment supprimer cet objet %(objet_name)s "
"( %(objet)s ) ?"
#: deposits/templates/deposits/delete.html:36 deposits/views.py:72
msgid "Confirm"
msgstr "Confirmer"
#: deposits/templates/deposits/deposit.html:28
msgid "Create or edit deposit"
msgstr "Créer ou modifier une caution"
#: deposits/templates/deposits/deposit.html:35 deposits/views.py:179
msgid "Add"
msgstr "Ajouter"
#: deposits/templates/deposits/index_deposit_item.html:27
#: deposits/templates/deposits/navbar.html:33
msgid "Deposit items"
msgstr "Articles sous caution"
#: deposits/templates/deposits/index_deposit_item.html:30
msgid "List of deposit items"
msgstr "Liste des articles sous caution"
#: deposits/templates/deposits/index_deposit_item.html:33
msgid "Add a deposit item"
msgstr "Ajouter un article"
#: deposits/templates/deposits/index_deposit_item.html:36
msgid "Delete one or several deposit items"
msgstr "Supprimer ou un plusieurs articles"
#: deposits/templates/deposits/index_deposits.html:29
msgid "List of deposits"
msgstr "Liste des cautions"
#: deposits/templates/deposits/index_deposits.html:35
msgid "Deposit"
msgid_plural "Deposits"
msgstr[0] "Caution"
msgstr[1] "Cautions"
#: deposits/templates/deposits/index_deposits.html:38
msgid "Unreturned deposit"
msgid_plural "Unreturned deposits"
msgstr[0] "Caution non rendue"
msgstr[1] "Cautions non rendues"
#: deposits/templates/deposits/index_deposits.html:45 deposits/views.py:274
#: deposits/views.py:303
msgid "Unreturned deposits"
msgstr "Cautions non rendues"
#: deposits/templates/deposits/index_deposits.html:56 deposits/views.py:273
#: deposits/views.py:302
msgid "Returned deposits"
msgstr "Cautions rendues"
#: deposits/templates/deposits/index_stats.html:28
#: deposits/templates/deposits/index_stats.html:31
#: deposits/templates/deposits/navbar.html:36
msgid "Deposits statistics"
msgstr "Statistiques sur les cautions"
#: deposits/templates/deposits/navbar.html:30
msgid "View deposits"
msgstr "Voir les cautions"
#: deposits/views.py:66
msgid "The deposit was created."
msgstr "La caution a été créée."
#: deposits/views.py:73
msgid "New deposit"
msgstr "Nouvelle caution"
#: deposits/views.py:91
msgid "The deposit was edited."
msgstr "La caution a été modifiée."
#: deposits/views.py:97 deposits/views.py:202
msgid "Edit"
msgstr "Modifier"
#: deposits/views.py:98
msgid "Edit deposit"
msgstr "Modifier la caution"
#: deposits/views.py:113
msgid "The deposit was deleted."
msgstr "La caution a été supprimée."
#: deposits/views.py:174
msgid "The item was created."
msgstr "L'article a été créé."
#: deposits/views.py:180
msgid "New deposit item"
msgstr "Nouvel article (caution)"
#: deposits/views.py:197
msgid "The item was edited."
msgstr "L'article a été modifié."
#: deposits/views.py:203
msgid "Edit deposit item"
msgstr "Modifier l'article"
#: deposits/views.py:220
msgid "The items were deleted."
msgstr "Les articles ont été supprimés."
#: deposits/views.py:225
msgid "Delete"
msgstr "Supprimer"
#: deposits/views.py:226
msgid "Delete deposit item"
msgstr "Supprimer l'article"
#: deposits/views.py:270
msgid "Deposits by payment method"
msgstr "Cautions par moyen de paiement"
#: deposits/views.py:275 deposits/views.py:304 deposits/views.py:337
msgid "Total"
msgstr "Total"
#: deposits/views.py:299
msgid "Deposits by item type"
msgstr "Cautions par type d'article"
#: deposits/views.py:321
msgid "Not yet returned"
msgstr "Pas encore rendues"
#: deposits/views.py:326
msgid "Already returned"
msgstr "Déjà rendues"
#: deposits/views.py:334
msgid "Deposits amounts"
msgstr "Montants de cautions"
#: deposits/views.py:336
msgid "Category"
msgstr "Catégorie"

View file

@ -0,0 +1,51 @@
# Generated by Django 2.2.18 on 2021-08-07 11:08
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import re2o.mixins
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cotisations', '0004_auto_20210208_1827'),
]
operations = [
migrations.CreateModel(
name='DepositItem',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True, verbose_name='designation')),
('deposit_amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='deposit amount')),
],
options={
'verbose_name': 'deposit item',
'verbose_name_plural': 'deposit items',
'abstract': False,
},
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
),
migrations.CreateModel(
name='Deposit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateTimeField(auto_now_add=True, verbose_name='date')),
('returned', models.BooleanField(default=False, verbose_name='returned')),
('deposit_amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='deposit amount')),
('item', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='deposits.DepositItem')),
('payment_method', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cotisations.Paiement')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'deposit',
'verbose_name_plural': 'deposits',
'abstract': False,
},
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
),
]

View file

149
deposits/models.py Normal file
View file

@ -0,0 +1,149 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2019 Arthur Grisel-Davy
# Copyright © 2020 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.
"""
Deposit model
"""
from __future__ import absolute_import
from django.db import models
from django.utils.translation import ugettext_lazy as _
from re2o.mixins import AclMixin, RevMixin
class Deposit(RevMixin, AclMixin, models.Model):
"""
The model for a deposit. It reprensents the fact that a user made a deposit
as a guarantee for an item which should be returned to get the deposit
back.
A deposit is linked to :
* a user (the one who made the deposit)
* an item (borrowed in exchange for the deposit)
Every deposit is dated throught the 'date' value. Its amount is saved in
the 'deposit_amount' in case an item's amount changes later on.
A deposit has a 'returned' value (default: False) which means that the item
was returned by the user and the deposit was payed back.
"""
user = models.ForeignKey("users.User", on_delete=models.PROTECT)
item = models.ForeignKey("DepositItem", on_delete=models.PROTECT)
payment_method = models.ForeignKey("cotisations.Paiement", on_delete=models.PROTECT)
date = models.DateTimeField(auto_now_add=True, verbose_name=_("date"))
returned = models.BooleanField(default=False, verbose_name=_("returned"))
deposit_amount = models.DecimalField(
max_digits=5, decimal_places=2, verbose_name=_("deposit amount")
)
class Meta:
abstract = False
verbose_name = _("deposit")
verbose_name_plural = _("deposits")
def __init__(self, *args, **kwargs):
super(Deposit, self).__init__(*args, **kwargs)
self.__original_item = getattr(self, "item", None)
self.__original_deposit_amount = getattr(self, "deposit_amount", None)
def __str__(self):
if self.returned:
return _("Deposit from {name} for {item} at {date}, returned").format(
name=self.user.get_full_name(),
item=self.item,
date=self.date,
)
else:
return _(
"Deposit from {name} for {item} at {date}, not yet returned"
).format(
name=self.user.get_full_name(),
item=self.item,
date=self.date,
)
def save(self, *args, **kwargs):
# Save the item's deposit amount in the deposit's attribute
self.deposit_amount = self.item.deposit_amount
# If the item didn't change, keep the previous deposit_amount
# This is done in case a DepositItem's deposit_amount is changed, we
# want to make sure deposits created before keep the same amount
if self.__original_deposit_amount and self.item == self.__original_item:
self.deposit_amount = self.__original_deposit_amount
super(Deposit, self).save(*args, **kwargs)
def can_view(self, user_request, *_args, **_kwargs):
"""Check that the user has the right to view the deposit or that it
belongs to them."""
if (
not user_request.has_perm("deposits.view_deposit")
and self.user != user_request
):
return (
False,
_("You don't have the right to view other deposits than yours."),
("deposits.view_deposit",),
)
else:
return True, None, None
@staticmethod
def can_view_all(user_request, *_args, **_kwargs):
"""Check that the user has access to the list of all tickets."""
can = user_request.has_perm("deposits.view_deposit")
return (
can,
_("You don't have the right to view the list of deposits.")
if not can
else None,
("deposits.view_deposit",),
)
class DepositItem(RevMixin, AclMixin, models.Model):
"""An item for a deposit.
Attributes:
name: the name of this deposit item.
deposit_amount: the amount needed to be deposited by users.
"""
name = models.CharField(
max_length=255,
blank=False,
null=False,
unique=True,
verbose_name=_("designation"),
)
deposit_amount = models.DecimalField(
max_digits=5, decimal_places=2, verbose_name=_("deposit amount")
)
class Meta:
abstract = False
verbose_name = _("deposit item")
verbose_name_plural = _("deposit items")
def __str__(self):
return self.name

View file

@ -0,0 +1,48 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
{% load logs_extra %}
{% load design %}
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "Deposit item" %}</th>
<th>{% trans "Amount" %}</th>
<th></th>
</tr>
</thead>
{% for item in item_list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.deposit_amount }} €</td>
<td class="text-right">
{% can_edit item %}
{% include 'buttons/edit.html' with href='deposits:edit-deposit-item' id=item.id %}
{% acl_end %}
{% history_button item %}
</td>
</tr>
{% endfor %}
</table>

View file

@ -0,0 +1,89 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 %}
{% load logs_extra %}
{% block content %}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>
{% trans "User" as tr_user %}
{% include 'buttons/sort.html' with prefix='deposit' col="user" text=tr_user %}
</th>
<th>
{% trans "Item" as tr_item %}
{% include 'buttons/sort.html' with prefix='deposit' col="item" text=tr_item %}
</th>
<th>
{% trans "Amount" as tr_amount %}
{% include 'buttons/sort.html' with prefix='deposit' col="amount" text=tr_amount %}
</th>
<th>
{% trans "Payment method" as tr_payment %}
{% include 'buttons/sort.html' with prefix='deposit' col="payment" text=tr_payment %}
</th>
<th>
{% trans "Date" as tr_date %}
{% include 'buttons/sort.html' with prefix='deposit' col="date" text=tr_date %}
</th>
<th>
{% trans "Returned" as tr_returned %}
{% include 'buttons/sort.html' with prefix='deposit' col="returned" text=tr_returned %}
</th>
<th></th>
</tr>
{% for deposit in deposits_list %}
<tr>
<td><a href="{% url 'users:profil' deposit.user.id %}" role="button">{{ deposit.user.get_short_name }}</a></td>
<td>{{ deposit.item.name }}</td>
<td>{{ deposit.deposit_amount }} €</td>
<td>{{ deposit.payment_method.moyen }}</td>
<td>{{ deposit.date }}</td>
{% if deposit.returned %}
<td><i class="fa fa-check" style="color:green"></i></td>
{% else %}
<td><i class="fa fa-times" style="color:red"></i></td>
{% endif %}
<td class="text-right">
{% can_edit deposit %}
{% include 'buttons/edit.html' with href='deposits:edit-deposit' id=deposit.id %}
{% acl_end %}
{% history_button deposit %}
</td>
</tr>
{% endfor %}
</thead>
</table>
{% if deposits_list.paginator and show_pagination is not False %}
{% include 'pagination.html' with list=deposits_list go_to_id="deposits" %}
{% endif %}
</div>
{% endblock %}

View file

@ -0,0 +1,48 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
<div class="panel panel-default">
<div class="panel-heading clearfix profil" data-parent="#accordion" data-toggle="collapse" data-target="#deposits">
<h3 class="panel-title pull-left">
<i class="fa fa-balance-scale"></i> {% trans "Deposits" %}
</h3>
</div>
<div id="deposits" class="panel-collapse collapse">
<div class="panel-body">
{% can_create Deposit %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'deposits:new-deposit' users.id %}">
<i class="fa fa-balance-scale"></i> {% trans "Add a deposit" %}
</a>
{% acl_end %}
</div>
<div class="panel-body">
{% if deposits_list %}
{% include 'deposits/aff_deposits.html' with deposits_list=deposits_list %}
{% else %}
<p>{% trans "No deposit" %}</p>
{% endif %}
</div>
</div>
</div>

View file

@ -0,0 +1,40 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 %}
<h3>{{ stats_dict.title }}</h3>
<table class="table table-striped">
<thead>
<tr>
{% for header in stats_dict.headers %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
{% for stats in stats_dict.data %}
<tr>
{% for item in stats %}
<td>{{ item }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>

View file

@ -0,0 +1,39 @@
{% extends 'deposits/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
{% block title %}{% trans "Deletion of deposit items" %}{% endblock %}
{% block content %}
<form class="form" method="post">
{% csrf_token %}
<h4>
{% blocktrans %}Warning: are you sure you really want to delete this {{ objet_name }} object ( {{ objet }} )?{% endblocktrans %}
</h4>
{% trans "Confirm" as tr_confirm %}
{% bootstrap_button tr_confirm button_type='submit' icon='trash' button_class='btn-danger' %}
</form>
{% endblock %}

View file

@ -0,0 +1,44 @@
{% extends 'deposits/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 staticfiles%}
{% load i18n %}
{% block title %}{% trans "Create or edit deposit" %}{% endblock %}
{% block content %}
{% if title %}
<h3>{{ title }}</h3>
{% else %}
<h3>{% trans "Add" %}</h3>
{% endif %}
<form class="form" method="post">
{% csrf_token %}
{% bootstrap_form depositform %}
{% bootstrap_button action_name button_type='submit' icon='ok' button_class='btn-success' %}
</form>
{% endblock %}

View file

@ -0,0 +1,40 @@
{% extends 'deposits/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
{% block title %}{% trans "Deposit items" %}{% endblock %}
{% block content %}
<h2>{% trans "List of deposit items" %}</h2>
{% can_create DepositItem %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'deposits:add-deposit-item' %}">
<i class="fa fa-plus"></i> {% trans "Add a deposit item" %}
</a>
<a class="btn btn-danger btn-sm" role="button" href="{% url 'deposits:del-deposit-item' %}">
<i class="fa fa-trash"></i> {% trans "Delete one or several deposit items" %}
</a>
{% acl_end %}
{% include 'deposits/aff_deposit_item.html' with item_list=item_list %}
{% endblock %}

View file

@ -0,0 +1,64 @@
{% extends 'deposits/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
{% load logs_extra %}
{% block content %}
<h2>{% trans "List of deposits" %}</h2>
<div class="container-fluid">
<hr class="col-sm-12">
<div class="row justify-content-start">
<div class="col-sm-6">
<span class="badge badge-light">&nbsp;{{ nbr_deposits }}</span> {% blocktrans count nb=nbr_deposits %}Deposit{% plural %}Deposits{% endblocktrans %}
</div>
<div class="col-sm-6">
<span class="badge badge-light">&nbsp;{{ nbr_deposits_lent }}</span> {% blocktrans count nb=nbr_deposits_lent %}Unreturned deposit{% plural %}Unreturned deposits{% endblocktrans %}
</div>
</div>
<hr class="col-sm-12">
</div>
<div id="unreturned_deposits">
<h3>{% trans "Unreturned deposits" %}</h2>
{% include 'deposits/aff_deposits.html' with deposits_list=lent_deposits_list show_pagination=False %}
{% if lent_deposits_list.paginator %}
{% include 'pagination.html' with list=lent_deposits_list page_arg='lpage' go_to_id='unreturned_deposits' %}
{% endif %}
</div>
<hr/>
<div id="returned_deposits">
<h3>{% trans "Returned deposits" %}</h2>
{% include 'deposits/aff_deposits.html' with deposits_list=returned_deposits_list show_pagination=False %}
{% if returned_deposits_list.paginator %}
{% include 'pagination.html' with list=returned_deposits_list page_arg='rpage' go_to_id='returned_deposits' %}
{% endif %}
</div>
{% endblock %}

View file

@ -0,0 +1,36 @@
{% extends 'deposits/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
{% block title %}{% trans "Deposits statistics" %}{% endblock %}
{% block content %}
<h2>{% trans "Deposits statistics" %}</h2>
{% for stats_dict in stats_list %}
{% include 'deposits/aff_stats.html' with stats_dict=stats_dict %}
<br/>
{% endfor %}
{% endblock %}

View file

@ -0,0 +1,39 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
<li><a class="dropdown-item" href="#"><i class="fa fa-balance-scale"></i>
{% trans "Deposits" %}
&raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'deposits:index-deposits' %}"><i
class="fa fa-eye"></i>
{% trans "View deposits" %}</a></li>
<li><a class="dropdown-item" href="{% url 'deposits:index-deposit-item' %}"><i
class="fa fa-barcode"></i>
{% trans "Deposit items" %}</a></li>
<li><a class="dropdown-item" href="{% url 'deposits:index-stats' %}"><i
class="fa fa-area-chart"></i>
{% trans "Deposits statistics" %}</a></li>
</ul>
</li>

View file

@ -0,0 +1,28 @@
{% extends 'base.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2021 Jean-Romain Garnier
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 i18n %}
{% block sidebar %}
{% endblock %}

3
deposits/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

45
deposits/urls.py Normal file
View file

@ -0,0 +1,45 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
"""
Deposits url
"""
from django.urls import path
from . import views
app_name = "deposits"
urlpatterns = [
path("new_deposit/<int:userid>", views.new_deposit, name="new-deposit"),
path("edit_deposit/<int:depositid>", views.edit_deposit, name="edit-deposit"),
path("del_deposit/<int:depositid>", views.del_deposit, name="del-deposit"),
path("index_deposits", views.index_deposits, name="index-deposits"),
path("add_deposit_item", views.add_deposit_item, name="add-deposit-item"),
path(
"edit_deposit_item/<int:itemid>",
views.edit_deposit_item,
name="edit-deposit-item",
),
path("del_deposit_item", views.del_deposit_item, name="del-deposit-item"),
path("index_deposit_item", views.index_deposit_item, name="index-deposit-item"),
path("index_stats", views.index_stats, name="index-stats"),
]

38
deposits/utils.py Normal file
View file

@ -0,0 +1,38 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
"""
Deposits utils
"""
from re2o.base import SortTable
class DepositSortTable(SortTable):
"""Extension of the SortTable class to handle the deposit optional app"""
DEPOSIT_INDEX = {
"deposit_user": ["user__pseudo"],
"deposit_item": ["item__name"],
"deposit_payment": ["payment_method__moyen"],
"deposit_date": ["date"],
"deposit_returned": ["returned"],
"deposit_amount": ["deposit_amount"],
"default": ["-date"],
}

383
deposits/views.py Normal file
View file

@ -0,0 +1,383 @@
# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2021 Jean-Romain Garnier
#
# 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.
"""
Deposits views
"""
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.db.models import Sum
from preferences.models import GeneralOption
from re2o.acl import (
can_create,
can_delete,
can_delete_set,
can_edit,
can_view_all,
)
from re2o.base import re2o_paginator
from re2o.views import form
from users.models import User
from cotisations.models import Paiement
from .forms import DepositForm, DepositItemForm, DelDepositItemForm
from .models import Deposit, DepositItem
from .utils import DepositSortTable
@login_required
@can_create(Deposit)
@can_edit(User)
def new_deposit(request, user, userid):
"""
View called to create a new deposit.
"""
deposit = Deposit(user=user)
# Building the invoice form and the article formset
deposit_form = DepositForm(
request.POST or None, instance=deposit, user=request.user, creation=True
)
if deposit_form.is_valid():
deposit_form.save()
messages.success(request, _("The deposit was created."))
return redirect(reverse("users:profil", kwargs={"userid": deposit.user.pk}))
return form(
{
"depositform": deposit_form,
"action_name": _("Confirm"),
"title": _("New deposit"),
},
"deposits/deposit.html",
request,
)
@login_required
@can_edit(Deposit)
def edit_deposit(request, deposit, **_kwargs):
"""
View used to edit an existing deposit.
"""
deposit_form = DepositForm(
request.POST or None, instance=deposit, user=request.user
)
if deposit_form.is_valid():
deposit_form.save()
messages.success(request, _("The deposit was edited."))
return redirect(reverse("users:profil", kwargs={"userid": deposit.user.pk}))
return form(
{
"depositform": deposit_form,
"action_name": _("Edit"),
"title": _("Edit deposit"),
},
"deposits/deposit.html",
request,
)
@login_required
@can_delete(Deposit)
def del_deposit(request, deposit, **_kwargs):
"""
View used to delete an existing deposit.
"""
if request.method == "POST":
deposit.delete()
messages.success(request, _("The deposit was deleted."))
return redirect(reverse("users:profil", kwargs={"userid": deposit.user.pk}))
return form(
{"object": deposit, "objet_name": _("deposit")},
"deposits/delete.html",
request,
)
@login_required
@can_view_all(Deposit, DepositItem, Paiement, User)
def index_deposits(request):
"""
View used to display the list of all deposits.
"""
pagination_number = GeneralOption.get_cached_value("pagination_number")
# Get the list of all deposits, sorted according to the user's request
deposits_list = Deposit.objects.select_related("user", "item", "payment_method")
deposits_list = DepositSortTable.sort(
deposits_list,
request.GET.get("col"),
request.GET.get("order"),
DepositSortTable.DEPOSIT_INDEX,
)
nbr_deposits = deposits_list.count()
# Split it into 2: the list of those which have not yet been returned...
lent_deposits_list = deposits_list.filter(returned=False)
nbr_deposits_lent = lent_deposits_list.count()
lent_deposits_list = re2o_paginator(
request, lent_deposits_list, pagination_number, page_arg="lpage"
)
# ... and the list of those that have already been returned
returned_deposits_list = deposits_list.filter(returned=True)
returned_deposits_list = re2o_paginator(
request, returned_deposits_list, pagination_number, page_arg="rpage"
)
return render(
request,
"deposits/index_deposits.html",
{
"lent_deposits_list": lent_deposits_list,
"returned_deposits_list": returned_deposits_list,
"nbr_deposits": nbr_deposits,
"nbr_deposits_lent": nbr_deposits_lent,
},
)
@login_required
@can_create(DepositItem)
def add_deposit_item(request):
"""
View used to add a deposit item.
"""
item = DepositItemForm(request.POST or None)
if item.is_valid():
item.save()
messages.success(request, _("The item was created."))
return redirect(reverse("deposits:index-deposit-item"))
return form(
{
"depositform": item,
"action_name": _("Add"),
"title": _("New deposit item"),
},
"deposits/deposit.html",
request,
)
@login_required
@can_edit(DepositItem)
def edit_deposit_item(request, item_instance, **_kwargs):
"""
View used to edit a deposit item.
"""
item = DepositItemForm(request.POST or None, instance=item_instance)
if item.is_valid():
if item.changed_data:
item.save()
messages.success(request, _("The item was edited."))
return redirect(reverse("deposits:index-deposit-item"))
return form(
{
"depositform": item,
"action_name": _("Edit"),
"title": _("Edit deposit item"),
},
"deposits/deposit.html",
request,
)
@login_required
@can_delete_set(DepositItem)
def del_deposit_item(request, instances):
"""
View used to delete one of the deposit items.
"""
item = DelDepositItemForm(request.POST or None, instances=instances)
if item.is_valid():
item_del = item.cleaned_data["deposit_items"]
item_del.delete()
messages.success(request, _("The items were deleted."))
return redirect(reverse("deposits:index-deposit-item"))
return form(
{
"depositform": item,
"action_name": _("Delete"),
"title": _("Delete deposit item"),
},
"deposits/deposit.html",
request,
)
@login_required
@can_view_all(DepositItem)
def index_deposit_item(request):
"""
View used to display the list of all available deposit items.
"""
# TODO : Offer other means of sorting
item_list = DepositItem.objects.order_by("name")
return render(request, "deposits/index_deposit_item.html", {"item_list": item_list})
@login_required
@can_view_all(Deposit, DepositItem, Paiement, User)
def index_stats(request):
"""
View used to display general statistics about deposits
"""
# We want to build a list of tables for statistics
stats = []
# Statistics for payment methods
payment_data = []
for method in Paiement.objects.order_by("moyen"):
deposits = Deposit.objects.filter(payment_method=method)
amount = deposits.aggregate(Sum("deposit_amount")).get(
"deposit_amount__sum", None
)
payment_data.append(
(
method.moyen,
deposits.filter(returned=False).count(),
deposits.filter(returned=True).count(),
deposits.count(),
"{}".format(amount or 0),
)
)
stats.append(
{
"title": _("Deposits by payment method"),
"headers": [
_("Payment method"),
_("Unreturned deposits"),
_("Returned deposits"),
_("Total"),
_("Amount"),
],
"data": payment_data,
}
)
# Statistics for deposit items
items_data = []
for item in DepositItem.objects.order_by("name"):
deposits = Deposit.objects.filter(item=item)
amount = deposits.aggregate(Sum("deposit_amount")).get(
"deposit_amount__sum", None
)
items_data.append(
(
item.name,
deposits.filter(returned=False).count(),
deposits.filter(returned=True).count(),
deposits.count(),
"{}".format(amount or 0),
)
)
stats.append(
{
"title": _("Deposits by item type"),
"headers": [
_("Deposit item"),
_("Unreturned deposits"),
_("Returned deposits"),
_("Total"),
_("Amount"),
],
"data": items_data,
}
)
# Statistics for amounts
pending_amount = (
Deposit.objects.filter(returned=False)
.aggregate(Sum("deposit_amount"))
.get("deposit_amount__sum", None)
)
returned_amount = (
Deposit.objects.filter(returned=True)
.aggregate(Sum("deposit_amount"))
.get("deposit_amount__sum", None)
)
amounts_data = [
(
_("Not yet returned"),
Deposit.objects.filter(returned=False).count(),
"{}".format(pending_amount or 0),
),
(
_("Already returned"),
Deposit.objects.filter(returned=True).count(),
"{}".format(returned_amount or 0),
),
]
stats.append(
{
"title": _("Deposits amounts"),
"headers": [
_("Category"),
_("Total"),
_("Amount"),
],
"data": amounts_data,
}
)
return render(request, "deposits/index_stats.html", {"stats_list": stats})
# Canonic views for optional apps
def aff_profil(request, user):
"""View used to display the deposits on a user's profile."""
deposits_list = Deposit.objects.filter(user=user).select_related(
"user", "item", "payment_method"
)
deposits_list = DepositSortTable.sort(
deposits_list,
request.GET.get("col"),
request.GET.get("order"),
DepositSortTable.DEPOSIT_INDEX,
)
pagination_number = GeneralOption.get_cached_value("pagination_large_number")
deposits = re2o_paginator(request, deposits_list, pagination_number)
context = {
"users": user,
"deposits_list": deposits,
}
return render_to_string(
"deposits/aff_profil.html", context=context, request=request, using=None
)
def navbar_user():
"""View used to display a link to deposit items in the navbar (in the dropdown
menu Treasury).
"""
return ("cotisations", render_to_string("deposits/navbar.html"))