mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
chore: commit qui sert à rien
This commit is contained in:
24
Back-End/School/management/commands/init_establishment.py
Normal file
24
Back-End/School/management/commands/init_establishment.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from School.models import Establishment, StructureType
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Initialize the establishment'
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
establishment_data = {
|
||||||
|
"name": "N3WT",
|
||||||
|
"address": "Société n3wt-innov 69 Chez LANA",
|
||||||
|
"total_capacity": 69,
|
||||||
|
"establishment_type": [StructureType.MATERNELLE, StructureType.PRIMAIRE],
|
||||||
|
"licence_code": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
establishment, created = Establishment.objects.update_or_create(
|
||||||
|
name=establishment_data["name"],
|
||||||
|
defaults=establishment_data
|
||||||
|
)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
self.stdout.write(self.style.SUCCESS('Establishment created successfully'))
|
||||||
|
else:
|
||||||
|
self.stdout.write(self.style.SUCCESS('Establishment updated successfully'))
|
||||||
@ -1,5 +1,5 @@
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from School.models import PaymentMode, PaymentModeType, FeeType
|
from School.models import PaymentMode, PaymentModeType, FeeType, Establishment
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Initialize or update Payment Modes'
|
help = 'Initialize or update Payment Modes'
|
||||||
@ -8,6 +8,7 @@ class Command(BaseCommand):
|
|||||||
self.create_or_update_payment_modes()
|
self.create_or_update_payment_modes()
|
||||||
|
|
||||||
def create_or_update_payment_modes(self):
|
def create_or_update_payment_modes(self):
|
||||||
|
establishment = Establishment.objects.get(name="N3WT")
|
||||||
for fee_type in FeeType.choices:
|
for fee_type in FeeType.choices:
|
||||||
fee_type_value = fee_type[0]
|
fee_type_value = fee_type[0]
|
||||||
|
|
||||||
@ -18,7 +19,8 @@ class Command(BaseCommand):
|
|||||||
mode=mode_value,
|
mode=mode_value,
|
||||||
type=fee_type_value,
|
type=fee_type_value,
|
||||||
defaults={
|
defaults={
|
||||||
'is_active': False
|
'is_active': False,
|
||||||
|
'establishment': establishment
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from School.models import PaymentPlan, PaymentPlanType, FeeType
|
from School.models import PaymentPlan, PaymentPlanType, FeeType, Establishment
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Initialize or update Payment Plans'
|
help = 'Initialize or update Payment Plans'
|
||||||
@ -11,6 +11,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def create_or_update_payment_plans(self):
|
def create_or_update_payment_plans(self):
|
||||||
current_date = timezone.now().date()
|
current_date = timezone.now().date()
|
||||||
|
establishment = Establishment.objects.get(name="N3WT")
|
||||||
|
|
||||||
for fee_type in FeeType.choices:
|
for fee_type in FeeType.choices:
|
||||||
fee_type_value = fee_type[0]
|
fee_type_value = fee_type[0]
|
||||||
@ -21,7 +22,8 @@ class Command(BaseCommand):
|
|||||||
type=fee_type_value,
|
type=fee_type_value,
|
||||||
defaults={
|
defaults={
|
||||||
'due_dates': [current_date + relativedelta(months=1)],
|
'due_dates': [current_date + relativedelta(months=1)],
|
||||||
'is_active': True
|
'is_active': True,
|
||||||
|
'establishment': establishment
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +33,8 @@ class Command(BaseCommand):
|
|||||||
type=fee_type_value,
|
type=fee_type_value,
|
||||||
defaults={
|
defaults={
|
||||||
'due_dates': [current_date + relativedelta(months=1+4*i) for i in range(3)],
|
'due_dates': [current_date + relativedelta(months=1+4*i) for i in range(3)],
|
||||||
'is_active': False
|
'is_active': False,
|
||||||
|
'establishment': establishment
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +44,8 @@ class Command(BaseCommand):
|
|||||||
type=fee_type_value,
|
type=fee_type_value,
|
||||||
defaults={
|
defaults={
|
||||||
'due_dates': [current_date + relativedelta(months=1+i) for i in range(10)],
|
'due_dates': [current_date + relativedelta(months=1+i) for i in range(10)],
|
||||||
'is_active': False
|
'is_active': False,
|
||||||
|
'establishment': establishment
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,7 +55,8 @@ class Command(BaseCommand):
|
|||||||
type=fee_type_value,
|
type=fee_type_value,
|
||||||
defaults={
|
defaults={
|
||||||
'due_dates': [current_date + relativedelta(months=1+i) for i in range(12)],
|
'due_dates': [current_date + relativedelta(months=1+i) for i in range(12)],
|
||||||
'is_active': False
|
'is_active': False,
|
||||||
|
'establishment': establishment
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from Auth.models import Profile
|
from Auth.models import Profile
|
||||||
from School.models import Speciality, Teacher, SchoolClass
|
from School.models import Speciality, Teacher, SchoolClass, Establishment
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Initialize or update Fees and Discounts'
|
help = 'Initialize or update Fees and Discounts'
|
||||||
@ -108,6 +108,7 @@ class Command(BaseCommand):
|
|||||||
self.stdout.write(self.style.SUCCESS('Teachers initialized or updated successfully'))
|
self.stdout.write(self.style.SUCCESS('Teachers initialized or updated successfully'))
|
||||||
|
|
||||||
def create_or_update_schoolClasses(self):
|
def create_or_update_schoolClasses(self):
|
||||||
|
establishment = Establishment.objects.get(name="N3WT")
|
||||||
school_classes_data = [
|
school_classes_data = [
|
||||||
{
|
{
|
||||||
"atmosphere_name": "Classe A",
|
"atmosphere_name": "Classe A",
|
||||||
@ -119,7 +120,8 @@ class Command(BaseCommand):
|
|||||||
"type": 1,
|
"type": 1,
|
||||||
"time_range": ["08:30", "17:30"],
|
"time_range": ["08:30", "17:30"],
|
||||||
"opening_days": [1, 2, 4, 5],
|
"opening_days": [1, 2, 4, 5],
|
||||||
"teachers": [2] # ID of Severus Rogue
|
"teachers": [2], # ID of Severus Rogue
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"atmosphere_name": "Classe B",
|
"atmosphere_name": "Classe B",
|
||||||
@ -131,7 +133,8 @@ class Command(BaseCommand):
|
|||||||
"type": 1,
|
"type": 1,
|
||||||
"time_range": ["08:30", "17:30"],
|
"time_range": ["08:30", "17:30"],
|
||||||
"opening_days": [1, 2, 4, 5],
|
"opening_days": [1, 2, 4, 5],
|
||||||
"teachers": [3] # ID of Minerva McGonagall
|
"teachers": [3], # ID of Minerva McGonagall
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"atmosphere_name": "Classe C",
|
"atmosphere_name": "Classe C",
|
||||||
@ -143,7 +146,8 @@ class Command(BaseCommand):
|
|||||||
"type": 1,
|
"type": 1,
|
||||||
"time_range": ["08:30", "17:30"],
|
"time_range": ["08:30", "17:30"],
|
||||||
"opening_days": [1, 2, 4, 5],
|
"opening_days": [1, 2, 4, 5],
|
||||||
"teachers": [4] # ID of Pomona Chourave
|
"teachers": [4], # ID of Pomona Chourave
|
||||||
|
"establishment": establishment
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from Auth.models import Profile
|
from Auth.models import Profile
|
||||||
from School.models import Fee, Discount, FeeType, DiscountType
|
from School.models import Fee, Discount, FeeType, DiscountType, Establishment
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Initialize or update Fees and Discounts'
|
help = 'Initialize or update Fees and Discounts'
|
||||||
@ -10,41 +10,47 @@ class Command(BaseCommand):
|
|||||||
self.create_or_update_discounts()
|
self.create_or_update_discounts()
|
||||||
|
|
||||||
def create_or_update_fees(self):
|
def create_or_update_fees(self):
|
||||||
|
establishment = Establishment.objects.get(name="N3WT")
|
||||||
fees_data = [
|
fees_data = [
|
||||||
{
|
{
|
||||||
"name": "Frais d'inscription",
|
"name": "Frais d'inscription",
|
||||||
"base_amount": "150.00",
|
"base_amount": "150.00",
|
||||||
"description": "Montant de base",
|
"description": "Montant de base",
|
||||||
"is_active": True,
|
"is_active": True,
|
||||||
"type": FeeType.REGISTRATION_FEE
|
"type": FeeType.REGISTRATION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Matériel",
|
"name": "Matériel",
|
||||||
"base_amount": "85.00",
|
"base_amount": "85.00",
|
||||||
"description": "Livres / jouets",
|
"description": "Livres / jouets",
|
||||||
"is_active": True,
|
"is_active": True,
|
||||||
"type": FeeType.REGISTRATION_FEE
|
"type": FeeType.REGISTRATION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Sorties périscolaires",
|
"name": "Sorties périscolaires",
|
||||||
"base_amount": "120.00",
|
"base_amount": "120.00",
|
||||||
"description": "Sorties",
|
"description": "Sorties",
|
||||||
"is_active": True,
|
"is_active": True,
|
||||||
"type": FeeType.REGISTRATION_FEE
|
"type": FeeType.REGISTRATION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Les colibris",
|
"name": "Les colibris",
|
||||||
"base_amount": "4500.00",
|
"base_amount": "4500.00",
|
||||||
"description": "TPS / PS / MS / GS",
|
"description": "TPS / PS / MS / GS",
|
||||||
"is_active": True,
|
"is_active": True,
|
||||||
"type": FeeType.TUITION_FEE
|
"type": FeeType.TUITION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Les butterflies",
|
"name": "Les butterflies",
|
||||||
"base_amount": "5000.00",
|
"base_amount": "5000.00",
|
||||||
"description": "CP / CE1 / CE2 / CM1 / CM2",
|
"description": "CP / CE1 / CE2 / CM1 / CM2",
|
||||||
"is_active": True,
|
"is_active": True,
|
||||||
"type": FeeType.TUITION_FEE
|
"type": FeeType.TUITION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -58,20 +64,23 @@ class Command(BaseCommand):
|
|||||||
self.stdout.write(self.style.SUCCESS('Fees initialized or updated successfully'))
|
self.stdout.write(self.style.SUCCESS('Fees initialized or updated successfully'))
|
||||||
|
|
||||||
def create_or_update_discounts(self):
|
def create_or_update_discounts(self):
|
||||||
|
establishment = Establishment.objects.get(name="N3WT")
|
||||||
discounts_data = [
|
discounts_data = [
|
||||||
{
|
{
|
||||||
"name": "Parrainage",
|
"name": "Parrainage",
|
||||||
"amount": "10.00",
|
"amount": "10.00",
|
||||||
"description": "Réduction pour parrainage",
|
"description": "Réduction pour parrainage",
|
||||||
"discount_type": DiscountType.PERCENT,
|
"discount_type": DiscountType.PERCENT,
|
||||||
"type": FeeType.TUITION_FEE
|
"type": FeeType.TUITION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Réinscription",
|
"name": "Réinscription",
|
||||||
"amount": "100.00",
|
"amount": "100.00",
|
||||||
"description": "Réduction pour Réinscription",
|
"description": "Réduction pour Réinscription",
|
||||||
"discount_type": DiscountType.PERCENT,
|
"discount_type": DiscountType.PERCENT,
|
||||||
"type": FeeType.REGISTRATION_FEE
|
"type": FeeType.REGISTRATION_FEE,
|
||||||
|
"establishment": establishment
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ from django.contrib.postgres.fields import ArrayField
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
LEVEL_CHOICES = [
|
LEVEL_CHOICES = [
|
||||||
(1, 'Très Petite Section (TPS)'),
|
(1, 'Très Petite Section (TPS)'),
|
||||||
(2, 'Petite Section (PS)'),
|
(2, 'Petite Section (PS)'),
|
||||||
@ -19,6 +18,23 @@ LEVEL_CHOICES = [
|
|||||||
(9, 'Cours Moyen 2 (CM2)')
|
(9, 'Cours Moyen 2 (CM2)')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class StructureType(models.IntegerChoices):
|
||||||
|
MATERNELLE = 1, _('Maternelle')
|
||||||
|
PRIMAIRE = 2, _('Primaire')
|
||||||
|
SECONDAIRE = 3, _('Secondaire')
|
||||||
|
|
||||||
|
class Establishment(models.Model):
|
||||||
|
name = models.CharField(max_length=255, unique=True)
|
||||||
|
address = models.CharField(max_length=255)
|
||||||
|
total_capacity = models.IntegerField()
|
||||||
|
establishment_type = ArrayField(models.IntegerField(choices=StructureType.choices))
|
||||||
|
licence_code = models.CharField(max_length=100, blank=True)
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
class Speciality(models.Model):
|
class Speciality(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
updated_date = models.DateTimeField(auto_now=True)
|
updated_date = models.DateTimeField(auto_now=True)
|
||||||
@ -56,6 +72,7 @@ class SchoolClass(models.Model):
|
|||||||
type = models.IntegerField(choices=PLANNING_TYPE_CHOICES, default=1)
|
type = models.IntegerField(choices=PLANNING_TYPE_CHOICES, default=1)
|
||||||
time_range = models.JSONField(default=list)
|
time_range = models.JSONField(default=list)
|
||||||
opening_days = ArrayField(models.IntegerField(), default=list)
|
opening_days = ArrayField(models.IntegerField(), default=list)
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='school_classes')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.atmosphere_name
|
return self.atmosphere_name
|
||||||
@ -95,6 +112,7 @@ class Discount(models.Model):
|
|||||||
discount_type = models.IntegerField(choices=DiscountType.choices, default=DiscountType.CURRENCY)
|
discount_type = models.IntegerField(choices=DiscountType.choices, default=DiscountType.CURRENCY)
|
||||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='discounts')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -106,6 +124,7 @@ class Fee(models.Model):
|
|||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='fees')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -115,6 +134,7 @@ class PaymentPlan(models.Model):
|
|||||||
due_dates = ArrayField(models.DateField(), blank=True)
|
due_dates = ArrayField(models.DateField(), blank=True)
|
||||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
is_active = models.BooleanField(default=False)
|
is_active = models.BooleanField(default=False)
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='payment_plans')
|
||||||
|
|
||||||
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()}"
|
||||||
@ -123,6 +143,7 @@ class PaymentMode(models.Model):
|
|||||||
mode = models.IntegerField(choices=PaymentModeType.choices, default=PaymentModeType.SEPA)
|
mode = models.IntegerField(choices=PaymentModeType.choices, default=PaymentModeType.SEPA)
|
||||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
is_active = models.BooleanField(default=False)
|
is_active = models.BooleanField(default=False)
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='payment_modes')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.get_mode_display()} - {self.get_type_display()}"
|
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, PaymentMode
|
from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, Fee, PaymentPlan, PaymentMode, Establishment
|
||||||
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
|
||||||
@ -201,3 +201,8 @@ class PaymentModeSerializer(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = PaymentMode
|
model = PaymentMode
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Establishment
|
||||||
|
fields = '__all__'
|
||||||
@ -16,7 +16,9 @@ from School.views import (
|
|||||||
PaymentPlansView,
|
PaymentPlansView,
|
||||||
PaymentPlanView,
|
PaymentPlanView,
|
||||||
PaymentModesView,
|
PaymentModesView,
|
||||||
PaymentModeView
|
PaymentModeView,
|
||||||
|
EstablishmentsView,
|
||||||
|
EstablishmentView
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@ -51,4 +53,9 @@ urlpatterns = [
|
|||||||
re_path(r'^paymentModes/(?P<_filter>[a-zA-z]+)$', PaymentModesView.as_view(), name="paymentModes"),
|
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$', PaymentModeView.as_view(), name="paymentMode"),
|
||||||
re_path(r'^paymentMode/([0-9]+)$', PaymentModeView.as_view(), name="paymentMode"),
|
re_path(r'^paymentMode/([0-9]+)$', PaymentModeView.as_view(), name="paymentMode"),
|
||||||
|
|
||||||
|
re_path(r'^establishments$', EstablishmentsView.as_view(), name="establishments"),
|
||||||
|
re_path(r'^establishment$', EstablishmentView.as_view(), name='establishment'),
|
||||||
|
re_path(r'^establishment/([0-9]+)$', EstablishmentView.as_view(), name='establishment')
|
||||||
|
|
||||||
]
|
]
|
||||||
@ -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, PaymentMode
|
from .models import Teacher, Speciality, SchoolClass, Planning, Discount, Fee, PaymentPlan, PaymentMode, Establishment
|
||||||
from .serializers import TeacherSerializer, SpecialitySerializer, SchoolClassSerializer, PlanningSerializer, DiscountSerializer, FeeSerializer, PaymentPlanSerializer, PaymentModeSerializer
|
from .serializers import TeacherSerializer, SpecialitySerializer, SchoolClassSerializer, PlanningSerializer, DiscountSerializer, FeeSerializer, PaymentPlanSerializer, PaymentModeSerializer, EstablishmentSerializer
|
||||||
from N3wtSchool import bdd
|
from N3wtSchool import bdd
|
||||||
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
||||||
|
|
||||||
@ -401,3 +401,45 @@ class PaymentModeView(APIView):
|
|||||||
payment_mode_serializer.save()
|
payment_mode_serializer.save()
|
||||||
return JsonResponse(payment_mode_serializer.data, safe=False)
|
return JsonResponse(payment_mode_serializer.data, safe=False)
|
||||||
return JsonResponse(payment_mode_serializer.errors, safe=False, status=400)
|
return JsonResponse(payment_mode_serializer.errors, safe=False, status=400)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class EstablishmentsView(APIView):
|
||||||
|
def get(self, request):
|
||||||
|
establishments=getAllObjects(Establishment)
|
||||||
|
establishments_serializer=EstablishmentSerializer(establishments, many=True)
|
||||||
|
return JsonResponse(establishments_serializer.data, safe=False, status=200)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class EstablishmentView(APIView):
|
||||||
|
def get(self, request, _id):
|
||||||
|
try:
|
||||||
|
establishment = Establishment.objects.get(id=_id)
|
||||||
|
establishment_serializer = EstablishmentSerializer(establishment)
|
||||||
|
return JsonResponse(establishment_serializer.data, safe=False)
|
||||||
|
except Establishment.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=404)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
establishment_data = JSONParser().parse(request)
|
||||||
|
establishment_serializer = EstablishmentSerializer(data=establishment_data)
|
||||||
|
if establishment_serializer.is_valid():
|
||||||
|
establishment_serializer.save()
|
||||||
|
return JsonResponse(establishment_serializer.data, safe=False, status=201)
|
||||||
|
return JsonResponse(establishment_serializer.errors, safe=False, status=400)
|
||||||
|
|
||||||
|
def put(self, request, _id):
|
||||||
|
establishment_data = JSONParser().parse(request)
|
||||||
|
try:
|
||||||
|
establishment = Establishment.objects.get(id=_id)
|
||||||
|
except Establishment.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=404)
|
||||||
|
establishment_serializer = EstablishmentSerializer(establishment, data=establishment_data, partial=True)
|
||||||
|
if establishment_serializer.is_valid():
|
||||||
|
establishment_serializer.save()
|
||||||
|
return JsonResponse(establishment_serializer.data, safe=False)
|
||||||
|
return JsonResponse(establishment_serializer.errors, safe=False, status=400)
|
||||||
|
|
||||||
|
def delete(self, request, _id):
|
||||||
|
return delete_object(Establishment, _id)
|
||||||
@ -4,7 +4,7 @@ from django.conf import settings
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from Auth.models import Profile
|
from Auth.models import Profile
|
||||||
from School.models import SchoolClass, Fee, Discount
|
from School.models import SchoolClass, Fee, Discount, Establishment
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
@ -209,6 +209,8 @@ class RegistrationForm(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
blank=True)
|
blank=True)
|
||||||
|
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='register_forms')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
||||||
|
|
||||||
|
|||||||
@ -20,14 +20,15 @@ commands = [
|
|||||||
["python", "manage.py", "makemigrations", "GestionMessagerie", "--noinput"],
|
["python", "manage.py", "makemigrations", "GestionMessagerie", "--noinput"],
|
||||||
["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_modes"]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
test_commands = [
|
test_commands = [
|
||||||
|
["python", "manage.py", "init_establishment"],
|
||||||
["python", "manage.py", "init_school_configuration"],
|
["python", "manage.py", "init_school_configuration"],
|
||||||
["python", "manage.py", "init_school_fees"]
|
["python", "manage.py", "init_school_fees"],
|
||||||
|
["python", "manage.py", "init_payment_plans"],
|
||||||
|
["python", "manage.py", "init_payment_modes"]
|
||||||
]
|
]
|
||||||
|
|
||||||
for command in commands:
|
for command in commands:
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
// src/components/Layout.js
|
// src/components/Layout.js
|
||||||
import React from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import Sidebar from '@/components/Sidebar';
|
import Sidebar from '@/components/Sidebar';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import {useTranslations} from 'next-intl';
|
import {useTranslations} from 'next-intl';
|
||||||
@ -25,6 +25,7 @@ import {
|
|||||||
} from '@/utils/Url';
|
} from '@/utils/Url';
|
||||||
|
|
||||||
import { disconnect } from '@/app/lib/authAction';
|
import { disconnect } from '@/app/lib/authAction';
|
||||||
|
import { fetchEstablishment } from '@/app/lib/schoolAction';
|
||||||
|
|
||||||
export default function Layout({
|
export default function Layout({
|
||||||
children,
|
children,
|
||||||
@ -40,6 +41,9 @@ export default function Layout({
|
|||||||
"settings": { "id": "settings", "name": t('settings'), "url": FE_ADMIN_SETTINGS_URL, "icon": Settings }
|
"settings": { "id": "settings", "name": t('settings'), "url": FE_ADMIN_SETTINGS_URL, "icon": Settings }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [establishment, setEstablishment] = useState(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const currentPage = pathname.split('/').pop();
|
const currentPage = pathname.split('/').pop();
|
||||||
|
|
||||||
@ -57,10 +61,21 @@ export default function Layout({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
fetchEstablishment()
|
||||||
|
.then(data => {
|
||||||
|
setEstablishment(data);
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching establishment : ', error))
|
||||||
|
.finally(() => setIsLoading(false));
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{!isLoading && (
|
||||||
<div className="flex min-h-screen bg-gray-50">
|
<div className="flex min-h-screen bg-gray-50">
|
||||||
<Sidebar currentPage={currentPage} items={Object.values(sidebarItems)} className="h-full" />
|
<Sidebar establishment={establishment} currentPage={currentPage} items={Object.values(sidebarItems)} className="h-full" />
|
||||||
<div className="flex flex-col flex-1">
|
<div className="flex flex-col flex-1">
|
||||||
{/* Header - h-16 = 64px */}
|
{/* Header - h-16 = 64px */}
|
||||||
<header className="h-16 bg-white border-b border-gray-200 px-8 py-4 flex items-center justify-between z-9">
|
<header className="h-16 bg-white border-b border-gray-200 px-8 py-4 flex items-center justify-between z-9">
|
||||||
@ -89,6 +104,7 @@ export default function Layout({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,9 @@ 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
|
BE_SCHOOL_PAYMENT_MODES_URL,
|
||||||
|
BE_SCHOOL_ESTABLISHMENT_URL,
|
||||||
|
ESTABLISHMENT_ID
|
||||||
} from '@/utils/Url';
|
} from '@/utils/Url';
|
||||||
|
|
||||||
const requestResponseHandler = async (response) => {
|
const requestResponseHandler = async (response) => {
|
||||||
@ -82,6 +84,11 @@ export const fetchTuitionPaymentModes = () => {
|
|||||||
.then(requestResponseHandler)
|
.then(requestResponseHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const fetchEstablishment = () => {
|
||||||
|
return fetch(`${BE_SCHOOL_ESTABLISHMENT_URL}/${ESTABLISHMENT_ID}`)
|
||||||
|
.then(requestResponseHandler)
|
||||||
|
}
|
||||||
|
|
||||||
export const createDatas = (url, newData, csrfToken) => {
|
export const createDatas = (url, newData, csrfToken) => {
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@ -14,7 +14,7 @@ const SidebarItem = ({ icon: Icon, text, active, url, onClick }) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
function Sidebar({ currentPage, items }) {
|
function Sidebar({ establishment, currentPage, items }) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [selectedItem, setSelectedItem] = useState(currentPage);
|
const [selectedItem, setSelectedItem] = useState(currentPage);
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ function Sidebar({ currentPage, items }) {
|
|||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
<div className="w-64 bg-white border-r border-gray-200 py-6 px-4">
|
<div className="w-64 bg-white border-r border-gray-200 py-6 px-4">
|
||||||
<div className="flex items-center mb-8 px-2">
|
<div className="flex items-center mb-8 px-2">
|
||||||
<div className="text-xl font-semibold">Ecole NEWT</div>
|
<div className="text-xl font-semibold">{establishment?.name}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav className="space-y-1">
|
<nav className="space-y-1">
|
||||||
|
|||||||
@ -41,6 +41,10 @@ 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_MODE_URL = `${BASE_URL}/School/paymentMode`;
|
||||||
export const BE_SCHOOL_PAYMENT_MODES_URL = `${BASE_URL}/School/paymentModes`;
|
export const BE_SCHOOL_PAYMENT_MODES_URL = `${BASE_URL}/School/paymentModes`;
|
||||||
|
export const BE_SCHOOL_ESTABLISHMENT_URL = `${BASE_URL}/School/establishment`;
|
||||||
|
|
||||||
|
// En attendant la gestion des sessions
|
||||||
|
export const ESTABLISHMENT_ID = 1;
|
||||||
|
|
||||||
// GESTION MESSAGERIE
|
// GESTION MESSAGERIE
|
||||||
export const BE_GESTIONMESSAGERIE_MESSAGES_URL = `${BASE_URL}/GestionMessagerie/messages`
|
export const BE_GESTIONMESSAGERIE_MESSAGES_URL = `${BASE_URL}/GestionMessagerie/messages`
|
||||||
|
|||||||
62
README.md
62
README.md
@ -1,62 +0,0 @@
|
|||||||
# N3wt School
|
|
||||||
|
|
||||||
Logiciel de gestion d'école
|
|
||||||
|
|
||||||
|
|
||||||
## Maquette
|
|
||||||
|
|
||||||
Maquette figma : https://www.figma.com/design/1BtWHIQlJDTeue2oYblefV/Maquette-Logiciel-de-gestion-Ecole?node-id=42-296&t=AdaSQYWkLLf1o5OI-0
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Installation de docker
|
|
||||||
Lien de téléchargement : https://www.docker.com/get-started/
|
|
||||||
|
|
||||||
# Lancement de monteschool
|
|
||||||
|
|
||||||
```sh
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
Lancement du front end
|
|
||||||
```sh
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
se connecter à localhost:8080
|
|
||||||
|
|
||||||
# Installation et développement en local
|
|
||||||
|
|
||||||
* [Installation Manuelle](./docs/Installation_Manuelle.md)
|
|
||||||
* [Convention de codage](./docs/CODING_GUIDELINES.md)
|
|
||||||
|
|
||||||
# Installer la vérification de commit (dans le projet principal)
|
|
||||||
|
|
||||||
```
|
|
||||||
npm i
|
|
||||||
npm run prepare
|
|
||||||
```
|
|
||||||
|
|
||||||
# Faire une livraison Mise en Production
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Faire la première release (1.0.0)
|
|
||||||
npm run release -- --first-release
|
|
||||||
|
|
||||||
# Faire une prerelease (RC,alpha,beta)
|
|
||||||
npm run release -- --prerelease <name>
|
|
||||||
|
|
||||||
|
|
||||||
# Faire une release
|
|
||||||
npm run release
|
|
||||||
|
|
||||||
# Forcer la release sur un mode particulier (majeur, mineur ou patch)
|
|
||||||
# npm run script
|
|
||||||
npm run release -- --release-as minor
|
|
||||||
# Or
|
|
||||||
npm run release -- --release-as 1.1.0
|
|
||||||
|
|
||||||
# ignorer les hooks de commit lors de la release
|
|
||||||
npm run release -- --no-verify
|
|
||||||
```
|
|
||||||
|
|
||||||
20
package.json
20
package.json
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "n3wt-school",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"scripts": {
|
|
||||||
"prepare": "husky",
|
|
||||||
"release": "standard-version",
|
|
||||||
"update-version": "node scripts/update-version.js"
|
|
||||||
},
|
|
||||||
"standard-version": {
|
|
||||||
"scripts": {
|
|
||||||
"postbump": "git add Front-End/package.json Back-End/__version__.py && git commit --amend --no-edit"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@commitlint/cli": "^19.5.0",
|
|
||||||
"@commitlint/config-conventional": "^19.5.0",
|
|
||||||
"husky": "^9.1.6",
|
|
||||||
"standard-version": "^9.5.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user