move accound refound view to counter

This commit is contained in:
imperosol
2025-03-14 16:04:51 +01:00
committed by Thomas Girod
parent 002554b802
commit 26d4c4b811
11 changed files with 68 additions and 116 deletions

View File

@ -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,
@ -250,3 +251,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(),
)

View File

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

View File

@ -0,0 +1,16 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}Refound account{% endtrans %}
{% endblock %}
{% block content %}
<div id="accounting">
<h3>{% trans %}Refound account{% endtrans %}</h3>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="submit" value="{% trans %}Refound{% endtrans %}" /></p>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,59 @@
#
# 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.test import TestCase
from django.urls import reverse
from core.models import User
class TestRefoundAccount(TestCase):
@classmethod
def setUpTestData(cls):
cls.skia = User.objects.get(username="skia")
# refill skia's account
cls.skia.customer.amount = 800
cls.skia.customer.save()
cls.refound_account_url = reverse("counter:account_refound")
def test_permission_denied(self):
self.client.force_login(User.objects.get(username="guy"))
response_post = self.client.post(
self.refound_account_url, {"user": self.skia.id}
)
response_get = self.client.get(self.refound_account_url)
assert response_get.status_code == 403
assert response_post.status_code == 403
def test_root_granteed(self):
self.client.force_login(User.objects.get(username="root"))
response = self.client.post(self.refound_account_url, {"user": self.skia.id})
self.assertRedirects(response, self.refound_account_url)
self.skia.refresh_from_db()
response = self.client.get(self.refound_account_url)
assert response.status_code == 200
assert '<form action="" method="post">' in str(response.content)
assert self.skia.customer.amount == 0
def test_comptable_granteed(self):
self.client.force_login(User.objects.get(username="comptable"))
response = self.client.post(self.refound_account_url, {"user": self.skia.id})
self.assertRedirects(response, self.refound_account_url)
self.skia.refresh_from_db()
response = self.client.get(self.refound_account_url)
assert response.status_code == 200
assert '<form action="" method="post">' in str(response.content)
assert self.skia.customer.amount == 0

View File

@ -30,6 +30,7 @@ from counter.views.admin import (
ProductTypeEditView,
ProductTypeListView,
RefillingDeleteView,
RefoundAccountView,
ReturnableProductCreateView,
ReturnableProductDeleteView,
ReturnableProductListView,
@ -170,4 +171,5 @@ urlpatterns = [
CounterRefillingListView.as_view(),
name="refilling_list",
),
path("admin/refound/", RefoundAccountView.as_view(), name="account_refound"),
]

View File

@ -15,8 +15,9 @@
from datetime import timedelta
from django.conf import settings
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin, 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
@ -24,11 +25,16 @@ 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, ReturnableProductForm
from counter.forms import (
CloseCustomerAccountForm,
CounterEditForm,
ProductEditForm,
ReturnableProductForm,
)
from counter.models import (
Counter,
Product,
@ -325,3 +331,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()