Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions home/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
StudentBills,
UnregisteredStudent,
Update,
GlobalConstants,
)
from home.utils.rebate_checker import max_days_rebate

Expand Down Expand Up @@ -79,7 +80,18 @@
)
REBATE_BILLS_DESC_TEXT = "This contains the rebate bills of each students."

# Register your models here
@admin.register(GlobalConstants)
class GlobalConstantsAdmin(admin.ModelAdmin):
model = GlobalConstants

def has_add_permission(self, request):
# Only allow one instance of GlobalConstants
if self.model.objects.count() > 0:
return False
return super().has_add_permission(request)

def has_delete_permission(self, request, obj=None):
return False


@admin.register(About)
Expand Down Expand Up @@ -451,11 +463,19 @@ def set_semester(modeladmin, request, queryset: list[LongRebate]):
set_semester.__name__ = f"get_rebate_days_per_caterer_{semester}"
return set_semester

try:
for semester in Semester.objects.all():
actions.append(set_semester_action(semester.name))
except Exception as e:
print("Semester table not available", e)
def get_actions(self, request):
actions = super().get_actions(request)
try:
for semester in Semester.objects.all():
action = self.set_semester_action(semester.name)
actions[action.__name__] = (
action,
action.__name__,
action.short_description,
)
except Exception as e:
print("Semester table not available", e)
return actions


@admin.register(Rebate)
Expand Down Expand Up @@ -679,11 +699,19 @@ def set_period(modeladmin, request, queryset):
set_period.__name__ = f"set_period_{semester_name}_{period_sno}"
return set_period

try:
for period in Period.objects.all():
actions.append(set_period_action(period.semester.name, period.Sno))
except Exception as e:
print("Periods table not available", e)
def get_actions(self, request):
actions = super().get_actions(request)
try:
for period in Period.objects.all():
action = self.set_period_action(period.semester.name, period.Sno)
actions[action.__name__] = (
action,
action.__name__,
action.short_description,
)
except Exception as e:
print("Periods table not available", e)
return actions

@admin.action(description="Allocate the unregistered students")
def allocate(self, request, queryset):
Expand Down
8 changes: 6 additions & 2 deletions home/context_processors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .models import Caterer
from .models import Caterer, GlobalConstants

"""
File-name: context_processors.py
Expand All @@ -9,4 +9,8 @@

def base(request):
caterer = Caterer.objects.filter(visible=True).all()
return {"all_caterer": caterer}
constants = GlobalConstants.objects.first()
if not constants:
# Provide defaults if no constants exist yet
constants = GlobalConstants.objects.create()
return {"all_caterer": caterer, "constants": constants}
27 changes: 27 additions & 0 deletions home/migrations/0010_globalconstants.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 5.1.14 on 2026-06-05 17:41

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('home', '0009_student_photo'),
]

operations = [
migrations.CreateModel(
name='GlobalConstants',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('short_rebate_stretch_limit', models.IntegerField(default=7, help_text='Maximum number of days for a single short rebate application.', verbose_name='Short Rebate Stretch Limit')),
('short_rebate_period_limit', models.IntegerField(default=8, help_text='Maximum total days allowed for short rebates within a single period.', verbose_name='Short Rebate Period Limit')),
('min_rebate_days', models.IntegerField(default=2, help_text='Minimum number of days required for a rebate application.', verbose_name='Minimum Rebate Days')),
('days_prior_notice', models.IntegerField(default=2, help_text='Minimum days before leave commencement the form must be filled.', verbose_name='Days Prior Notice')),
],
options={
'verbose_name': 'Global Constant',
'verbose_name_plural': 'Global Constants',
},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.1.14 on 2026-06-05 17:42

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('home', '0010_globalconstants'),
]

operations = [
migrations.AlterField(
model_name='globalconstants',
name='short_rebate_period_limit',
field=models.IntegerField(default=10, help_text='Maximum total days allowed for short rebates within a single period.', verbose_name='Short Rebate Period Limit'),
),
migrations.AlterField(
model_name='globalconstants',
name='short_rebate_stretch_limit',
field=models.IntegerField(default=10, help_text='Maximum number of days for a single short rebate application.', verbose_name='Short Rebate Stretch Limit'),
),
]
2 changes: 1 addition & 1 deletion home/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .caterer import Caterer
from .contacts import Contact
from .fees import Fee
from .home import About, Carousel, Update
from .home import About, Carousel, GlobalConstants, Update
from .links import Form
from .rules import Rule, ShortRebate
from .students import (
Expand Down
34 changes: 34 additions & 0 deletions home/models/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,37 @@ def __str__(self):
class Meta:
verbose_name = "Update"
verbose_name_plural = "Updates"


class GlobalConstants(models.Model):
"""
Stores globally accessible constants for the website like rebate limits.
"""

short_rebate_stretch_limit = models.IntegerField(
_("Short Rebate Stretch Limit"),
default=10,
help_text="Maximum number of days for a single short rebate application.",
)
short_rebate_period_limit = models.IntegerField(
_("Short Rebate Period Limit"),
default=10,
help_text="Maximum total days allowed for short rebates within a single period.",
)
min_rebate_days = models.IntegerField(
_("Minimum Rebate Days"),
default=2,
help_text="Minimum number of days required for a rebate application.",
)
days_prior_notice = models.IntegerField(
_("Days Prior Notice"),
default=2,
help_text="Minimum days before leave commencement the form must be filled.",
)

def __str__(self):
return "Global Constants"

class Meta:
verbose_name = "Global Constant"
verbose_name_plural = "Global Constants"
40 changes: 26 additions & 14 deletions home/utils/rebate_checker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from datetime import timedelta

from home.models import LeftShortRebate, LongRebate, Rebate, StudentBills
from home.models import (
GlobalConstants,
LeftShortRebate,
LongRebate,
Rebate,
StudentBills,
)


def count(start, end):
Expand Down Expand Up @@ -54,41 +60,47 @@ def is_not_duplicate(student, new_rebate_start, new_rebate_end):
def max_days_rebate(student, start, end, period):
"""
Checks what period rebate is being applied,
if the rebate does not exceeds 8 days for that period approves the rebate and
if the rebate does not exceeds the set limit for that period approves the rebate and
adds the rebate to student bills(Commented out this feature for now, as administration wants to approve it from its side before adding to student bills)
"""
constants = GlobalConstants.objects.first()
if not constants:
constants = GlobalConstants.objects.create()

limit = constants.short_rebate_period_limit

student_bill, _ = StudentBills.objects.get_or_create(
email=student, semester=period.semester
)
sum = count(start, end)
match period.Sno:
case 1:
if student_bill.period1_short + sum <= 8:
if student_bill.period1_short + sum <= limit:
return -1
else:
return 8 - student_bill.period1_short
return limit - student_bill.period1_short
case 2:
if student_bill.period2_short + sum <= 8:
if student_bill.period2_short + sum <= limit:
return -1
else:
return 8 - student_bill.period2_short
return limit - student_bill.period2_short
case 3:
if student_bill.period3_short + sum <= 8:
if student_bill.period3_short + sum <= limit:
return -1
else:
return 8 - student_bill.period3_short
return limit - student_bill.period3_short
case 4:
if student_bill.period4_short + sum <= 8:
if student_bill.period4_short + sum <= limit:
return -1
else:
return 8 - student_bill.period4_short
return limit - student_bill.period4_short
case 5:
if student_bill.period5_short + sum <= 8:
if student_bill.period5_short + sum <= limit:
return -1
else:
return 8 - student_bill.period5_short
return limit - student_bill.period5_short
case 6:
if student_bill.period6_short + sum <= 8:
if student_bill.period6_short + sum <= limit:
return -1
else:
return 8 - student_bill.period6_short
return limit - student_bill.period6_short
19 changes: 12 additions & 7 deletions home/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
Caterer,
Contact,
Form,
GlobalConstants,
LeftShortRebate,
LongRebate,
Menu,
Expand Down Expand Up @@ -187,20 +188,24 @@ def rebate(request):
request.session["text"] = message
return redirect(request.path)

constants = GlobalConstants.objects.first()
if not constants:
constants = GlobalConstants.objects.create()

try:
start_date = parse_date(request.POST["start_date"])
end_date = parse_date(request.POST["end_date"])
rebate_days = ((end_date - start_date).days) + 1
before_rebate_days = (start_date - date.today()).days

if rebate_days > 7:
message = "Max no of days for rebate is 7"
elif before_rebate_days < 2:
message = "Form needs to be filled atleast 2 days prior the comencement of leave."
if rebate_days > constants.short_rebate_stretch_limit:
message = f"Max no of days for rebate is {constants.short_rebate_stretch_limit}"
elif before_rebate_days < constants.days_prior_notice:
message = f"Form needs to be filled atleast {constants.days_prior_notice} days prior the comencement of leave."
elif not is_not_duplicate(student, start_date, end_date):
message = "You have already applied for rebate during this duration"
elif rebate_days < 2:
message = "Min no of days for rebate is 2"
elif rebate_days < constants.min_rebate_days:
message = f"Min no of days for rebate is {constants.min_rebate_days}"
else:
additional_message = ""
if not period_obj.start_date <= start_date <= period_obj.end_date:
Expand Down Expand Up @@ -233,7 +238,7 @@ def rebate(request):
)
if upper_cap_check >= 0:
message = (
"You can only apply for max 8 days in a period. Days left for this period: "
f"You can only apply for max {constants.short_rebate_period_limit} days in a period. Days left for this period: "
+ str(upper_cap_check)
)
elif not message:
Expand Down
1 change: 1 addition & 0 deletions messWebsite/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"allauth.account.middleware.AccountMiddleware",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you sure?

"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"messWebsite.middleware.LoginRequiredMiddleware",
Expand Down
6 changes: 3 additions & 3 deletions templates/rebateForm.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ <h1 class="m-0 pb-2">Short Term Rebate Form</h1>
<div class="px-3">
<div class="px-5 mx-5">
<ul>
<li>Rebate can be availed for a minimum of 2 days, upto 7 days at a stretch.</li>
<li>Maximum of 8 days rebate per month will be provided through the short term rebate forms. </li>
<li>Fill the form atleast 2 days prior the comencement of leave, else the application will not be accepted.</li>
<li>Rebate can be availed for a minimum of {{ constants.min_rebate_days }} days, upto {{ constants.short_rebate_stretch_limit }} days at a stretch.</li>
<li>Maximum of {{ constants.short_rebate_period_limit }} days rebate per period will be provided through the short term rebate forms. </li>
<li>Fill the form atleast {{ constants.days_prior_notice }} days prior the comencement of leave, else the application will not be accepted.</li>
<ul>
</div>
</div>
Expand Down
Loading