diff --git a/Back-End/School/models.py b/Back-End/School/models.py
index 7c7f609..f549d77 100644
--- a/Back-End/School/models.py
+++ b/Back-End/School/models.py
@@ -96,7 +96,6 @@ class Fee(models.Model):
name = models.CharField(max_length=255, unique=True)
base_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
description = models.TextField(blank=True)
- discounts = models.ManyToManyField('Discount', blank=True)
is_active = models.BooleanField(default=True)
updated_at = models.DateTimeField(auto_now=True)
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
diff --git a/Back-End/School/serializers.py b/Back-End/School/serializers.py
index a4e2a90..7c63f88 100644
--- a/Back-End/School/serializers.py
+++ b/Back-End/School/serializers.py
@@ -1,8 +1,5 @@
from rest_framework import serializers
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
from Auth.models import Profile
from N3wtSchool import settings, bdd
from django.utils import timezone
@@ -187,41 +184,12 @@ class DiscountSerializer(serializers.ModelSerializer):
return local_time.strftime("%d-%m-%Y %H:%M")
class FeeSerializer(serializers.ModelSerializer):
- discounts = serializers.PrimaryKeyRelatedField(queryset=Discount.objects.all(), many=True)
updated_at_formatted = serializers.SerializerMethodField()
class Meta:
model = Fee
fields = '__all__'
- def create(self, validated_data):
- discounts_data = validated_data.pop('discounts', [])
-
- # Create the Fee instance
- fee = Fee.objects.create(**validated_data)
-
- # Add discounts if provided
- fee.discounts.set(discounts_data)
-
- return fee
-
- def update(self, instance, validated_data):
- discounts_data = validated_data.pop('discounts', [])
-
- # Update the Fee 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.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
- instance.discounts.set(discounts_data)
-
- return instance
-
def get_updated_at_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_at)
local_tz = pytz.timezone(settings.TZ_APPLI)
diff --git a/Back-End/Subscriptions/models.py b/Back-End/Subscriptions/models.py
index b183107..fe7d2af 100644
--- a/Back-End/Subscriptions/models.py
+++ b/Back-End/Subscriptions/models.py
@@ -4,7 +4,7 @@ from django.conf import settings
from django.utils.translation import gettext_lazy as _
from Auth.models import Profile
-from School.models import SchoolClass
+from School.models import SchoolClass, Fee, Discount
from datetime import datetime
@@ -204,6 +204,12 @@ class RegistrationForm(models.Model):
registration_file = models.FileField(upload_to=settings.DOCUMENT_DIR, default="", blank=True)
associated_rf = models.CharField(max_length=200, default="", blank=True)
+ # Many-to-Many Relationship
+ fees = models.ManyToManyField(Fee, blank=True, related_name='register_forms')
+
+ # Many-to-Many Relationship
+ discounts = models.ManyToManyField(Discount, blank=True, related_name='register_forms')
+
def __str__(self):
return "RF_" + self.student.last_name + "_" + self.student.first_name
diff --git a/Back-End/Subscriptions/serializers.py b/Back-End/Subscriptions/serializers.py
index b4a996c..2e916a7 100644
--- a/Back-End/Subscriptions/serializers.py
+++ b/Back-End/Subscriptions/serializers.py
@@ -1,6 +1,7 @@
from rest_framework import serializers
from .models import RegistrationFileTemplate, RegistrationFile, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationFee
-from School.models import SchoolClass
+from School.models import SchoolClass, Fee, Discount
+from School.serializers import FeeSerializer, DiscountSerializer
from Auth.models import Profile
from Auth.serializers import ProfileSerializer
from GestionMessagerie.models import Messagerie
@@ -133,6 +134,9 @@ class RegistrationFormSerializer(serializers.ModelSerializer):
status_label = serializers.SerializerMethodField()
formatted_last_update = serializers.SerializerMethodField()
registration_files = RegistrationFileSerializer(many=True, required=False)
+ fees = serializers.PrimaryKeyRelatedField(queryset=Fee.objects.all(), many=True, required=False)
+ discounts = serializers.PrimaryKeyRelatedField(queryset=Discount.objects.all(), many=True, required=False)
+
class Meta:
model = RegistrationForm
fields = '__all__'
@@ -140,11 +144,19 @@ class RegistrationFormSerializer(serializers.ModelSerializer):
def create(self, validated_data):
student_data = validated_data.pop('student')
student = StudentSerializer.create(StudentSerializer(), student_data)
+ fees_data = validated_data.pop('fees', [])
+ discounts_data = validated_data.pop('discounts', [])
registrationForm = RegistrationForm.objects.create(student=student, **validated_data)
+
+ # Associer les IDs des objets Fee et Discount au RegistrationForm
+ registrationForm.fees.set([fee.id for fee in fees_data])
+ registrationForm.discounts.set([discount.id for discount in discounts_data])
return registrationForm
def update(self, instance, validated_data):
student_data = validated_data.pop('student', None)
+ fees_data = validated_data.pop('fees', [])
+ discounts_data = validated_data.pop('discounts', [])
if student_data:
student = instance.student
StudentSerializer.update(StudentSerializer(), student, student_data)
@@ -156,6 +168,10 @@ class RegistrationFormSerializer(serializers.ModelSerializer):
pass
instance.save()
+ # Associer les IDs des objets Fee et Discount au RegistrationForm
+ instance.fees.set([fee.id for fee in fees_data])
+ instance.discounts.set([discount.id for discount in discounts_data])
+
return instance
def get_status_label(self, obj):
diff --git a/Front-End/src/app/[locale]/admin/structure/page.js b/Front-End/src/app/[locale]/admin/structure/page.js
index 545a112..e76e5ed 100644
--- a/Front-End/src/app/[locale]/admin/structure/page.js
+++ b/Front-End/src/app/[locale]/admin/structure/page.js
@@ -2,7 +2,7 @@
import React, { useState, useEffect } from 'react';
import StructureManagement from '@/components/Structure/Configuration/StructureManagement';
import ScheduleManagement from '@/components/Structure/Planning/ScheduleManagement';
-import FeesManagement from '@/components/Structure/Configuration/FeesManagement';
+import FeesManagement from '@/components/Structure/Tarification/FeesManagement';
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import useCsrfToken from '@/hooks/useCsrfToken';
import { ClassesProvider } from '@/context/ClassesContext';
diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js
index 5ddb2da..641d223 100644
--- a/Front-End/src/app/[locale]/admin/subscriptions/page.js
+++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js
@@ -32,7 +32,13 @@ import {
fetchStudents,
editRegisterForm } from "@/app/lib/subscriptionAction"
-import { fetchClasses } from '@/app/lib/schoolAction';
+import {
+ fetchClasses,
+ fetchRegistrationDiscounts,
+ fetchTuitionDiscounts,
+ fetchRegistrationFees,
+ fetchTuitionFees } from '@/app/lib/schoolAction';
+
import { createProfile } from '@/app/lib/authAction';
import {
@@ -75,6 +81,11 @@ export default function Page({ params: { locale } }) {
const [isEditing, setIsEditing] = useState(false);
const [fileToEdit, setFileToEdit] = useState(null);
+ const [registrationDiscounts, setRegistrationDiscounts] = useState([]);
+ const [tuitionDiscounts, setTuitionDiscounts] = useState([]);
+ const [registrationFees, setRegistrationFees] = useState([]);
+ const [tuitionFees, setTuitionFees] = useState([]);
+
const csrfToken = useCsrfToken();
const openModal = () => {
@@ -151,6 +162,7 @@ const registerFormArchivedDataHandler = (data) => {
}
}
}
+
// TODO: revoir le système de pagination et de UseEffect
useEffect(() => {
@@ -195,7 +207,27 @@ const registerFormArchivedDataHandler = (data) => {
setFichiers(data)
})
- .catch((err)=>{ err = err.message; console.log(err);});
+ .catch((err)=>{ err = err.message; console.log(err);})
+ fetchRegistrationDiscounts()
+ .then(data => {
+ setRegistrationDiscounts(data);
+ })
+ .catch(requestErrorHandler)
+ fetchTuitionDiscounts()
+ .then(data => {
+ setTuitionDiscounts(data);
+ })
+ .catch(requestErrorHandler)
+ fetchRegistrationFees()
+ .then(data => {
+ setRegistrationFees(data);
+ })
+ .catch(requestErrorHandler)
+ fetchTuitionFees()
+ .then(data => {
+ setTuitionFees(data);
+ })
+ .catch(requestErrorHandler);
} else {
setTimeout(() => {
setRegistrationFormsDataPending(mockFicheInscription);
@@ -321,6 +353,8 @@ useEffect(()=>{
const createRF = (updatedData) => {
console.log('createRF updatedData:', updatedData);
+ const selectedRegistrationFeesIds = updatedData.selectedRegistrationFees.map(feeId => feeId)
+ const selectedRegistrationDiscountsIds = updatedData.selectedRegistrationDiscounts.map(discountId => discountId)
if (updatedData.selectedGuardians.length !== 0) {
const selectedGuardiansIds = updatedData.selectedGuardians.map(guardianId => guardianId)
@@ -330,7 +364,9 @@ useEffect(()=>{
last_name: updatedData.studentLastName,
first_name: updatedData.studentFirstName,
},
- idGuardians: selectedGuardiansIds
+ idGuardians: selectedGuardiansIds,
+ fees: selectedRegistrationFeesIds,
+ discounts: selectedRegistrationDiscountsIds
};
createRegisterForm(data,csrfToken)
@@ -379,7 +415,9 @@ useEffect(()=>{
}
],
sibling: []
- }
+ },
+ fees: selectedRegistrationFeesIds,
+ discounts: selectedRegistrationDiscountsIds
};
createRegisterForm(data,csrfToken)
@@ -784,6 +822,10 @@ const handleFileUpload = ({file, name, is_required, order}) => {
size='sm:w-1/4'
ContentComponent={() => (
+ Information + Aucune réduction n'a été créée sur les frais d'inscription. +
+ )} +