mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Harmonisation des fees / ajout de type de réduction / mise à jour
du calcul [#18]
This commit is contained in:
@ -73,40 +73,33 @@ class PaymentOptions(models.IntegerChoices):
|
||||
FOUR_TIME_PAYMENT = 1, _('Paiement en 4 fois')
|
||||
TEN_TIME_PAYMENT = 2, _('Paiement en 10 fois')
|
||||
|
||||
class DiscountType(models.IntegerChoices):
|
||||
CURRENCY = 0, 'Currency'
|
||||
PERCENT = 1, 'Percent'
|
||||
|
||||
class FeeType(models.IntegerChoices):
|
||||
REGISTRATION_FEE = 0, 'Registration Fee'
|
||||
TUITION_FEE = 1, 'Tuition Fee'
|
||||
|
||||
class Discount(models.Model):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2)
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||
description = models.TextField(blank=True)
|
||||
discount_type = models.IntegerField(choices=DiscountType.choices, default=DiscountType.CURRENCY)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Fee(models.Model):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
description = models.TextField(blank=True)
|
||||
base_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||
currency = models.CharField(max_length=3, default='EUR')
|
||||
description = models.TextField(blank=True)
|
||||
payment_option = models.IntegerField(choices=PaymentOptions.choices, default=PaymentOptions.SINGLE_PAYMENT)
|
||||
discounts = models.ManyToManyField('Discount', blank=True)
|
||||
payment_option = models.IntegerField(choices=PaymentOptions, default=PaymentOptions.SINGLE_PAYMENT)
|
||||
is_active = models.BooleanField(default=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
currency = models.CharField(max_length=3, default='EUR')
|
||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class TuitionFee(models.Model):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
description = models.TextField(blank=True)
|
||||
base_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||
currency = models.CharField(max_length=3, default='EUR')
|
||||
discounts = models.ManyToManyField('Discount', blank=True)
|
||||
payment_option = models.IntegerField(choices=PaymentOptions, default=PaymentOptions.SINGLE_PAYMENT)
|
||||
is_active = models.BooleanField(default=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def clean(self):
|
||||
if self.validity_end_date <= self.validity_start_date:
|
||||
raise ValidationError(_('La date de fin de validité doit être après la date de début de validité.'))
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from rest_framework import serializers
|
||||
from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, TuitionFee, Fee
|
||||
from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, Fee
|
||||
from Subscriptions.models import RegistrationForm
|
||||
from Subscriptions.serializers import StudentSerializer
|
||||
from Auth.serializers import ProfileSerializer
|
||||
@ -208,42 +208,7 @@ class FeeSerializer(serializers.ModelSerializer):
|
||||
instance.payment_option = validated_data.get('payment_option', instance.payment_option)
|
||||
instance.is_active = validated_data.get('is_active', instance.is_active)
|
||||
instance.updated_at = validated_data.get('updated_at', instance.updated_at)
|
||||
instance.save()
|
||||
|
||||
# Update discounts if provided
|
||||
instance.discounts.set(discounts_data)
|
||||
|
||||
return instance
|
||||
|
||||
class TuitionFeeSerializer(serializers.ModelSerializer):
|
||||
discounts = serializers.PrimaryKeyRelatedField(queryset=Discount.objects.all(), many=True)
|
||||
|
||||
class Meta:
|
||||
model = TuitionFee
|
||||
fields = '__all__'
|
||||
|
||||
def create(self, validated_data):
|
||||
discounts_data = validated_data.pop('discounts', [])
|
||||
|
||||
# Create the TuitionFee instance
|
||||
tuition_fee = TuitionFee.objects.create(**validated_data)
|
||||
|
||||
# Add discounts if provided
|
||||
tuition_fee.discounts.set(discounts_data)
|
||||
|
||||
return tuition_fee
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
discounts_data = validated_data.pop('discounts', [])
|
||||
|
||||
# Update the TuitionFee instance
|
||||
instance.name = validated_data.get('name', instance.name)
|
||||
instance.description = validated_data.get('description', instance.description)
|
||||
instance.base_amount = validated_data.get('base_amount', instance.base_amount)
|
||||
instance.currency = validated_data.get('currency', instance.currency)
|
||||
instance.payment_option = validated_data.get('payment_option', instance.payment_option)
|
||||
instance.is_active = validated_data.get('is_active', instance.is_active)
|
||||
instance.updated_at = validated_data.get('updated_at', instance.updated_at)
|
||||
instance.type = validated_data.get('type', instance.type)
|
||||
instance.save()
|
||||
|
||||
# Update discounts if provided
|
||||
|
||||
@ -11,8 +11,6 @@ from School.views import (
|
||||
PlanningView,
|
||||
FeesView,
|
||||
FeeView,
|
||||
TuitionFeesView,
|
||||
TuitionFeeView,
|
||||
DiscountsView,
|
||||
DiscountView,
|
||||
)
|
||||
@ -33,15 +31,11 @@ urlpatterns = [
|
||||
re_path(r'^plannings$', PlanningsView.as_view(), name="plannings"),
|
||||
re_path(r'^planning$', PlanningView.as_view(), name="planning"),
|
||||
re_path(r'^planning/([0-9]+)$', PlanningView.as_view(), name="planning"),
|
||||
|
||||
re_path(r'^fees$', FeesView.as_view(), name="fees"),
|
||||
|
||||
re_path(r'^fees/(?P<_filter>[a-zA-z]+)$', FeesView.as_view(), name="fees"),
|
||||
re_path(r'^fee$', FeeView.as_view(), name="fee"),
|
||||
re_path(r'^fee/([0-9]+)$', FeeView.as_view(), name="fee"),
|
||||
|
||||
re_path(r'^tuitionFees$', TuitionFeesView.as_view(), name="tuitionFees"),
|
||||
re_path(r'^tuitionFee$', TuitionFeeView.as_view(), name="tuitionFee"),
|
||||
re_path(r'^tuitionFee/([0-9]+)$', TuitionFeeView.as_view(), name="tuitionFee"),
|
||||
|
||||
re_path(r'^discounts$', DiscountsView.as_view(), name="discounts"),
|
||||
re_path(r'^discount$', DiscountView.as_view(), name="discount"),
|
||||
re_path(r'^discount/([0-9]+)$', DiscountView.as_view(), name="discount"),
|
||||
|
||||
@ -5,8 +5,8 @@ from rest_framework.parsers import JSONParser
|
||||
from rest_framework.views import APIView
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from .models import Teacher, Speciality, SchoolClass, Planning, Discount, TuitionFee, Fee
|
||||
from .serializers import TeacherSerializer, SpecialitySerializer, SchoolClassSerializer, PlanningSerializer, DiscountSerializer, TuitionFeeSerializer, FeeSerializer
|
||||
from .models import Teacher, Speciality, SchoolClass, Planning, Discount, Fee
|
||||
from .serializers import TeacherSerializer, SpecialitySerializer, SchoolClassSerializer, PlanningSerializer, DiscountSerializer, FeeSerializer
|
||||
from N3wtSchool import bdd
|
||||
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
||||
|
||||
@ -267,18 +267,16 @@ class PlanningView(APIView):
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class FeesView(APIView):
|
||||
def get(self, request):
|
||||
feesList = Fee.objects.all()
|
||||
fees_serializer = FeeSerializer(feesList, many=True)
|
||||
return JsonResponse(fees_serializer.data, safe=False)
|
||||
def get(self, request, _filter, *args, **kwargs):
|
||||
|
||||
def post(self, request):
|
||||
fee_data = JSONParser().parse(request)
|
||||
fee_serializer = FeeSerializer(data=fee_data)
|
||||
if fee_serializer.is_valid():
|
||||
fee_serializer.save()
|
||||
return JsonResponse(fee_serializer.data, safe=False, status=201)
|
||||
return JsonResponse(fee_serializer.errors, safe=False, status=400)
|
||||
if _filter not in ['registration', 'tuition']:
|
||||
return JsonResponse({"error": "Invalid type parameter. Must be 'registration' or 'tuition'."}, safe=False, status=400)
|
||||
|
||||
fee_type_value = 0 if _filter == 'registration' else 1
|
||||
fees = Fee.objects.filter(type=fee_type_value)
|
||||
fee_serializer = FeeSerializer(fees, many=True)
|
||||
|
||||
return JsonResponse(fee_serializer.data, safe=False, status=200)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
@ -312,47 +310,4 @@ class FeeView(APIView):
|
||||
return JsonResponse(fee_serializer.errors, safe=False, status=400)
|
||||
|
||||
def delete(self, request, _id):
|
||||
return delete_object(Fee, _id)
|
||||
|
||||
# Vues pour les frais de scolarité (TuitionFee)
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class TuitionFeesView(APIView):
|
||||
def get(self, request):
|
||||
tuitionFeesList = TuitionFee.objects.all()
|
||||
tuitionFees_serializer = TuitionFeeSerializer(tuitionFeesList, many=True)
|
||||
return JsonResponse(tuitionFees_serializer.data, safe=False)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class TuitionFeeView(APIView):
|
||||
def get(self, request, _id):
|
||||
try:
|
||||
tuitionFee = TuitionFee.objects.get(id=_id)
|
||||
tuitionFee_serializer = TuitionFeeSerializer(tuitionFee)
|
||||
return JsonResponse(tuitionFee_serializer.data, safe=False)
|
||||
except TuitionFee.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=404)
|
||||
|
||||
def post(self, request):
|
||||
tuitionFee_data = JSONParser().parse(request)
|
||||
tuitionFee_serializer = TuitionFeeSerializer(data=tuitionFee_data)
|
||||
if tuitionFee_serializer.is_valid():
|
||||
tuitionFee_serializer.save()
|
||||
return JsonResponse(tuitionFee_serializer.data, safe=False, status=201)
|
||||
return JsonResponse(tuitionFee_serializer.errors, safe=False, status=400)
|
||||
|
||||
def put(self, request, _id):
|
||||
tuitionFee_data = JSONParser().parse(request)
|
||||
try:
|
||||
tuitionFee = TuitionFee.objects.get(id=_id)
|
||||
except TuitionFee.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=404)
|
||||
tuitionFee_serializer = TuitionFeeSerializer(tuitionFee, data=tuitionFee_data, partial=True) # Utilisation de partial=True
|
||||
if tuitionFee_serializer.is_valid():
|
||||
tuitionFee_serializer.save()
|
||||
return JsonResponse(tuitionFee_serializer.data, safe=False)
|
||||
return JsonResponse(tuitionFee_serializer.errors, safe=False, status=400)
|
||||
|
||||
def delete(self, request, _id):
|
||||
return delete_object(TuitionFee, _id)
|
||||
return delete_object(Fee, _id)
|
||||
Reference in New Issue
Block a user