move accound refound view to counter

This commit is contained in:
imperosol 2025-03-14 16:04:51 +01:00
parent 3a45ebb2fa
commit e4cc4cb96b
11 changed files with 65 additions and 119 deletions

View File

@ -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"),
]

View File

@ -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()

View File

@ -109,7 +109,7 @@
<h4>{% trans %}Accounting{% endtrans %}</h4> <h4>{% trans %}Accounting{% endtrans %}</h4>
<ul> <ul>
{% if user.is_root or user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %} {% if user.is_root or user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
<li><a href="{{ url('accounting:refound_account') }}">{% trans %}Refound Account{% endtrans %}</a></li> <li><a href="{{ url("counter:account_refound") }}">{% trans %}Refound Account{% endtrans %}</a></li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>

View File

@ -65,7 +65,7 @@ from core.views.forms import (
UserProfileForm, UserProfileForm,
) )
from core.views.mixins import QuickNotifMixin, TabedViewMixin 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 eboutic.models import Invoice
from subscription.models import Subscription from subscription.models import Subscription
from trombi.views import UserTrombiForm from trombi.views import UserTrombiForm
@ -385,8 +385,6 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
kwargs = super().get_context_data(**kwargs) kwargs = super().get_context_data(**kwargs)
from django.db.models import Sum from django.db.models import Sum
from counter.models import Counter
foyer = Counter.objects.filter(name="Foyer").first() foyer = Counter.objects.filter(name="Foyer").first()
mde = Counter.objects.filter(name="MDE").first() mde = Counter.objects.filter(name="MDE").first()
gommette = Counter.objects.filter(name="La Gommette").first() gommette = Counter.objects.filter(name="La Gommette").first()

View File

@ -3,6 +3,7 @@ from django.utils.translation import gettext_lazy as _
from phonenumber_field.widgets import RegionalPhoneNumberWidget from phonenumber_field.widgets import RegionalPhoneNumberWidget
from club.widgets.ajax_select import AutoCompleteSelectClub from club.widgets.ajax_select import AutoCompleteSelectClub
from core.models import User
from core.views.forms import NFCTextInput, SelectDate, SelectDateTime from core.views.forms import NFCTextInput, SelectDate, SelectDateTime
from core.views.widgets.ajax_select import ( from core.views.widgets.ajax_select import (
AutoCompleteSelect, AutoCompleteSelect,
@ -230,3 +231,13 @@ class EticketForm(forms.ModelForm):
"product": AutoCompleteSelectProduct, "product": AutoCompleteSelectProduct,
"event_date": SelectDate, "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(),
)

View File

@ -11,7 +11,7 @@ from django.utils.timezone import now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from core.models import User, UserQuerySet 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): class Command(BaseCommand):
@ -106,6 +106,7 @@ class Command(BaseCommand):
raise ValueError("One or more accounts were not engaged in a dump process") raise ValueError("One or more accounts were not engaged in a dump process")
counter = Counter.objects.get(pk=settings.SITH_COUNTER_ACCOUNT_DUMP_ID) counter = Counter.objects.get(pk=settings.SITH_COUNTER_ACCOUNT_DUMP_ID)
seller = User.objects.get(pk=settings.SITH_ROOT_USER_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( sales = Selling.objects.bulk_create(
[ [
Selling( Selling(
@ -113,7 +114,7 @@ class Command(BaseCommand):
club=counter.club, club=counter.club,
counter=counter, counter=counter,
seller=seller, seller=seller,
product=None, product=product,
customer=account, customer=account,
quantity=1, quantity=1,
unit_price=account.amount, unit_price=account.amount,
@ -126,7 +127,7 @@ class Command(BaseCommand):
sales.sort(key=attrgetter("customer_id")) sales.sort(key=attrgetter("customer_id"))
# dumps and sales are linked to the same customers # 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): for dump, sale in zip(pending_dumps, sales, strict=False):
dump.dump_operation = sale dump.dump_operation = sale
AccountDump.objects.bulk_update(pending_dumps, ["dump_operation"]) AccountDump.objects.bulk_update(pending_dumps, ["dump_operation"])

View File

@ -27,7 +27,7 @@ class TestRefoundAccount(TestCase):
# refill skia's account # refill skia's account
cls.skia.customer.amount = 800 cls.skia.customer.amount = 800
cls.skia.customer.save() 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): def test_permission_denied(self):
self.client.force_login(User.objects.get(username="guy")) self.client.force_login(User.objects.get(username="guy"))

View File

@ -30,6 +30,7 @@ from counter.views.admin import (
ProductTypeEditView, ProductTypeEditView,
ProductTypeListView, ProductTypeListView,
RefillingDeleteView, RefillingDeleteView,
RefoundAccountView,
SellingDeleteView, SellingDeleteView,
) )
from counter.views.auth import counter_login, counter_logout from counter.views.auth import counter_login, counter_logout
@ -51,10 +52,7 @@ from counter.views.home import (
CounterMain, CounterMain,
) )
from counter.views.invoice import InvoiceCallView from counter.views.invoice import InvoiceCallView
from counter.views.student_card import ( from counter.views.student_card import StudentCardDeleteView, StudentCardFormView
StudentCardDeleteView,
StudentCardFormView,
)
urlpatterns = [ urlpatterns = [
path("<int:counter_id>/", CounterMain.as_view(), name="details"), path("<int:counter_id>/", CounterMain.as_view(), name="details"),
@ -151,4 +149,5 @@ urlpatterns = [
CounterRefillingListView.as_view(), CounterRefillingListView.as_view(),
name="refilling_list", name="refilling_list",
), ),
path("admin/refound/", RefoundAccountView.as_view(), name="account_refound"),
] ]

View File

@ -15,18 +15,21 @@
from datetime import timedelta from datetime import timedelta
from django.conf import settings from django.conf import settings
from django.contrib.auth.mixins import UserPassesTestMixin
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.forms import CheckboxSelectMultiple from django.forms import CheckboxSelectMultiple
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext as _
from django.views.generic import DetailView, ListView, TemplateView 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.auth.mixins import CanEditMixin, CanViewMixin
from core.utils import get_semester_code, get_start_of_semester 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.models import Counter, Product, ProductType, Refilling, Selling
from counter.utils import is_logged_in_counter from counter.utils import is_logged_in_counter
from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin
@ -253,3 +256,42 @@ class CounterRefillingListView(CounterAdminTabsMixin, CounterAdminMixin, ListVie
kwargs = super().get_context_data(**kwargs) kwargs = super().get_context_data(**kwargs)
kwargs["counter"] = self.counter kwargs["counter"] = self.counter
return kwargs 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()

View File

@ -41,10 +41,6 @@ urlpatterns = [
path("com/", include(("com.urls", "com"), namespace="com")), path("com/", include(("com.urls", "com"), namespace="com")),
path("club/", include(("club.urls", "club"), namespace="club")), path("club/", include(("club.urls", "club"), namespace="club")),
path("counter/", include(("counter.urls", "counter"), namespace="counter")), 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("eboutic/", include(("eboutic.urls", "eboutic"), namespace="eboutic")),
path( path(
"launderette/", "launderette/",