mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Ajout des modes de paiements + création d'une commande dans le
back permettant d'initialiser des données de test (pour les tarifs)
This commit is contained in:
85
Back-End/School/management/commands/init_data.py
Normal file
85
Back-End/School/management/commands/init_data.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from School.models import Fee, Discount, FeeType, DiscountType
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Initialize or update Fees and Discounts'
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
self.create_or_update_fees()
|
||||||
|
self.create_or_update_discounts()
|
||||||
|
|
||||||
|
def create_or_update_fees(self):
|
||||||
|
fees_data = [
|
||||||
|
{
|
||||||
|
"name": "Frais d'inscription",
|
||||||
|
"base_amount": "150.00",
|
||||||
|
"description": "Montant de base",
|
||||||
|
"is_active": True,
|
||||||
|
"type": FeeType.REGISTRATION_FEE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Matériel",
|
||||||
|
"base_amount": "85.00",
|
||||||
|
"description": "Livres / jouets",
|
||||||
|
"is_active": True,
|
||||||
|
"type": FeeType.REGISTRATION_FEE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sorties périscolaires",
|
||||||
|
"base_amount": "120.00",
|
||||||
|
"description": "Sorties",
|
||||||
|
"is_active": True,
|
||||||
|
"type": FeeType.REGISTRATION_FEE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Les colibris",
|
||||||
|
"base_amount": "4500.00",
|
||||||
|
"description": "TPS / PS / MS / GS",
|
||||||
|
"is_active": True,
|
||||||
|
"type": FeeType.TUITION_FEE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Les butterflies",
|
||||||
|
"base_amount": "5000.00",
|
||||||
|
"description": "CP / CE1 / CE2 / CM1 / CM2",
|
||||||
|
"is_active": True,
|
||||||
|
"type": FeeType.TUITION_FEE
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
for fee_data in fees_data:
|
||||||
|
Fee.objects.update_or_create(
|
||||||
|
name=fee_data["name"],
|
||||||
|
type=fee_data["type"],
|
||||||
|
defaults=fee_data
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('Fees initialized or updated successfully'))
|
||||||
|
|
||||||
|
def create_or_update_discounts(self):
|
||||||
|
discounts_data = [
|
||||||
|
{
|
||||||
|
"name": "Parrainage",
|
||||||
|
"amount": "10.00",
|
||||||
|
"description": "Réduction pour parrainage",
|
||||||
|
"discount_type": DiscountType.PERCENT,
|
||||||
|
"type": FeeType.TUITION_FEE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Réinscription",
|
||||||
|
"amount": "100.00",
|
||||||
|
"description": "Réduction pour Réinscription",
|
||||||
|
"discount_type": DiscountType.PERCENT,
|
||||||
|
"type": FeeType.REGISTRATION_FEE
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
for discount_data in discounts_data:
|
||||||
|
Discount.objects.update_or_create(
|
||||||
|
name=discount_data["name"],
|
||||||
|
type=discount_data["type"],
|
||||||
|
discount_type=discount_data["discount_type"],
|
||||||
|
defaults=discount_data
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('Discounts initialized or updated successfully'))
|
||||||
25
Back-End/School/management/commands/init_payment_modes.py
Normal file
25
Back-End/School/management/commands/init_payment_modes.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from School.models import PaymentMode, PaymentModeType, FeeType
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Initialize or update Payment Modes'
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
self.create_or_update_payment_modes()
|
||||||
|
|
||||||
|
def create_or_update_payment_modes(self):
|
||||||
|
for fee_type in FeeType.choices:
|
||||||
|
fee_type_value = fee_type[0]
|
||||||
|
|
||||||
|
for mode in PaymentModeType.choices:
|
||||||
|
mode_value = mode[0]
|
||||||
|
|
||||||
|
PaymentMode.objects.update_or_create(
|
||||||
|
mode=mode_value,
|
||||||
|
type=fee_type_value,
|
||||||
|
defaults={
|
||||||
|
'is_active': False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('Payment Modes initialized or updated successfully'))
|
||||||
@ -82,6 +82,12 @@ class FeeType(models.IntegerChoices):
|
|||||||
REGISTRATION_FEE = 0, 'Registration Fee'
|
REGISTRATION_FEE = 0, 'Registration Fee'
|
||||||
TUITION_FEE = 1, 'Tuition Fee'
|
TUITION_FEE = 1, 'Tuition Fee'
|
||||||
|
|
||||||
|
class PaymentModeType(models.IntegerChoices):
|
||||||
|
SEPA = 1, 'Prélèvement SEPA'
|
||||||
|
TRANSFER = 2, 'Virement'
|
||||||
|
CHECK = 3, 'Chèque'
|
||||||
|
CASH = 4, 'Espèce'
|
||||||
|
|
||||||
class Discount(models.Model):
|
class Discount(models.Model):
|
||||||
name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255, unique=True)
|
||||||
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||||
@ -113,3 +119,11 @@ class PaymentPlan(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.get_frequency_display()} - {self.get_type_display()}"
|
return f"{self.get_frequency_display()} - {self.get_type_display()}"
|
||||||
|
|
||||||
|
class PaymentMode(models.Model):
|
||||||
|
mode = models.IntegerField(choices=PaymentModeType.choices, default=PaymentModeType.SEPA)
|
||||||
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
|
is_active = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.get_mode_display()} - {self.get_type_display()}"
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, Fee, PaymentPlan
|
from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, Fee, PaymentPlan, PaymentMode
|
||||||
from Auth.models import Profile
|
from Auth.models import Profile
|
||||||
from N3wtSchool import settings, bdd
|
from N3wtSchool import settings, bdd
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
@ -196,3 +196,8 @@ class PaymentPlanSerializer(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = PaymentPlan
|
model = PaymentPlan
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
class PaymentModeSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = PaymentMode
|
||||||
|
fields = '__all__'
|
||||||
@ -14,7 +14,9 @@ from School.views import (
|
|||||||
DiscountsView,
|
DiscountsView,
|
||||||
DiscountView,
|
DiscountView,
|
||||||
PaymentPlansView,
|
PaymentPlansView,
|
||||||
PaymentPlanView
|
PaymentPlanView,
|
||||||
|
PaymentModesView,
|
||||||
|
PaymentModeView
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@ -45,4 +47,8 @@ urlpatterns = [
|
|||||||
re_path(r'^paymentPlans/(?P<_filter>[a-zA-z]+)$', PaymentPlansView.as_view(), name="paymentPlans"),
|
re_path(r'^paymentPlans/(?P<_filter>[a-zA-z]+)$', PaymentPlansView.as_view(), name="paymentPlans"),
|
||||||
re_path(r'^paymentPlan$', PaymentPlanView.as_view(), name="paymentPlan"),
|
re_path(r'^paymentPlan$', PaymentPlanView.as_view(), name="paymentPlan"),
|
||||||
re_path(r'^paymentPlan/([0-9]+)$', PaymentPlanView.as_view(), name="paymentPlan"),
|
re_path(r'^paymentPlan/([0-9]+)$', PaymentPlanView.as_view(), name="paymentPlan"),
|
||||||
|
|
||||||
|
re_path(r'^paymentModes/(?P<_filter>[a-zA-z]+)$', PaymentModesView.as_view(), name="paymentModes"),
|
||||||
|
re_path(r'^paymentMode$', PaymentModeView.as_view(), name="paymentMode"),
|
||||||
|
re_path(r'^paymentMode/([0-9]+)$', PaymentModeView.as_view(), name="paymentMode"),
|
||||||
]
|
]
|
||||||
@ -5,8 +5,8 @@ from rest_framework.parsers import JSONParser
|
|||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from .models import Teacher, Speciality, SchoolClass, Planning, Discount, Fee, PaymentPlan
|
from .models import Teacher, Speciality, SchoolClass, Planning, Discount, Fee, PaymentPlan, PaymentMode
|
||||||
from .serializers import TeacherSerializer, SpecialitySerializer, SchoolClassSerializer, PlanningSerializer, DiscountSerializer, FeeSerializer, PaymentPlanSerializer
|
from .serializers import TeacherSerializer, SpecialitySerializer, SchoolClassSerializer, PlanningSerializer, DiscountSerializer, FeeSerializer, PaymentPlanSerializer, PaymentModeSerializer
|
||||||
from N3wtSchool import bdd
|
from N3wtSchool import bdd
|
||||||
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
||||||
|
|
||||||
@ -356,3 +356,48 @@ class PaymentPlanView(APIView):
|
|||||||
|
|
||||||
def delete(self, request, _id):
|
def delete(self, request, _id):
|
||||||
return delete_object(PaymentPlan, _id)
|
return delete_object(PaymentPlan, _id)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class PaymentModesView(APIView):
|
||||||
|
def get(self, request, _filter, *args, **kwargs):
|
||||||
|
|
||||||
|
if _filter not in ['registration', 'tuition']:
|
||||||
|
return JsonResponse({"error": "Invalid type parameter. Must be 'registration' or 'tuition'."}, safe=False, status=400)
|
||||||
|
|
||||||
|
type_value = 0 if _filter == 'registration' else 1
|
||||||
|
paymentModes = PaymentMode.objects.filter(type=type_value)
|
||||||
|
payment_modes_serializer = PaymentModeSerializer(paymentModes, many=True)
|
||||||
|
|
||||||
|
return JsonResponse(payment_modes_serializer.data, safe=False, status=200)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class PaymentModeView(APIView):
|
||||||
|
def get(self, request, _id):
|
||||||
|
try:
|
||||||
|
payment_mode = PaymentMode.objects.get(id=_id)
|
||||||
|
payment_mode_serializer = PaymentModeSerializer(payment_mode)
|
||||||
|
return JsonResponse(payment_mode_serializer.data, safe=False)
|
||||||
|
except PaymentMode.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=404)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
payment_mode_data = JSONParser().parse(request)
|
||||||
|
payment_mode_serializer = PaymentModeSerializer(data=payment_mode_data)
|
||||||
|
if payment_mode_serializer.is_valid():
|
||||||
|
payment_mode_serializer.save()
|
||||||
|
return JsonResponse(payment_mode_serializer.data, safe=False, status=201)
|
||||||
|
return JsonResponse(payment_mode_serializer.errors, safe=False, status=400)
|
||||||
|
|
||||||
|
def put(self, request, _id):
|
||||||
|
payment_mode_data = JSONParser().parse(request)
|
||||||
|
try:
|
||||||
|
payment_mode = PaymentMode.objects.get(id=_id)
|
||||||
|
except PaymentMode.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=404)
|
||||||
|
payment_mode_serializer = PaymentModeSerializer(payment_mode, data=payment_mode_data, partial=True)
|
||||||
|
if payment_mode_serializer.is_valid():
|
||||||
|
payment_mode_serializer.save()
|
||||||
|
return JsonResponse(payment_mode_serializer.data, safe=False)
|
||||||
|
return JsonResponse(payment_mode_serializer.errors, safe=False, status=400)
|
||||||
@ -19,7 +19,9 @@ commands = [
|
|||||||
["python", "manage.py", "makemigrations", "Auth", "--noinput"],
|
["python", "manage.py", "makemigrations", "Auth", "--noinput"],
|
||||||
["python", "manage.py", "makemigrations", "School", "--noinput"],
|
["python", "manage.py", "makemigrations", "School", "--noinput"],
|
||||||
["python", "manage.py", "migrate", "--noinput"],
|
["python", "manage.py", "migrate", "--noinput"],
|
||||||
["python", "manage.py", "init_payment_plans"]
|
["python", "manage.py", "init_payment_plans"],
|
||||||
|
["python", "manage.py", "init_payment_modes"],
|
||||||
|
["python", "manage.py", "init_data"]
|
||||||
]
|
]
|
||||||
|
|
||||||
for command in commands:
|
for command in commands:
|
||||||
|
|||||||
@ -17,8 +17,10 @@ import { createDatas,
|
|||||||
fetchTuitionDiscounts,
|
fetchTuitionDiscounts,
|
||||||
fetchRegistrationFees,
|
fetchRegistrationFees,
|
||||||
fetchTuitionFees,
|
fetchTuitionFees,
|
||||||
fetchRregistrationPaymentPlans,
|
fetchRegistrationPaymentPlans,
|
||||||
fetchTuitionPaymentPlans } from '@/app/lib/schoolAction';
|
fetchTuitionPaymentPlans,
|
||||||
|
fetchRegistrationPaymentModes,
|
||||||
|
fetchTuitionPaymentModes } from '@/app/lib/schoolAction';
|
||||||
import SidebarTabs from '@/components/SidebarTabs';
|
import SidebarTabs from '@/components/SidebarTabs';
|
||||||
import FilesManagement from '@/components/Structure/Files/FilesManagement';
|
import FilesManagement from '@/components/Structure/Files/FilesManagement';
|
||||||
|
|
||||||
@ -38,6 +40,8 @@ export default function Page() {
|
|||||||
const [fichiers, setFichiers] = useState([]);
|
const [fichiers, setFichiers] = useState([]);
|
||||||
const [registrationPaymentPlans, setRegistrationPaymentPlans] = useState([]);
|
const [registrationPaymentPlans, setRegistrationPaymentPlans] = useState([]);
|
||||||
const [tuitionPaymentPlans, setTuitionPaymentPlans] = useState([]);
|
const [tuitionPaymentPlans, setTuitionPaymentPlans] = useState([]);
|
||||||
|
const [registrationPaymentModes, setRegistrationPaymentModes] = useState([]);
|
||||||
|
const [tuitionPaymentModes, setTuitionPaymentModes] = useState([]);
|
||||||
|
|
||||||
const csrfToken = useCsrfToken();
|
const csrfToken = useCsrfToken();
|
||||||
|
|
||||||
@ -78,6 +82,12 @@ export default function Page() {
|
|||||||
|
|
||||||
// Fetch data for tuition payment plans
|
// Fetch data for tuition payment plans
|
||||||
handleTuitionPaymentPlans();
|
handleTuitionPaymentPlans();
|
||||||
|
|
||||||
|
// Fetch data for registration payment modes
|
||||||
|
handleRegistrationPaymentModes();
|
||||||
|
|
||||||
|
// Fetch data for tuition payment modes
|
||||||
|
handleTuitionPaymentModes();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSpecialities = () => {
|
const handleSpecialities = () => {
|
||||||
@ -145,7 +155,7 @@ export default function Page() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRegistrationPaymentPlans = () => {
|
const handleRegistrationPaymentPlans = () => {
|
||||||
fetchRregistrationPaymentPlans()
|
fetchRegistrationPaymentPlans()
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setRegistrationPaymentPlans(data);
|
setRegistrationPaymentPlans(data);
|
||||||
})
|
})
|
||||||
@ -160,6 +170,22 @@ export default function Page() {
|
|||||||
.catch(error => console.error('Error fetching tuition payment plans:', error));
|
.catch(error => console.error('Error fetching tuition payment plans:', error));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRegistrationPaymentModes = () => {
|
||||||
|
fetchRegistrationPaymentModes()
|
||||||
|
.then(data => {
|
||||||
|
setRegistrationPaymentModes(data);
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching registration payment modes:', error));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTuitionPaymentModes = () => {
|
||||||
|
fetchTuitionPaymentModes()
|
||||||
|
.then(data => {
|
||||||
|
setTuitionPaymentModes(data);
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching tuition payment modes:', error));
|
||||||
|
};
|
||||||
|
|
||||||
const handleCreate = (url, newData, setDatas) => {
|
const handleCreate = (url, newData, setDatas) => {
|
||||||
return createDatas(url, newData, csrfToken)
|
return createDatas(url, newData, csrfToken)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@ -263,7 +289,10 @@ export default function Page() {
|
|||||||
setRegistrationPaymentPlans={setRegistrationPaymentPlans}
|
setRegistrationPaymentPlans={setRegistrationPaymentPlans}
|
||||||
tuitionPaymentPlans={tuitionPaymentPlans}
|
tuitionPaymentPlans={tuitionPaymentPlans}
|
||||||
setTuitionPaymentPlans={setTuitionPaymentPlans}
|
setTuitionPaymentPlans={setTuitionPaymentPlans}
|
||||||
setRegist
|
registrationPaymentModes={registrationPaymentModes}
|
||||||
|
setRegistrationPaymentModes={setRegistrationPaymentModes}
|
||||||
|
tuitionPaymentModes={tuitionPaymentModes}
|
||||||
|
setTuitionPaymentModes={setTuitionPaymentModes}
|
||||||
handleCreate={handleCreate}
|
handleCreate={handleCreate}
|
||||||
handleEdit={handleEdit}
|
handleEdit={handleEdit}
|
||||||
handleDelete={handleDelete}
|
handleDelete={handleDelete}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
BE_SCHOOL_FEES_URL,
|
BE_SCHOOL_FEES_URL,
|
||||||
BE_SCHOOL_DISCOUNTS_URL,
|
BE_SCHOOL_DISCOUNTS_URL,
|
||||||
BE_SCHOOL_PAYMENT_PLANS_URL,
|
BE_SCHOOL_PAYMENT_PLANS_URL,
|
||||||
|
BE_SCHOOL_PAYMENT_MODES_URL
|
||||||
} from '@/utils/Url';
|
} from '@/utils/Url';
|
||||||
|
|
||||||
const requestResponseHandler = async (response) => {
|
const requestResponseHandler = async (response) => {
|
||||||
@ -61,7 +62,7 @@ export const fetchTuitionFees = () => {
|
|||||||
.then(requestResponseHandler)
|
.then(requestResponseHandler)
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchRregistrationPaymentPlans = () => {
|
export const fetchRegistrationPaymentPlans = () => {
|
||||||
return fetch(`${BE_SCHOOL_PAYMENT_PLANS_URL}/registration`)
|
return fetch(`${BE_SCHOOL_PAYMENT_PLANS_URL}/registration`)
|
||||||
.then(requestResponseHandler)
|
.then(requestResponseHandler)
|
||||||
}
|
}
|
||||||
@ -71,6 +72,16 @@ export const fetchTuitionPaymentPlans = () => {
|
|||||||
.then(requestResponseHandler)
|
.then(requestResponseHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const fetchRegistrationPaymentModes = () => {
|
||||||
|
return fetch(`${BE_SCHOOL_PAYMENT_MODES_URL}/registration`)
|
||||||
|
.then(requestResponseHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchTuitionPaymentModes = () => {
|
||||||
|
return fetch(`${BE_SCHOOL_PAYMENT_MODES_URL}/tuition`)
|
||||||
|
.then(requestResponseHandler)
|
||||||
|
}
|
||||||
|
|
||||||
export const createDatas = (url, newData, csrfToken) => {
|
export const createDatas = (url, newData, csrfToken) => {
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@ -1,41 +1,59 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import CheckBoxList from '@/components/CheckBoxList';
|
import { DollarSign } from 'lucide-react';
|
||||||
import { CreditCard } from 'lucide-react';
|
|
||||||
|
|
||||||
const paymentModes = [
|
const paymentModesOptions = [
|
||||||
{ id: 1, name: 'Prélèvement SEPA' },
|
{ id: 1, name: 'Prélèvement SEPA' },
|
||||||
{ id: 2, name: 'Virement' },
|
{ id: 2, name: 'Virement' },
|
||||||
{ id: 3, name: 'Chèque' },
|
{ id: 3, name: 'Chèque' },
|
||||||
{ id: 4, name: 'Espèce' },
|
{ id: 4, name: 'Espèce' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const PaymentModeSelector = ({ formData, setFormData, fieldName }) => {
|
const PaymentModeSelector = ({ paymentModes, setPaymentModes, handleEdit, type }) => {
|
||||||
const handleCheckboxChange = (event) => {
|
const [activePaymentModes, setActivePaymentModes] = useState([]);
|
||||||
const value = parseInt(event.target.value, 10);
|
|
||||||
setFormData((prevFormData) => {
|
useEffect(() => {
|
||||||
const selectedModes = prevFormData[fieldName] || [];
|
// Initialiser activePaymentModes avec les modes dont is_active est à true
|
||||||
const newSelectedModes = selectedModes.includes(value)
|
const activeModes = paymentModes.filter(mode => mode.is_active).map(mode => mode.mode);
|
||||||
? selectedModes.filter((mode) => mode !== value)
|
setActivePaymentModes(activeModes);
|
||||||
: [...selectedModes, value];
|
}, [paymentModes]);
|
||||||
return { ...prevFormData, [fieldName]: newSelectedModes };
|
|
||||||
|
const handleModeToggle = (modeId) => {
|
||||||
|
setActivePaymentModes((prevActiveModes) => {
|
||||||
|
const newActiveModes = prevActiveModes.includes(modeId)
|
||||||
|
? prevActiveModes.filter((mode) => mode !== modeId)
|
||||||
|
: [...prevActiveModes, modeId];
|
||||||
|
|
||||||
|
// Mettre à jour le mode de paiement dans le backend
|
||||||
|
const updatedMode = paymentModes.find(mode => mode.mode === modeId);
|
||||||
|
if (updatedMode) {
|
||||||
|
handleEdit(updatedMode.id, { ...updatedMode, is_active: !updatedMode.is_active });
|
||||||
|
}
|
||||||
|
|
||||||
|
return newActiveModes;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mb-4 w-full">
|
<div className="space-y-4">
|
||||||
<div className="flex justify-center bg-gray p-4 rounded-lg shadow-md w-full">
|
<div className="flex items-center mb-4">
|
||||||
<CreditCard className="w-6 h-6 text-emerald-500 mr-2" />
|
<DollarSign className="w-6 h-6 text-emerald-500 mr-2" />
|
||||||
<h2 className="text-xl font-semibold">Mode de paiement</h2>
|
<h2 className="text-xl font-semibold">Modes de paiement</h2>
|
||||||
<CheckBoxList
|
</div>
|
||||||
items={paymentModes}
|
<div className="grid grid-cols-2 gap-4 mt-4">
|
||||||
formData={formData}
|
{paymentModesOptions.map((mode) => (
|
||||||
handleChange={handleCheckboxChange}
|
<button
|
||||||
fieldName={fieldName}
|
key={mode.id}
|
||||||
itemLabelFunc={(item) => (
|
type="button"
|
||||||
<span className="text-sm font-medium">{item.name}</span>
|
onClick={() => handleModeToggle(mode.id)}
|
||||||
)}
|
className={`p-4 rounded-lg shadow-md text-center text-gray-700' ${
|
||||||
horizontal={true}
|
activePaymentModes.includes(mode.id)
|
||||||
/>
|
? 'bg-emerald-300'
|
||||||
|
: 'bg-white'
|
||||||
|
} hover:bg-emerald-200`}
|
||||||
|
>
|
||||||
|
{mode.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import FeesSection from '@/components/Structure/Tarification/FeesSection';
|
|||||||
import DiscountsSection from '@/components/Structure/Tarification/DiscountsSection';
|
import DiscountsSection from '@/components/Structure/Tarification/DiscountsSection';
|
||||||
import PaymentPlanSelector from '@/components/PaymentPlanSelector';
|
import PaymentPlanSelector from '@/components/PaymentPlanSelector';
|
||||||
import PaymentModeSelector from '@/components/PaymentModeSelector';
|
import PaymentModeSelector from '@/components/PaymentModeSelector';
|
||||||
import { BE_SCHOOL_FEE_URL, BE_SCHOOL_DISCOUNT_URL, BE_SCHOOL_PAYMENT_PLAN_URL } from '@/utils/Url';
|
import { BE_SCHOOL_FEE_URL, BE_SCHOOL_DISCOUNT_URL, BE_SCHOOL_PAYMENT_PLAN_URL, BE_SCHOOL_PAYMENT_MODE_URL } from '@/utils/Url';
|
||||||
import { set } from 'lodash';
|
import { set } from 'lodash';
|
||||||
|
|
||||||
const FeesManagement = ({ registrationDiscounts,
|
const FeesManagement = ({ registrationDiscounts,
|
||||||
@ -18,6 +18,10 @@ const FeesManagement = ({ registrationDiscounts,
|
|||||||
setRegistrationPaymentPlans,
|
setRegistrationPaymentPlans,
|
||||||
tuitionPaymentPlans,
|
tuitionPaymentPlans,
|
||||||
setTuitionPaymentPlans,
|
setTuitionPaymentPlans,
|
||||||
|
registrationPaymentModes,
|
||||||
|
setRegistrationPaymentModes,
|
||||||
|
tuitionPaymentModes,
|
||||||
|
setTuitionPaymentModes,
|
||||||
handleCreate,
|
handleCreate,
|
||||||
handleEdit,
|
handleEdit,
|
||||||
handleDelete }) => {
|
handleDelete }) => {
|
||||||
@ -75,13 +79,14 @@ const FeesManagement = ({ registrationDiscounts,
|
|||||||
type={0}
|
type={0}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="col-span-1">
|
<div className="col-span-1 p-6 rounded-lg shadow-inner mt-4">
|
||||||
<PaymentModeSelector
|
<PaymentModeSelector
|
||||||
formData={formRegistrationData}
|
paymentModes={registrationPaymentModes}
|
||||||
setFormData={setFormRegistrationData}
|
setPaymentModes={setRegistrationPaymentModes}
|
||||||
fieldName="paymentRegistrationMode"
|
handleEdit={(id, updatedData) => handleEdit(`${BE_SCHOOL_PAYMENT_MODE_URL}`, id, updatedData, setRegistrationPaymentModes)}
|
||||||
|
type={0}
|
||||||
/>
|
/>
|
||||||
</div> */}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white p-2 rounded-lg shadow-md">
|
<div className="bg-white p-2 rounded-lg shadow-md">
|
||||||
@ -117,6 +122,14 @@ const FeesManagement = ({ registrationDiscounts,
|
|||||||
type={1}
|
type={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-span-1 p-6 rounded-lg shadow-inner mt-4">
|
||||||
|
<PaymentModeSelector
|
||||||
|
paymentModes={tuitionPaymentModes}
|
||||||
|
setPaymentModes={setTuitionPaymentModes}
|
||||||
|
handleEdit={(id, updatedData) => handleEdit(`${BE_SCHOOL_PAYMENT_MODE_URL}`, id, updatedData, setTuitionPaymentModes)}
|
||||||
|
type={1}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -39,6 +39,8 @@ export const BE_SCHOOL_DISCOUNT_URL = `${BASE_URL}/School/discount`;
|
|||||||
export const BE_SCHOOL_DISCOUNTS_URL = `${BASE_URL}/School/discounts`;
|
export const BE_SCHOOL_DISCOUNTS_URL = `${BASE_URL}/School/discounts`;
|
||||||
export const BE_SCHOOL_PAYMENT_PLAN_URL = `${BASE_URL}/School/paymentPlan`;
|
export const BE_SCHOOL_PAYMENT_PLAN_URL = `${BASE_URL}/School/paymentPlan`;
|
||||||
export const BE_SCHOOL_PAYMENT_PLANS_URL = `${BASE_URL}/School/paymentPlans`;
|
export const BE_SCHOOL_PAYMENT_PLANS_URL = `${BASE_URL}/School/paymentPlans`;
|
||||||
|
export const BE_SCHOOL_PAYMENT_MODE_URL = `${BASE_URL}/School/paymentMode`;
|
||||||
|
export const BE_SCHOOL_PAYMENT_MODES_URL = `${BASE_URL}/School/paymentModes`;
|
||||||
|
|
||||||
// GESTION MESSAGERIE
|
// GESTION MESSAGERIE
|
||||||
export const BE_GESTIONMESSAGERIE_MESSAGES_URL = `${BASE_URL}/GestionMessagerie/messagerie`
|
export const BE_GESTIONMESSAGERIE_MESSAGES_URL = `${BASE_URL}/GestionMessagerie/messagerie`
|
||||||
|
|||||||
Reference in New Issue
Block a user