From 7fe53465acc2df53351f713ccacd12223d6eff1a Mon Sep 17 00:00:00 2001 From: N3WT DE COMPET Date: Sun, 18 May 2025 10:45:00 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Remplacement=20des=20enum=20par=20des=20?= =?UTF-8?q?mod=C3=A8les=20pour=20les=20payementModes=20et=20les=20payement?= =?UTF-8?q?Plans?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Back-End/Establishment/serializers.py | 8 +- .../management/commands/init_mock_datas.py | 18 +- Back-End/School/models.py | 37 +- Back-End/School/signals.py | 26 +- Back-End/School/views.py | 1 - Back-End/Subscriptions/models.py | 8 +- .../templatetags/myTemplateTag.py | 17 +- .../Inscription/InscriptionFormShared.js | 20 +- .../Inscription/PaymentMethodSelector.js | 10 +- .../src/components/PaymentModeSelector.js | 38 +- .../src/components/PaymentPlanSelector.js | 366 ++++-------------- .../Structure/Tarification/FeesManagement.js | 50 ++- 12 files changed, 198 insertions(+), 401 deletions(-) diff --git a/Back-End/Establishment/serializers.py b/Back-End/Establishment/serializers.py index 990038c..50909ca 100644 --- a/Back-End/Establishment/serializers.py +++ b/Back-End/Establishment/serializers.py @@ -67,16 +67,16 @@ class EstablishmentSerializer(serializers.ModelSerializer): return list(Discount.objects.filter(establishment=obj).distinct().values_list('name', flat=True)) def get_active_payment_mode_count(self, obj): - return PaymentMode.objects.filter(establishment=obj, is_active=True).distinct().count() + return PaymentMode.objects.filter(establishment=obj).distinct().count() def get_active_payment_modes(self, obj): - return list(PaymentMode.objects.filter(establishment=obj, is_active=True).distinct().values_list('mode', flat=True)) + return list(PaymentMode.objects.filter(establishment=obj).distinct().values_list('mode', flat=True)) def get_active_payment_plan_count(self, obj): - return PaymentPlan.objects.filter(establishment=obj, is_active=True).distinct().count() + return PaymentPlan.objects.filter(establishment=obj).distinct().count() def get_active_payment_plans(self, obj): - return list(PaymentPlan.objects.filter(establishment=obj, is_active=True).distinct().values_list('frequency', flat=True)) + return list(PaymentPlan.objects.filter(establishment=obj).distinct().values_list('plan_type', flat=True)) def get_file_group_count(self, obj): return RegistrationFileGroup.objects.filter(establishment=obj).distinct().count() diff --git a/Back-End/School/management/commands/init_mock_datas.py b/Back-End/School/management/commands/init_mock_datas.py index 003da40..511c318 100644 --- a/Back-End/School/management/commands/init_mock_datas.py +++ b/Back-End/School/management/commands/init_mock_datas.py @@ -157,16 +157,15 @@ class Command(BaseCommand): self.stdout.write(self.style.ERROR(f'Error in data for discount: {serializer.errors}')) def init_payment_modes(self): - modes = [PaymentModeType.SEPA, PaymentModeType.TRANSFER, PaymentModeType.CHECK, PaymentModeType.CASH] + modes = list(PaymentModeType.objects.filter(code__in=["SEPA", "TRANSFER", "CHECK", "CASH"])) types = [FeeType.REGISTRATION_FEE, FeeType.TUITION_FEE] for establishment in self.establishments: for mode in modes: for type in types: payment_mode_data = { - "mode": mode, + "mode": mode.pk, "type": type, - "is_active": random.choice([True, False]), "establishment": establishment.id } @@ -178,7 +177,7 @@ class Command(BaseCommand): self.stdout.write(self.style.ERROR(f'Error in data for payment mode: {serializer.errors}')) def init_payment_plans(self): - frequencies = [PaymentPlanType.ONE_TIME, PaymentPlanType.THREE_TIMES, PaymentPlanType.TEN_TIMES, PaymentPlanType.TWELVE_TIMES] + frequencies = list(PaymentPlanType.objects.filter(code__in=["ONE_TIME", "THREE_TIMES", "TEN_TIMES", "TWELVE_TIMES"])) types = [FeeType.REGISTRATION_FEE, FeeType.TUITION_FEE] current_date = timezone.now().date() @@ -186,9 +185,8 @@ class Command(BaseCommand): for frequency in frequencies: for type in types: payment_plan_data = { - "frequency": frequency, + "frequency": frequency.pk, "type": type, - "is_active": random.choice([True, False]), "establishment": establishment.id, "due_dates": self.generate_due_dates(frequency, current_date) } @@ -201,13 +199,13 @@ class Command(BaseCommand): self.stdout.write(self.style.ERROR(f'Error in data for payment plan: {serializer.errors}')) def generate_due_dates(self, frequency, start_date): - if frequency == PaymentPlanType.ONE_TIME: + if frequency.code == "ONE_TIME": return [start_date + relativedelta(months=1)] - elif frequency == PaymentPlanType.THREE_TIMES: + elif frequency.code == "THREE_TIMES": return [start_date + relativedelta(months=1+4*i) for i in range(3)] - elif frequency == PaymentPlanType.TEN_TIMES: + elif frequency.code == "TEN_TIMES": return [start_date + relativedelta(months=1+i) for i in range(10)] - elif frequency == PaymentPlanType.TWELVE_TIMES: + elif frequency.code == "TWELVE_TIMES": return [start_date + relativedelta(months=1+i) for i in range(12)] def init_specialities(self): diff --git a/Back-End/School/models.py b/Back-End/School/models.py index d1cfa21..6e8a0cf 100644 --- a/Back-End/School/models.py +++ b/Back-End/School/models.py @@ -67,12 +67,6 @@ class Planning(models.Model): def __str__(self): return f'Planning for {self.level} of {self.school_class.atmosphere_name}' -class PaymentPlanType(models.IntegerChoices): - ONE_TIME = 1, '1 fois' - THREE_TIMES = 3, '3 fois' - TEN_TIMES = 10, '10 fois' - TWELVE_TIMES = 12, '12 fois' - class DiscountType(models.IntegerChoices): CURRENCY = 0, 'Currency' PERCENT = 1, 'Percent' @@ -81,11 +75,20 @@ class FeeType(models.IntegerChoices): REGISTRATION_FEE = 0, 'Registration 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 PaymentPlanType(models.Model): + code = models.CharField(max_length=50, unique=True) + label = models.CharField(max_length=255) + + def __str__(self): + return self.label + +class PaymentModeType(models.Model): + code = models.CharField(max_length=50, unique=True) + label = models.CharField(max_length=255) + is_active = models.BooleanField(default=True) + + def __str__(self): + return self.label class Discount(models.Model): name = models.CharField(max_length=255, null=True, blank=True) @@ -112,23 +115,21 @@ class Fee(models.Model): return self.name class PaymentPlan(models.Model): - frequency = models.IntegerField(choices=PaymentPlanType.choices, default=PaymentPlanType.ONE_TIME) - due_dates = ArrayField(models.DateField(), blank=True) + plan_type = models.ForeignKey(PaymentPlanType, on_delete=models.PROTECT, related_name='payment_plans') + due_dates = ArrayField(models.DateField(), null=True, blank=True) type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE) - is_active = models.BooleanField(default=False) establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='payment_plans') def __str__(self): - return f"{self.get_frequency_display()} - {self.get_type_display()}" + return f"{self.plan_type.label} - {self.get_type_display()}" class PaymentMode(models.Model): - mode = models.IntegerField(choices=PaymentModeType.choices, default=PaymentModeType.SEPA) + mode = models.ForeignKey(PaymentModeType, on_delete=models.PROTECT, related_name='payment_modes') type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE) - is_active = models.BooleanField(default=False) establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='payment_modes') def __str__(self): - return f"{self.get_mode_display()} - {self.get_type_display()}" + return f"{self.mode.label} - {self.get_type_display()}" class Domain(models.Model): name = models.CharField(max_length=255) diff --git a/Back-End/School/signals.py b/Back-End/School/signals.py index 1246564..8567ac2 100644 --- a/Back-End/School/signals.py +++ b/Back-End/School/signals.py @@ -2,11 +2,10 @@ import json import os from django.db.models.signals import post_migrate from django.dispatch import receiver -from Establishment.models import Establishment -from School.models import Domain, Category, Competency, EstablishmentCompetency +from School.models import Domain, Category, Competency, PaymentModeType, PaymentPlanType @receiver(post_migrate) -def load_json_data(sender, **kwargs): +def school_post_migrate(sender, **kwargs): if sender.name != "School": return @@ -47,4 +46,23 @@ def load_json_data(sender, **kwargs): level=competency_data.get('niveau'), category=category ) - print(f"Données importées depuis : {json_file_path}") \ No newline at end of file + print(f"Données importées depuis : {json_file_path}") + + payment_mode_types = [ + {"code": "SEPA", "label": "Prélèvement SEPA"}, + {"code": "TRANSFER", "label": "Virement"}, + {"code": "CHECK", "label": "Chèque"}, + {"code": "CASH", "label": "Espèce"}, + ] + for mode in payment_mode_types: + PaymentModeType.objects.get_or_create(code=mode["code"], defaults={"label": mode["label"]}) + + # ... après la création des PaymentModeType ... + payment_plan_types = [ + {"code": "ONE_TIME", "label": "1 fois"}, + {"code": "THREE_TIMES", "label": "3 fois"}, + {"code": "TEN_TIMES", "label": "10 fois"}, + {"code": "TWELVE_TIMES", "label": "12 fois"}, + ] + for plan in payment_plan_types: + PaymentPlanType.objects.get_or_create(code=plan["code"], defaults={"label": plan["label"]}) \ No newline at end of file diff --git a/Back-End/School/views.py b/Back-End/School/views.py index 7448312..eecfb78 100644 --- a/Back-End/School/views.py +++ b/Back-End/School/views.py @@ -531,7 +531,6 @@ class CompetencyListCreateView(APIView): category__domain__cycle=cycle ).distinct() serializer = CompetencySerializer(competencies_list, many=True) - print(f'len : {competencies_list.count()}') return JsonResponse(serializer.data, safe=False) def post(self, request): diff --git a/Back-End/Subscriptions/models.py b/Back-End/Subscriptions/models.py index 0e3c1a6..a9b81bd 100644 --- a/Back-End/Subscriptions/models.py +++ b/Back-End/Subscriptions/models.py @@ -247,10 +247,10 @@ class RegistrationForm(models.Model): blank=True) establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='register_forms') - registration_payment = models.IntegerField(choices=PaymentModeType.choices, null=True, blank=True) - tuition_payment = models.IntegerField(choices=PaymentModeType.choices, null=True, blank=True) - registration_payment_plan = models.IntegerField(choices=PaymentPlanType.choices, null=True, blank=True) - tuition_payment_plan = models.IntegerField(choices=PaymentPlanType.choices, null=True, blank=True) + registration_payment = models.ForeignKey('School.PaymentModeType', on_delete=models.SET_NULL, null=True, blank=True, related_name='registration_payment_modes_forms') + tuition_payment = models.ForeignKey('School.PaymentModeType', on_delete=models.SET_NULL, null=True, blank=True, related_name='tuition_payment_modes_forms') + registration_payment_plan = models.ForeignKey('School.PaymentPlanType', on_delete=models.SET_NULL, null=True, blank=True, related_name='registration_payment_plans_forms') + tuition_payment_plan = models.ForeignKey('School.PaymentPlanType', on_delete=models.SET_NULL, null=True, blank=True, related_name='tuition_payment_plans_forms') def __str__(self): return "RF_" + self.student.last_name + "_" + self.student.first_name diff --git a/Back-End/Subscriptions/templatetags/myTemplateTag.py b/Back-End/Subscriptions/templatetags/myTemplateTag.py index cc47171..56a7d91 100644 --- a/Back-End/Subscriptions/templatetags/myTemplateTag.py +++ b/Back-End/Subscriptions/templatetags/myTemplateTag.py @@ -1,5 +1,4 @@ from Subscriptions.models import RegistrationForm, Student -from School.models import PaymentModeType, PaymentPlanType from django import template import re @@ -8,22 +7,30 @@ register = template.Library() @register.filter def getRegistrationPaymentPlan(pk): registerForm = RegistrationForm.objects.get(student=pk) - return PaymentPlanType(registerForm.registration_payment_plan).label + if registerForm.registration_payment_plan: + return registerForm.registration_payment_plan.label + return "" @register.filter def getTuitionPaymentPlan(pk): registerForm = RegistrationForm.objects.get(student=pk) - return PaymentPlanType(registerForm.tuition_payment_plan).label + if registerForm.tuition_payment_plan: + return registerForm.tuition_payment_plan.label + return "" @register.filter def getRegistrationPaymentMethod(pk): registerForm = RegistrationForm.objects.get(student=pk) - return PaymentModeType(registerForm.registration_payment).label + if registerForm.registration_payment: + return registerForm.registration_payment.label + return "" @register.filter def getTuitionPaymentMethod(pk): registerForm = RegistrationForm.objects.get(student=pk) - return PaymentModeType(registerForm.tuition_payment).label + if registerForm.tuition_payment: + return registerForm.tuition_payment.label + return "" @register.filter def getStudentLevel(pk): diff --git a/Front-End/src/components/Inscription/InscriptionFormShared.js b/Front-End/src/components/Inscription/InscriptionFormShared.js index 9bc0ff6..cfe3ebe 100644 --- a/Front-End/src/components/Inscription/InscriptionFormShared.js +++ b/Front-End/src/components/Inscription/InscriptionFormShared.js @@ -230,10 +230,7 @@ export default function InscriptionFormShared({ const handleRegistrationPaymentModes = () => { fetchRegistrationPaymentModes(selectedEstablishmentId) .then((data) => { - const activePaymentModes = data.filter( - (mode) => mode.is_active === true - ); - setRegistrationPaymentModes(activePaymentModes); + setRegistrationPaymentModes(data); }) .catch((error) => logger.error('Error fetching registration payment modes:', error) @@ -243,10 +240,7 @@ export default function InscriptionFormShared({ const handleTuitionPaymentModes = () => { fetchTuitionPaymentModes(selectedEstablishmentId) .then((data) => { - const activePaymentModes = data.filter( - (mode) => mode.is_active === true - ); - setTuitionPaymentModes(activePaymentModes); + setTuitionPaymentModes(data); }) .catch((error) => logger.error('Error fetching tuition payment modes:', error) @@ -256,10 +250,7 @@ export default function InscriptionFormShared({ const handleRegistrationPaymentPlans = () => { fetchRegistrationPaymentPlans(selectedEstablishmentId) .then((data) => { - const activePaymentPlans = data.filter( - (mode) => mode.is_active === true - ); - setRegistrationPaymentPlans(activePaymentPlans); + setRegistrationPaymentPlans(data); }) .catch((error) => logger.error('Error fetching registration payment plans:', error) @@ -269,10 +260,7 @@ export default function InscriptionFormShared({ const handleTuitionnPaymentPlans = () => { fetchTuitionPaymentPlans(selectedEstablishmentId) .then((data) => { - const activePaymentPlans = data.filter( - (mode) => mode.is_active === true - ); - setTuitionPaymentPlans(activePaymentPlans); + setTuitionPaymentPlans(data); }) .catch((error) => logger.error('Error fetching registration tuition plans:', error) diff --git a/Front-End/src/components/Inscription/PaymentMethodSelector.js b/Front-End/src/components/Inscription/PaymentMethodSelector.js index 7a37975..4b99012 100644 --- a/Front-End/src/components/Inscription/PaymentMethodSelector.js +++ b/Front-End/src/components/Inscription/PaymentMethodSelector.js @@ -31,9 +31,9 @@ export default function PaymentMethodSelector({ const paymentPlansOptions = [ { id: 1, name: '1 fois' }, - { id: 3, name: '3 fois' }, - { id: 10, name: '10 fois' }, - { id: 12, name: '12 fois' }, + { id: 2, name: '3 fois' }, + { id: 3, name: '10 fois' }, + { id: 4, name: '12 fois' }, ]; const getError = (field) => { @@ -105,7 +105,7 @@ export default function PaymentMethodSelector({ items={paymentPlansOptions .filter((option) => registrationPaymentPlans.some( - (plan) => plan.frequency === option.id + (plan) => plan.plan_type === option.id ) ) .map((option) => ({ @@ -167,7 +167,7 @@ export default function PaymentMethodSelector({ required items={paymentPlansOptions .filter((option) => - tuitionPaymentPlans.some((plan) => plan.frequency === option.id) + tuitionPaymentPlans.some((plan) => plan.plan_type === option.id) ) .map((option) => ({ id: option.id, diff --git a/Front-End/src/components/PaymentModeSelector.js b/Front-End/src/components/PaymentModeSelector.js index b04e4a2..1bfb343 100644 --- a/Front-End/src/components/PaymentModeSelector.js +++ b/Front-End/src/components/PaymentModeSelector.js @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; import { DollarSign } from 'lucide-react'; +import { useEstablishment } from '@/context/EstablishmentContext'; const paymentModesOptions = [ { id: 1, name: 'Prélèvement SEPA' }, @@ -11,36 +12,31 @@ const paymentModesOptions = [ const PaymentModeSelector = ({ paymentModes, setPaymentModes, - handleEdit, + handleCreate, + handleDelete, type, }) => { const [activePaymentModes, setActivePaymentModes] = useState([]); + const { selectedEstablishmentId } = useEstablishment(); useEffect(() => { - // Initialiser activePaymentModes avec les modes dont is_active est à true - const activeModes = paymentModes - .filter((mode) => mode.is_active) - .map((mode) => mode.mode); + const activeModes = paymentModes.map((mode) => mode.mode); setActivePaymentModes(activeModes); }, [paymentModes]); const handleModeToggle = (modeId) => { - setActivePaymentModes((prevActiveModes) => { - const newActiveModes = prevActiveModes.includes(modeId) - ? prevActiveModes.filter((mode) => mode !== modeId) - : [...prevActiveModes, modeId]; + const updatedMode = paymentModes.find((mode) => mode.mode === modeId); + const isActive = !!updatedMode; - // 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; - }); + if (!isActive) { + handleCreate({ + mode: modeId, + type, + establishment: selectedEstablishmentId, + }); + } else { + handleDelete(updatedMode.id, null); + } }; return ( @@ -55,7 +51,7 @@ const PaymentModeSelector = ({ key={mode.id} type="button" onClick={() => handleModeToggle(mode.id)} - className={`p-4 rounded-lg shadow-md text-center text-gray-700' ${ + className={`p-4 rounded-lg shadow-md text-center text-gray-700 ${ activePaymentModes.includes(mode.id) ? 'bg-emerald-100' : 'bg-stone-50' diff --git a/Front-End/src/components/PaymentPlanSelector.js b/Front-End/src/components/PaymentPlanSelector.js index 7f75a00..b34c26c 100644 --- a/Front-End/src/components/PaymentPlanSelector.js +++ b/Front-End/src/components/PaymentPlanSelector.js @@ -1,281 +1,62 @@ import React, { useState, useEffect } from 'react'; -import { Calendar, Eye, EyeOff, Clock, Check } from 'lucide-react'; +import { Calendar } from 'lucide-react'; import Table from '@/components/Table'; -import DateTab from '@/components/DateTab'; -import InputTextIcon from '@/components/InputTextIcon'; import Popup from '@/components/Popup'; import logger from '@/utils/logger'; +import { useEstablishment } from '@/context/EstablishmentContext'; +import CheckBox from '@/components/CheckBox'; const paymentPlansOptions = [ - { id: 0, name: '1 fois', frequency: 1 }, - { id: 1, name: '3 fois', frequency: 3 }, - { id: 2, name: '10 fois', frequency: 10 }, - { id: 3, name: '12 fois', frequency: 12 }, + { id: 1, name: '1 fois', frequency: 1 }, + { id: 2, name: '3 fois', frequency: 3 }, + { id: 3, name: '10 fois', frequency: 10 }, + { id: 4, name: '12 fois', frequency: 12 }, ]; const PaymentPlanSelector = ({ paymentPlans, - setPaymentPlans, - handleEdit, + handleCreate, + handleDelete, type, }) => { - const [dates, setDates] = useState({}); - const [selectedFrequency, setSelectedFrequency] = useState(null); - const [activeFrequencies, setActiveFrequencies] = useState([]); - const [defaultDay, setDefaultDay] = useState('-'); - const [isDefaultDayModified, setIsDefaultDayModified] = useState(false); const [popupVisible, setPopupVisible] = useState(false); const [popupMessage, setPopupMessage] = useState(''); - const [errorMsg, setErrorMsg] = useState(''); - const [resetModifiedDates, setResetModifiedDates] = useState(false); + const { selectedEstablishmentId } = useEstablishment(); + const [checkedPlans, setCheckedPlans] = useState([]); + + // Vérifie si un plan existe pour ce type (par id) + const isChecked = (planOption) => checkedPlans.includes(planOption.id); + + // Création ou suppression du plan + const handlePlanToggle = (planOption) => { + const updatedPlan = paymentPlans.find( + (plan) => plan.plan_type === planOption.id + ); + if (isChecked(planOption)) { + setCheckedPlans((prev) => prev.filter((id) => id !== planOption.id)); + handleDelete(updatedPlan.id, null); + } else { + setCheckedPlans((prev) => [...prev, planOption.id]); + handleCreate({ + plan_type: planOption.id, + type, + establishment: selectedEstablishmentId, + }); + } + }; useEffect(() => { if (paymentPlans && paymentPlans.length > 0) { - const activePlans = paymentPlans.filter((plan) => plan.is_active); - const frequencies = activePlans - .map((plan) => { - const paymentPlanOption = paymentPlansOptions.find( - (p) => p.frequency === plan.frequency - ); - return paymentPlanOption ? paymentPlanOption.id : null; - }) - .filter((id) => id !== null); - setActiveFrequencies(frequencies); - - if (activePlans.length > 0) { - const firstDueDate = new Date(activePlans[0].due_dates[0]); - setDefaultDay(firstDueDate.getDate()); - } - - const initialDates = {}; - paymentPlans.forEach((plan) => { - const paymentPlanOption = paymentPlansOptions.find( - (p) => p.frequency === plan.frequency - ); - if (paymentPlanOption) { - initialDates[paymentPlanOption.id] = plan.due_dates; - } - }); - setDates(initialDates); + setCheckedPlans( + paymentPlans.map((plan) => + typeof plan.plan_type === 'object' + ? plan.plan_type.id + : plan.plan_type + ) + ); } }, [paymentPlans]); - useEffect(() => { - updateDefaultDay(); - }, [dates, selectedFrequency]); - - const updateDefaultDay = () => { - const currentDates = dates[selectedFrequency]; - if (currentDates && currentDates.length > 0) { - const days = currentDates.map((date) => new Date(date).getDate()); - const allSameDay = days.every((day) => day === days[0]); - if (allSameDay) { - setDefaultDay(days[0]); - } else { - setDefaultDay('-'); - setIsDefaultDayModified(false); - } - } else { - setDefaultDay('-'); - } - }; - - const handleActivationChange = (value) => { - const selectedPlan = paymentPlans.find( - (plan) => - plan.frequency === - paymentPlansOptions.find((p) => p.id === value)?.frequency - ); - if (!selectedPlan) return; - - const updatedData = { - ...selectedPlan, - is_active: !selectedPlan.is_active, - }; - - handleEdit(selectedPlan.id, updatedData) - .then(() => { - setPaymentPlans((prevPlans) => - prevPlans.map((plan) => - plan.id === selectedPlan.id - ? { ...plan, is_active: updatedData.is_active } - : plan - ) - ); - setActiveFrequencies((prevFrequencies) => { - if (updatedData.is_active) { - setPopupMessage( - `L'option de paiement en ${paymentPlansOptions.find((p) => p.id === value).name} a été activée.` - ); - setPopupVisible(true); - return [...prevFrequencies, value]; - } else { - setPopupMessage( - `L'option de paiement en ${paymentPlansOptions.find((p) => p.id === value).name} a été désactivée.` - ); - setPopupVisible(true); - return prevFrequencies.filter((item) => item !== value); - } - }); - }) - .catch((error) => { - logger.error(error); - }); - }; - - const handleRowClick = (row) => { - const value = row.id; - - if (selectedFrequency === value) { - setSelectedFrequency(null); // Désélectionner l'onglet si la ligne est déjà sélectionnée - } else { - setSelectedFrequency(value); - - if (!dates[value]) { - const frequencyValue = - paymentPlansOptions.find((plan) => plan.id === value)?.frequency || 1; - - const newDates = Array(frequencyValue) - .fill('') - .map((_, index) => { - const newDate = new Date(); - - // Validate defaultDay - const day = - typeof defaultDay === 'number' && - defaultDay >= 1 && - defaultDay <= 31 - ? defaultDay - : 1; // Fallback to 1 if defaultDay is invalid - - newDate.setDate(day); - - if (value === 1) { - newDate.setMonth(newDate.getMonth() + index * 4); // Espacer de 4 mois pour le paiement en 3 fois - } else { - newDate.setMonth(newDate.getMonth() + index); - } - - return newDate.toISOString().split('T')[0]; - }); - - setDates((prevDates) => ({ ...prevDates, [value]: newDates })); - } - } - }; - - const handleDateChange = (planId, index, date) => { - setDates((prevDates) => { - const newDates = { ...prevDates }; - newDates[planId][index] = date; - return newDates; - }); - }; - - const handleDefaultDayChange = (e) => { - const value = e.target.value; - if (value === '') { - setDefaultDay('-'); - setErrorMsg(''); - setIsDefaultDayModified(false); - return; - } - - const day = parseInt(value, 10); - setDefaultDay(day); - - if (day < 1 || day > 31) { - setErrorMsg('Le jour doit être compris entre 1 et 31.'); - setIsDefaultDayModified(false); - return; - } - - setErrorMsg(''); - setIsDefaultDayModified(true); - setResetModifiedDates(true); - setTimeout(() => setResetModifiedDates(false), 0); - - // Mettre à jour les dates d'échéance en fonction du jour sélectionné - const updatedDates = dates[selectedFrequency].map((date) => { - const newDate = new Date(date); - newDate.setDate(day); - return newDate.toISOString().split('T')[0]; - }); - setDates((prevDates) => ({ - ...prevDates, - [selectedFrequency]: updatedDates, - })); - }; - - const handleSubmitDefaultDay = () => { - const selectedPlan = paymentPlans.find( - (plan) => - plan.frequency === - paymentPlansOptions.find((p) => p.id === selectedFrequency)?.frequency - ); - if (!selectedPlan) return; - - const updatedData = { - ...selectedPlan, - due_dates: dates[selectedFrequency], - }; - - handleEdit(selectedPlan.id, updatedData) - .then(() => { - setPopupMessage( - "Mise à jour des dates d'échéances effectuée avec succès" - ); - setPopupVisible(true); - setIsDefaultDayModified(false); - }) - .catch((error) => { - logger.error(error); - }); - }; - - const columns = [ - { name: 'OPTIONS', label: 'Option' }, - { name: 'ACTIONS', label: 'Action' }, - ]; - - const renderCell = (row, column) => { - switch (column) { - case 'OPTIONS': - return ( - {row.name} - ); - case 'ACTIONS': - return ( - - ); - default: - return null; - } - }; - - const selectedPaymentPlan = paymentPlans.find( - (plan) => - plan.frequency === - paymentPlansOptions.find((p) => p.id === selectedFrequency)?.frequency - ); - return (
@@ -285,49 +66,34 @@ const PaymentPlanSelector = ({
{ + switch (column) { + case 'OPTION': + return ( + + {row.name} + + ); + case 'ACTIF': + return ( + handlePlanToggle(row)} + fieldName="checked" + itemLabelFunc={() => ''} + horizontal={true} + /> + ); + default: + return null; + } + }} /> - {selectedFrequency !== null && selectedPaymentPlan && ( -
-
-
- -
- {isDefaultDayModified && defaultDay && ( - - )} -
- -
- )} - handleEdit( + handleCreate={(newData) => + handleCreate( + `${BE_SCHOOL_PAYMENT_PLANS_URL}`, + newData, + setRegistrationPaymentPlans + ) + } + handleDelete={(id) => + handleDelete( `${BE_SCHOOL_PAYMENT_PLANS_URL}`, id, - updatedData, setRegistrationPaymentPlans ) } @@ -131,11 +137,17 @@ const FeesManagement = ({ - handleEdit( + handleCreate={(newData) => + handleCreate( + `${BE_SCHOOL_PAYMENT_MODES_URL}`, + newData, + setRegistrationPaymentModes + ) + } + handleDelete={(id) => + handleDelete( `${BE_SCHOOL_PAYMENT_MODES_URL}`, id, - updatedData, setRegistrationPaymentModes ) } @@ -200,12 +212,18 @@ const FeesManagement = ({ - handleEdit( + handleCreate={(newData) => + handleCreate( + `${BE_SCHOOL_PAYMENT_PLANS_URL}`, + newData, + setTuitionPaymentPlans + ) + } + handleDelete={(id) => + handleDelete( `${BE_SCHOOL_PAYMENT_PLANS_URL}`, id, - updatedData, - setRegistrationPaymentPlans + setTuitionPaymentPlans ) } type={1} @@ -215,11 +233,17 @@ const FeesManagement = ({ - handleEdit( + handleCreate={(newData) => + handleCreate( + `${BE_SCHOOL_PAYMENT_MODES_URL}`, + newData, + setTuitionPaymentModes + ) + } + handleDelete={(id) => + handleDelete( `${BE_SCHOOL_PAYMENT_MODES_URL}`, id, - updatedData, setTuitionPaymentModes ) }