mirror of
https://github.com/ae-utbm/sith.git
synced 2025-04-02 01:40:24 +00:00
move accound refound view to counter
This commit is contained in:
parent
3a45ebb2fa
commit
e4cc4cb96b
@ -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"),
|
|
||||||
]
|
|
@ -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()
|
|
@ -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>
|
||||||
|
@ -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()
|
||||||
|
@ -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(),
|
||||||
|
)
|
||||||
|
@ -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"])
|
||||||
|
@ -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"))
|
@ -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"),
|
||||||
]
|
]
|
||||||
|
@ -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()
|
||||||
|
@ -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/",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user