diff --git a/accounting/templates/accounting/refound_account.jinja b/accounting/templates/accounting/refound_account.jinja new file mode 100644 index 00000000..ff4995ac --- /dev/null +++ b/accounting/templates/accounting/refound_account.jinja @@ -0,0 +1,14 @@ +{% extends "core/base.jinja" %} + +{% block title %} +{% trans %}Refound account{% endtrans %} +{% endblock %} + +{% block content %} +

{% trans %}Refound account{% endtrans %}

+
+ {% csrf_token %} + {{ form.as_p() }} +

+
+{% endblock %} \ No newline at end of file diff --git a/accounting/tests.py b/accounting/tests.py index 7ce503c2..44fb84e9 100644 --- a/accounting/tests.py +++ b/accounting/tests.py @@ -1,3 +1,47 @@ -from django.test import TestCase +from django.test import Client, TestCase +from django.core.urlresolvers import reverse +from django.contrib.auth.models import Group +from django.core.management import call_command +from django.conf import settings -# Create your tests here. +from core.models import User +from counter.models import Counter + + +class RefoundAccountTest(TestCase): + def setUp(self): + call_command("populate") + self.skia = User.objects.filter(username="skia").first() + # reffil skia's account + self.skia.customer.amount = 800 + self.skia.customer.save() + + def test_permission_denied(self): + self.client.login(useername='guy', password='plop') + response_post = self.client.post(reverse("accounting:refound_account"), + {"user": self.skia.id}) + response_get = self.client.get(reverse("accounting:refound_account")) + self.assertTrue(response_get.status_code == 403) + self.assertTrue(response_post.status_code == 403) + + def test_root_granteed(self): + self.client.login(username='root', password='plop') + response_post = self.client.post(reverse("accounting:refound_account"), + {"user": self.skia.id}) + self.skia = User.objects.filter(username='skia').first() + response_get = self.client.get(reverse("accounting:refound_account")) + self.assertFalse(response_get.status_code == 403) + self.assertTrue('
' in str(response_get.content)) + self.assertFalse(response_post.status_code == 403) + self.assertTrue(self.skia.customer.amount == 0) + + def test_comptable_granteed(self): + self.client.login(username='comptable', password='plop') + response_post = self.client.post(reverse("accounting:refound_account"), + {"user": self.skia.id}) + self.skia = User.objects.filter(username='skia').first() + response_get = self.client.get(reverse("accounting:refound_account")) + self.assertFalse(response_get.status_code == 403) + self.assertTrue('' in str(response_get.content)) + self.assertFalse(response_post.status_code == 403) + self.assertTrue(self.skia.customer.amount == 0) diff --git a/accounting/urls.py b/accounting/urls.py index fcd4a5f8..379f7dc4 100644 --- a/accounting/urls.py +++ b/accounting/urls.py @@ -38,6 +38,8 @@ urlpatterns = [ url(r'^label/(?P[0-9]+)$', LabelListView.as_view(), name='label_list'), url(r'^label/(?P[0-9]+)/edit$', LabelEditView.as_view(), name='label_edit'), url(r'^label/(?P[0-9]+)/delete$', LabelDeleteView.as_view(), name='label_delete'), + # User account + url(r'^refound/account$', RefoundAccountView.as_view(), name='refound_account'), ] diff --git a/accounting/views.py b/accounting/views.py index 10b667fe..8b2b96b4 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -1,9 +1,13 @@ from django.views.generic import ListView, DetailView, RedirectView -from django.views.generic.edit import UpdateView, CreateView, DeleteView +from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView from django.shortcuts import render -from django.core.urlresolvers import reverse_lazy +from django.core.urlresolvers import reverse_lazy, reverse +from django.utils.translation import ugettext_lazy as _ from django.forms.models import modelform_factory +from django.core.exceptions import PermissionDenied from django.forms import HiddenInput +from django.db import transaction +from django.conf import settings from django import forms from django.http import HttpResponseRedirect, HttpResponse from django.utils.translation import ugettext as _ @@ -15,6 +19,7 @@ from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultip from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin from core.views.forms import SelectFile, SelectDate from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType, Label +from counter.models import Counter, Selling # Main accounting view @@ -481,3 +486,49 @@ class LabelDeleteView(CanEditMixin, DeleteView): def get_success_url(self): return self.object.get_absolute_url() + +class CloseCustomerAccountForm(forms.Form): + user = AutoCompleteSelectField('users', label=_('Refound this account'), help_text=None, required=True) + +class RefoundAccountView(FormView): + """ + Create a selling with the same amount than the current user money + """ + template_name = "accounting/refound_account.jinja" + form_class = CloseCustomerAccountForm + + def permission(self, user): + if user.is_root or user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']): + return True + else: + raise PermissionDenied + + def dispatch(self, request, *arg, **kwargs): + res = super(RefoundAccountView, self).dispatch(request, *arg, **kwargs) + if self.permission(request.user): + return res + + def post(self, request, *arg, **kwargs): + self.operator = request.user + if self.permission(request.user): + return super(RefoundAccountView, self).post(self, request, *arg, **kwargs) + + def form_valid(self, form): + self.customer = form.cleaned_data['user'] + self.create_selling() + return super(RefoundAccountView, self).form_valid(form) + + def get_success_url(self): + return reverse('accounting:refound_account') + + def create_selling(self): + with transaction.atomic(): + uprice = self.customer.customer.amount + main_club_counter = Counter.objects.filter(club__unix_name=settings.SITH_MAIN_CLUB['unix_name'], + type='OFFICE').first() + main_club = main_club_counter.club + s = Selling(label=_('Refound account'), unit_price=uprice, + quantity=1, seller=self.operator, + customer=self.customer.customer, + club=main_club, counter=main_club_counter) + s.save() diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index e0d7b79e..6ec34e54 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -67,6 +67,7 @@ class Command(BaseCommand): c.save() self.reset_index("counter") Counter(name="Eboutic", club=main_club, type='EBOUTIC').save() + Counter(name="AE", club=main_club, type='OFFICE').save() home_root.view_groups = [Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()] club_root.view_groups = [Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first()] diff --git a/core/templates/core/user_tools.jinja b/core/templates/core/user_tools.jinja index bd79f4c3..855f3ce2 100644 --- a/core/templates/core/user_tools.jinja +++ b/core/templates/core/user_tools.jinja @@ -43,6 +43,7 @@

{% trans %}Accounting{% endtrans %}

    {% if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']) or user.is_root %} +
  • {% trans %}Refound Account{% endtrans %}
  • {% trans %}General accounting{% endtrans %}
  • {% endif %} {% for m in user.memberships.filter(end_date=None).filter(role__gte=7).all() -%} diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 6ec2c920..c341015f 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-11-29 12:34+0100\n" +"POT-Creation-Date: 2016-11-29 15:16+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -296,7 +296,7 @@ msgstr "Il n'y a pas de types comptable dans ce site web." #: accounting/templates/accounting/bank_account_details.jinja:4 #: accounting/templates/accounting/bank_account_details.jinja:13 -#: core/templates/core/user_tools.jinja:50 +#: core/templates/core/user_tools.jinja:51 msgid "Bank account: " msgstr "Compte en banque : " @@ -515,7 +515,7 @@ msgid "Done" msgstr "Effectué" #: accounting/templates/accounting/journal_details.jinja:37 -#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:711 +#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:712 msgid "Comment" msgstr "Commentaire" @@ -556,6 +556,16 @@ msgstr "Éditer l'opération" msgid "Save" msgstr "Sauver" +#: accounting/templates/accounting/refound_account.jinja:4 +#: accounting/templates/accounting/refound_account.jinja:8 +#: accounting/views.py:399 +msgid "Refound account" +msgstr "Remboursement de compte" + +#: accounting/templates/accounting/refound_account.jinja:12 +msgid "Refound" +msgstr "Rembourser" + #: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:4 #: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:15 msgid "Simplified type list" @@ -608,6 +618,10 @@ msgstr "Créditeur" msgid "Comment:" msgstr "Commentaire :" +#: accounting/views.py:491 +msgid "Refound this account" +msgstr "Rembourser ce compte" + #: club/models.py:21 msgid "unix name" msgstr "nom unix" @@ -808,7 +822,7 @@ msgid "Payment method" msgstr "Méthode de paiement" #: club/templates/club/club_tools.jinja:4 -#: core/templates/core/user_tools.jinja:74 +#: core/templates/core/user_tools.jinja:75 msgid "Club tools" msgstr "Outils club" @@ -851,16 +865,16 @@ msgstr "Choisir un utilisateur" msgid "You do not have the permission to do that" msgstr "Vous n'avez pas la permission de faire cela" -#: club/views.py:165 counter/views.py:909 +#: club/views.py:165 counter/views.py:910 msgid "Begin date" msgstr "Date de début" -#: club/views.py:166 counter/views.py:910 +#: club/views.py:166 counter/views.py:911 msgid "End date" msgstr "Date de fin" #: club/views.py:180 core/templates/core/user_stats.jinja:27 -#: counter/views.py:990 +#: counter/views.py:991 msgid "Product" msgstr "Produit" @@ -2027,22 +2041,26 @@ msgid "Stats" msgstr "Stats" #: core/templates/core/user_tools.jinja:46 +msgid "Refound Account" +msgstr "Rembourser un compte" + +#: core/templates/core/user_tools.jinja:47 msgid "General accounting" msgstr "Comptabilité générale" -#: core/templates/core/user_tools.jinja:55 +#: core/templates/core/user_tools.jinja:56 msgid "Club account: " msgstr "Compte club : " -#: core/templates/core/user_tools.jinja:62 +#: core/templates/core/user_tools.jinja:63 msgid "Communication" msgstr "Communication" -#: core/templates/core/user_tools.jinja:65 +#: core/templates/core/user_tools.jinja:66 msgid "Moderate files" msgstr "Modérer les fichiers" -#: core/templates/core/user_tools.jinja:68 +#: core/templates/core/user_tools.jinja:69 msgid "Moderate pictures" msgstr "Modérer les photos" @@ -2351,7 +2369,7 @@ msgstr "Liste des relevés de caisse" msgid "Theoric sums" msgstr "Sommes théoriques" -#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:712 +#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:713 msgid "Emptied" msgstr "Coffre vidé" @@ -2609,57 +2627,57 @@ msgstr "Produit parent" msgid "Buying groups" msgstr "Groupes d'achat" -#: counter/views.py:691 +#: counter/views.py:692 msgid "10 cents" msgstr "10 centimes" -#: counter/views.py:692 +#: counter/views.py:693 msgid "20 cents" msgstr "20 centimes" -#: counter/views.py:693 +#: counter/views.py:694 msgid "50 cents" msgstr "50 centimes" -#: counter/views.py:694 +#: counter/views.py:695 msgid "1 euro" msgstr "1 €" -#: counter/views.py:695 +#: counter/views.py:696 msgid "2 euros" msgstr "2 €" -#: counter/views.py:696 +#: counter/views.py:697 msgid "5 euros" msgstr "5 €" -#: counter/views.py:697 +#: counter/views.py:698 msgid "10 euros" msgstr "10 €" -#: counter/views.py:698 +#: counter/views.py:699 msgid "20 euros" msgstr "20 €" -#: counter/views.py:699 +#: counter/views.py:700 msgid "50 euros" msgstr "50 €" -#: counter/views.py:700 +#: counter/views.py:701 msgid "100 euros" msgstr "100 €" -#: counter/views.py:701 counter/views.py:703 counter/views.py:705 -#: counter/views.py:707 counter/views.py:709 +#: counter/views.py:702 counter/views.py:704 counter/views.py:706 +#: counter/views.py:708 counter/views.py:710 msgid "Check amount" msgstr "Montant du chèque" -#: counter/views.py:702 counter/views.py:704 counter/views.py:706 -#: counter/views.py:708 counter/views.py:710 +#: counter/views.py:703 counter/views.py:705 counter/views.py:707 +#: counter/views.py:709 counter/views.py:711 msgid "Check quantity" msgstr "Nombre de chèque" -#: counter/views.py:1061 +#: counter/views.py:1062 msgid "people(s)" msgstr "personne(s)"