diff --git a/accounting/urls.py b/accounting/urls.py deleted file mode 100644 index 3bebe3bb..00000000 --- a/accounting/urls.py +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright 2023 © AE UTBM -# ae@utbm.fr / ae.info@utbm.fr -# -# This file is part of the website of the UTBM Student Association (AE UTBM), -# https://ae.utbm.fr. -# -# You can find the source code of the website at https://github.com/ae-utbm/sith -# -# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) -# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE -# OR WITHIN THE LOCAL FILE "LICENSE" -# -# - -from django.urls import path - -from accounting.views import RefoundAccountView - -urlpatterns = [ - # User account - path("refound/account/", RefoundAccountView.as_view(), name="refound_account"), -] diff --git a/accounting/views.py b/accounting/views.py deleted file mode 100644 index 3331d38e..00000000 --- a/accounting/views.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright 2023 © AE UTBM -# ae@utbm.fr / ae.info@utbm.fr -# -# This file is part of the website of the UTBM Student Association (AE UTBM), -# https://ae.utbm.fr. -# -# You can find the source code of the website at https://github.com/ae-utbm/sith -# -# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) -# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE -# OR WITHIN THE LOCAL FILE "LICENSE" -# -# - - -from django import forms -from django.conf import settings -from django.contrib.auth.mixins import UserPassesTestMixin -from django.db import transaction -from django.urls import reverse -from django.utils.translation import gettext_lazy as _ -from django.views.generic.edit import FormView - -from core.models import User -from core.views.widgets.ajax_select import AutoCompleteSelectUser -from counter.models import Counter, Product, Selling - -# Main accounting view - - -class CloseCustomerAccountForm(forms.Form): - user = forms.ModelChoiceField( - label=_("Refound this account"), - help_text=None, - required=True, - widget=AutoCompleteSelectUser, - queryset=User.objects.all(), - ) - - -class RefoundAccountView(UserPassesTestMixin, FormView): - """Create a selling with the same amount than the current user money.""" - - template_name = "accounting/refound_account.jinja" - form_class = CloseCustomerAccountForm - - def test_func(self): - return self.request.user.is_root or self.request.user.is_in_group( - pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID - ) - - def form_valid(self, form): - self.customer = form.cleaned_data["user"] - self.create_selling() - return super().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 - refound_club_counter = Counter.objects.get( - id=settings.SITH_COUNTER_REFOUND_ID - ) - refound_club = refound_club_counter.club - s = Selling( - label=_("Refound account"), - unit_price=uprice, - quantity=1, - seller=self.request.user, - customer=self.customer.customer, - club=refound_club, - counter=refound_club_counter, - product=Product.objects.get(id=settings.SITH_PRODUCT_REFOUND_ID), - ) - s.save() diff --git a/core/templates/core/user_tools.jinja b/core/templates/core/user_tools.jinja index 29b276a0..399a8c92 100644 --- a/core/templates/core/user_tools.jinja +++ b/core/templates/core/user_tools.jinja @@ -109,7 +109,7 @@

{% trans %}Accounting{% endtrans %}

diff --git a/core/views/user.py b/core/views/user.py index 8e7b092c..8715f36c 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -65,7 +65,7 @@ from core.views.forms import ( UserProfileForm, ) from core.views.mixins import QuickNotifMixin, TabedViewMixin -from counter.models import Refilling, Selling +from counter.models import Counter, Refilling, Selling from eboutic.models import Invoice from subscription.models import Subscription from trombi.views import UserTrombiForm @@ -385,8 +385,6 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView): kwargs = super().get_context_data(**kwargs) from django.db.models import Sum - from counter.models import Counter - foyer = Counter.objects.filter(name="Foyer").first() mde = Counter.objects.filter(name="MDE").first() gommette = Counter.objects.filter(name="La Gommette").first() diff --git a/counter/forms.py b/counter/forms.py index b509b515..ad32557b 100644 --- a/counter/forms.py +++ b/counter/forms.py @@ -3,6 +3,7 @@ from django.utils.translation import gettext_lazy as _ from phonenumber_field.widgets import RegionalPhoneNumberWidget from club.widgets.ajax_select import AutoCompleteSelectClub +from core.models import User from core.views.forms import NFCTextInput, SelectDate, SelectDateTime from core.views.widgets.ajax_select import ( AutoCompleteSelect, @@ -230,3 +231,13 @@ class EticketForm(forms.ModelForm): "product": AutoCompleteSelectProduct, "event_date": SelectDate, } + + +class CloseCustomerAccountForm(forms.Form): + user = forms.ModelChoiceField( + label=_("Refound this account"), + help_text=None, + required=True, + widget=AutoCompleteSelectUser, + queryset=User.objects.all(), + ) diff --git a/counter/management/commands/dump_accounts.py b/counter/management/commands/dump_accounts.py index e8219103..b25cb93c 100644 --- a/counter/management/commands/dump_accounts.py +++ b/counter/management/commands/dump_accounts.py @@ -11,7 +11,7 @@ from django.utils.timezone import now from django.utils.translation import gettext as _ from core.models import User, UserQuerySet -from counter.models import AccountDump, Counter, Customer, Selling +from counter.models import AccountDump, Counter, Customer, Product, Selling class Command(BaseCommand): @@ -106,6 +106,7 @@ class Command(BaseCommand): raise ValueError("One or more accounts were not engaged in a dump process") counter = Counter.objects.get(pk=settings.SITH_COUNTER_ACCOUNT_DUMP_ID) seller = User.objects.get(pk=settings.SITH_ROOT_USER_ID) + product = Product.objects.get(id=settings.SITH_PRODUCT_REFOUND_ID) sales = Selling.objects.bulk_create( [ Selling( @@ -113,7 +114,7 @@ class Command(BaseCommand): club=counter.club, counter=counter, seller=seller, - product=None, + product=product, customer=account, quantity=1, unit_price=account.amount, @@ -126,7 +127,7 @@ class Command(BaseCommand): sales.sort(key=attrgetter("customer_id")) # dumps and sales are linked to the same customers - # and or both ordered with the same key, so zipping them is valid + # and both ordered with the same key, so zipping them is valid for dump, sale in zip(pending_dumps, sales, strict=False): dump.dump_operation = sale AccountDump.objects.bulk_update(pending_dumps, ["dump_operation"]) diff --git a/accounting/templates/accounting/refound_account.jinja b/counter/templates/counter/refound_account.jinja similarity index 100% rename from accounting/templates/accounting/refound_account.jinja rename to counter/templates/counter/refound_account.jinja diff --git a/accounting/tests.py b/counter/tests/test_refound.py similarity index 96% rename from accounting/tests.py rename to counter/tests/test_refound.py index 34cf7cfb..25c3578c 100644 --- a/accounting/tests.py +++ b/counter/tests/test_refound.py @@ -27,7 +27,7 @@ class TestRefoundAccount(TestCase): # refill skia's account cls.skia.customer.amount = 800 cls.skia.customer.save() - cls.refound_account_url = reverse("accounting:refound_account") + cls.refound_account_url = reverse("counter:account_refound") def test_permission_denied(self): self.client.force_login(User.objects.get(username="guy")) diff --git a/counter/urls.py b/counter/urls.py index 885b4b14..30383ac1 100644 --- a/counter/urls.py +++ b/counter/urls.py @@ -30,6 +30,7 @@ from counter.views.admin import ( ProductTypeEditView, ProductTypeListView, RefillingDeleteView, + RefoundAccountView, SellingDeleteView, ) from counter.views.auth import counter_login, counter_logout @@ -51,10 +52,7 @@ from counter.views.home import ( CounterMain, ) from counter.views.invoice import InvoiceCallView -from counter.views.student_card import ( - StudentCardDeleteView, - StudentCardFormView, -) +from counter.views.student_card import StudentCardDeleteView, StudentCardFormView urlpatterns = [ path("/", CounterMain.as_view(), name="details"), @@ -151,4 +149,5 @@ urlpatterns = [ CounterRefillingListView.as_view(), name="refilling_list", ), + path("admin/refound/", RefoundAccountView.as_view(), name="account_refound"), ] diff --git a/counter/views/admin.py b/counter/views/admin.py index ffe81ea0..d0b75d51 100644 --- a/counter/views/admin.py +++ b/counter/views/admin.py @@ -15,18 +15,21 @@ from datetime import timedelta from django.conf import settings +from django.contrib.auth.mixins import UserPassesTestMixin from django.core.exceptions import PermissionDenied +from django.db import transaction from django.forms import CheckboxSelectMultiple from django.forms.models import modelform_factory from django.shortcuts import get_object_or_404 from django.urls import reverse, reverse_lazy from django.utils import timezone +from django.utils.translation import gettext as _ from django.views.generic import DetailView, ListView, TemplateView -from django.views.generic.edit import CreateView, DeleteView, UpdateView +from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView from core.auth.mixins import CanEditMixin, CanViewMixin from core.utils import get_semester_code, get_start_of_semester -from counter.forms import CounterEditForm, ProductEditForm +from counter.forms import CloseCustomerAccountForm, CounterEditForm, ProductEditForm from counter.models import Counter, Product, ProductType, Refilling, Selling from counter.utils import is_logged_in_counter from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin @@ -253,3 +256,42 @@ class CounterRefillingListView(CounterAdminTabsMixin, CounterAdminMixin, ListVie kwargs = super().get_context_data(**kwargs) kwargs["counter"] = self.counter return kwargs + + +class RefoundAccountView(UserPassesTestMixin, FormView): + """Create a selling with the same amount as the current user money.""" + + template_name = "counter/refound_account.jinja" + form_class = CloseCustomerAccountForm + + def test_func(self): + return self.request.user.is_root or self.request.user.is_in_group( + pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID + ) + + def form_valid(self, form): + self.customer = form.cleaned_data["user"] + self.create_selling() + return super().form_valid(form) + + def get_success_url(self): + return self.request.path + + def create_selling(self): + with transaction.atomic(): + uprice = self.customer.customer.amount + refound_club_counter = Counter.objects.get( + id=settings.SITH_COUNTER_REFOUND_ID + ) + refound_club = refound_club_counter.club + s = Selling( + label=_("Refound account"), + unit_price=uprice, + quantity=1, + seller=self.request.user, + customer=self.customer.customer, + club=refound_club, + counter=refound_club_counter, + product=Product.objects.get(id=settings.SITH_PRODUCT_REFOUND_ID), + ) + s.save() diff --git a/sith/urls.py b/sith/urls.py index 0dfa1310..c2250b30 100644 --- a/sith/urls.py +++ b/sith/urls.py @@ -41,10 +41,6 @@ urlpatterns = [ path("com/", include(("com.urls", "com"), namespace="com")), path("club/", include(("club.urls", "club"), namespace="club")), path("counter/", include(("counter.urls", "counter"), namespace="counter")), - path( - "accounting/", - include(("accounting.urls", "accounting"), namespace="accounting"), - ), path("eboutic/", include(("eboutic.urls", "eboutic"), namespace="eboutic")), path( "launderette/",