Compare commits
3 Commits
aa8e4e761f
...
d79f30e96c
| Author | SHA1 | Date | |
|---|---|---|---|
| d79f30e96c | |||
| da8c8db0d2 | |||
| 99d24583d6 |
@@ -31,6 +31,7 @@ def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> Non
|
||||
img.add_header("Content-Disposition", "inline", filename="cantorair.png")
|
||||
|
||||
# build mail list filling template
|
||||
queryset = queryset.filter(mail_sent=False)
|
||||
mails: List[EmailMultiAlternatives] = []
|
||||
for student in queryset:
|
||||
if not student.user or not student.email: # skip student if has not an associated user
|
||||
@@ -56,18 +57,25 @@ def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> Non
|
||||
mail.attach(filename=img)
|
||||
mail.attach_alternative(content=html_message, mimetype="text/html")
|
||||
mails.append(mail)
|
||||
student.mail_sent = True
|
||||
student.save()
|
||||
except Exception as e:
|
||||
messages.error(request=request, message=f"General Error: {e}")
|
||||
|
||||
if len(mails) == 0:
|
||||
messages.warning(request=request, message="No email will be sent")
|
||||
return
|
||||
|
||||
# Open only one conenction and send mass email
|
||||
try:
|
||||
sent: int = 0
|
||||
with get_connection() as conn:
|
||||
conn.send_messages(mails)
|
||||
sent = conn.send_messages(mails)
|
||||
except SMTPException as e:
|
||||
messages.error(request=request, message=f"Send Mail SMTP error: {e.strerror}")
|
||||
except Exception as e:
|
||||
messages.error(request=request, message=f"Send Mail General error: {e}")
|
||||
else:
|
||||
messages.success(request=request, message=f"Successfully sent {len(mails)} messages")
|
||||
messages.success(request=request, message=f"Successfully sent {sent} messages")
|
||||
|
||||
return
|
||||
|
||||
@@ -69,7 +69,7 @@ class ChangeAircraftForm(AdminActionForm):
|
||||
|
||||
class StudentAdmin(ImportMixin, AdminConfirmMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
||||
model = Student
|
||||
list_display = ("surname", "name", "course", "course_color", "email", "phone", "username", "password", "active", )
|
||||
list_display = ("surname", "name", "course", "course_color", "email", "phone", "username", "password", "active", "mail_sent")
|
||||
list_filter = ("course", "active", )
|
||||
search_fields = ("surname", "name", "phone", "email", )
|
||||
actions = ("change_course", "deactivate_students", "change_aircraft", "send_mail", )
|
||||
|
||||
@@ -23,7 +23,7 @@ from datetime import date
|
||||
from typing import Dict, List, Any
|
||||
|
||||
class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
||||
list_display = ("week", "student__surname", "student__name", "student__course", "course_color", "student_brief_mix", )
|
||||
list_display = ("week", "student__surname", "student__name", "student__course", "course_color", "student_brief_mix", "inserted")
|
||||
list_filter = ("week", "student__course", )
|
||||
search_fields = ("student__surname","student__name", )
|
||||
actions = ("export", )
|
||||
@@ -68,9 +68,9 @@ class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
||||
return (TrainingInLIne(self.model, self.admin_site), )
|
||||
else:
|
||||
return (
|
||||
TrainingInLIne(self.model, self.admin_site),
|
||||
HourBuildingInLine(self.model, self.admin_site),
|
||||
)
|
||||
TrainingInLIne(self.model, self.admin_site),
|
||||
HourBuildingInLine(self.model, self.admin_site),
|
||||
)
|
||||
|
||||
# If a user is registered as student do not show actions
|
||||
def get_actions(self, request: HttpRequest) -> Dict[str, Any]:
|
||||
@@ -89,13 +89,16 @@ class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
||||
|
||||
def get_form(self, request: HttpRequest, obj: WeekPreference | None = None, **kwargs: Dict[str, Any]) -> Form:
|
||||
form: Form = super().get_form(request, obj, **kwargs)
|
||||
current_week = date.today().isocalendar().week
|
||||
|
||||
today: date = date.today()
|
||||
current_week = today.isocalendar().week
|
||||
# If form contains the week field
|
||||
if "week" in form.base_fields:
|
||||
# Set default value as current week
|
||||
form.base_fields["week"].initial = current_week
|
||||
|
||||
if "inserted" in form.base_fields:
|
||||
form.base_fields["inserted"].initial = today
|
||||
|
||||
# If student is current user making request
|
||||
if hasattr(request.user, "student"):
|
||||
student: Student = request.user.student
|
||||
@@ -103,6 +106,7 @@ class WeekPreferenceAdmin(nested_admin.NestedPolymorphicModelAdmin):
|
||||
form.base_fields["student"].initial = student
|
||||
form.base_fields["student"].disabled = True
|
||||
form.base_fields["week"].disabled = True # student cannot change week
|
||||
form.base_fields["inserted"].disabled = True # student cannot change insertion date
|
||||
return form
|
||||
|
||||
# If user is a student deny edit permission for week past the current one
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.2.8 on 2025-12-10 10:18
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('flightslot', '0029_alter_course_ctype'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='weekpreference',
|
||||
name='inserted',
|
||||
field=models.DateField(default=datetime.date(2025, 12, 10)),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='availability',
|
||||
name='week',
|
||||
field=models.PositiveSmallIntegerField(auto_created=True, db_default=50, db_index=True, verbose_name='Week Number'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='weekpreference',
|
||||
name='week',
|
||||
field=models.PositiveSmallIntegerField(auto_created=True, db_default=50, db_index=True, verbose_name='Week Number'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.2.8 on 2025-12-10 10:28
|
||||
|
||||
import phonenumber_field.modelfields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('flightslot', '0030_weekpreference_inserted_alter_availability_week_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='student',
|
||||
name='mail_sent',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='student',
|
||||
name='phone',
|
||||
field=phonenumber_field.modelfields.PhoneNumberField(db_index=True, max_length=128, null=True, region=None, unique=True),
|
||||
),
|
||||
]
|
||||
@@ -19,6 +19,7 @@ class Student(models.Model):
|
||||
|
||||
phone = modelfields.PhoneNumberField(
|
||||
null=True,
|
||||
db_index=True,
|
||||
unique=True
|
||||
)
|
||||
|
||||
@@ -54,6 +55,11 @@ class Student(models.Model):
|
||||
Aircraft
|
||||
)
|
||||
|
||||
mail_sent = models.BooleanField(
|
||||
null=False,
|
||||
default=False
|
||||
)
|
||||
|
||||
def default_password(self) -> str: # Maximum 4 digits for passowrd
|
||||
if self.pk:
|
||||
return f"{self.name.lower()[0]}{self.surname.lower()}{self.id % 10000}"
|
||||
|
||||
@@ -24,5 +24,10 @@ class WeekPreference(models.Model):
|
||||
verbose_name="Student Selection"
|
||||
)
|
||||
|
||||
inserted = models.DateField(
|
||||
null=False,
|
||||
default=date.today()
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"Week {self.week} - {self.student.surname} {self.student.name[0]}."
|
||||
|
||||
Reference in New Issue
Block a user