Compare commits
2 Commits
231a3e9861
...
34eabe6af7
| Author | SHA1 | Date | |
|---|---|---|---|
| 34eabe6af7 | |||
| 71809d331f |
@@ -2,7 +2,7 @@ from django.http import HttpRequest, HttpResponse
|
|||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
from openpyxl import Workbook
|
from openpyxl import Workbook
|
||||||
from openpyxl.styles import Font, PatternFill, Alignment
|
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||||
from openpyxl.utils import get_column_letter
|
from openpyxl.utils import get_column_letter
|
||||||
|
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
@@ -34,22 +34,33 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
if not ws:
|
if not ws:
|
||||||
raise Exception("Export: cannot select active workbook")
|
raise Exception("Export: cannot select active workbook")
|
||||||
ws.title = f"Week Preferences"
|
ws.title = f"Week Preferences"
|
||||||
|
ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE
|
||||||
|
ws.page_setup.paperSize = ws.PAPERSIZE_A3
|
||||||
|
ws.page_setup.fitToHeight = 0
|
||||||
|
ws.page_setup.fitToWidth = 1
|
||||||
|
|
||||||
# Header titles
|
# Header titles
|
||||||
days = [f"{datetime.strptime(f"{year} {week} {x}", "%G %V %u").strftime("%A")} {datetime.strptime(f"{year} {week} {x}", "%G %V %u").day}" for x in range(1,8)]
|
days = [f"{datetime.strptime(f"{year} {week} {x}", "%G %V %u").strftime("%A")} {datetime.strptime(f"{year} {week} {x}", "%G %V %u").day}" for x in range(1,8)]
|
||||||
headers = ["Week", "Student", "Course", *days, "Cell.", "Mail", "Notes"]
|
headers = ["Week", "Student", "Course", *days, "Cell.", "Mail", "Notes"]
|
||||||
|
|
||||||
# Header fields positions
|
# Header fields positions
|
||||||
|
week_index: int = headers.index("Week") + 1
|
||||||
student_index: int = headers.index("Student") + 1
|
student_index: int = headers.index("Student") + 1
|
||||||
course_index: int = headers.index("Course") + 1
|
course_index: int = headers.index("Course") + 1
|
||||||
cell_index: int = headers.index("Cell.") + 1
|
cell_index: int = headers.index("Cell.") + 1
|
||||||
mail_index: int = headers.index("Mail") + 1
|
mail_index: int = headers.index("Mail") + 1
|
||||||
|
note_index: int = headers.index("Notes") + 1
|
||||||
|
|
||||||
# Stile header
|
# Stile header
|
||||||
header_fill = PatternFill("solid", fgColor="0e005c")
|
header_fill = PatternFill("solid", fgColor="0e005c")
|
||||||
bold_white = Font(color="FFFFFF", bold=True)
|
bold_white = Font(color="FFFFFF", bold=True)
|
||||||
bold_black = Font(color="000000", bold=True)
|
bold_black = Font(color="000000", bold=True)
|
||||||
center = Alignment(horizontal="center", vertical="center")
|
center = Alignment(horizontal="center", vertical="center", wrapText=True)
|
||||||
|
|
||||||
|
# Cell styles
|
||||||
|
border_thick: Side = Side(style='thick', color='000000')
|
||||||
|
border_bottom: Border = Border(bottom=border_thick)
|
||||||
|
border_all: Border = Border(bottom=border_thick, top=border_thick, left=border_thick, right=None)
|
||||||
|
|
||||||
# Scrittura header
|
# Scrittura header
|
||||||
for col, h in enumerate(headers, start=1):
|
for col, h in enumerate(headers, start=1):
|
||||||
@@ -58,7 +69,9 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
cell.font = bold_white
|
cell.font = bold_white
|
||||||
cell.alignment = center
|
cell.alignment = center
|
||||||
|
|
||||||
|
### Start of Student Loop ###
|
||||||
# Fill worksheet with EVERY training and hb for every student
|
# Fill worksheet with EVERY training and hb for every student
|
||||||
|
# Each of this iterations fills the table for a student
|
||||||
row: int = 2
|
row: int = 2
|
||||||
row_offset: int = 0
|
row_offset: int = 0
|
||||||
for i, q in enumerate(queryset.order_by("student__surname", "student__name", "student__course"), start=1):
|
for i, q in enumerate(queryset.order_by("student__surname", "student__name", "student__course"), start=1):
|
||||||
@@ -111,7 +124,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
hb_legs = HourBuildingLeg.objects.filter(hb_id = h.id)
|
hb_legs = HourBuildingLeg.objects.filter(hb_id = h.id)
|
||||||
for hh in hb_legs:
|
for hh in hb_legs:
|
||||||
hb_notes += f"{hh.departure} -> {hh.destination} [{hh.time}]\n" if not hh.stop else f"STOP at {hh.departure} [{hh.time}]\n"
|
hb_notes += f"{hh.departure} -> {hh.destination} [{hh.time}]\n" if not hh.stop else f"STOP at {hh.departure} [{hh.time}]\n"
|
||||||
hb_notes.strip('\r')
|
hb_notes.strip('\n')
|
||||||
hb_data.append([str(q.week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes])
|
hb_data.append([str(q.week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes])
|
||||||
|
|
||||||
# Build rows for table
|
# Build rows for table
|
||||||
@@ -126,6 +139,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
cell.font = bold_black
|
cell.font = bold_black
|
||||||
# Format Course Column
|
# Format Course Column
|
||||||
if j == course_index and q.student.course:
|
if j == course_index and q.student.course:
|
||||||
|
cell.font = bold_black
|
||||||
cell.fill = PatternFill("solid", fgColor=str(q.student.course.color).lstrip('#').lower())
|
cell.fill = PatternFill("solid", fgColor=str(q.student.course.color).lstrip('#').lower())
|
||||||
|
|
||||||
prev_cell_val: str = r[0]
|
prev_cell_val: str = r[0]
|
||||||
@@ -149,7 +163,12 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
|
|
||||||
# End week preferences for this student
|
# End week preferences for this student
|
||||||
student_end: int = row + row_offset -1
|
student_end: int = row + row_offset -1
|
||||||
# Merge Name
|
|
||||||
|
# Merge Week, thick border
|
||||||
|
# ws.cell(row=student_start, column=week_index).border = border_all
|
||||||
|
# ws.merge_cells(start_row=student_start, end_row=student_end, start_column=week_index, end_column=week_index)
|
||||||
|
# Merge Name, thick border
|
||||||
|
ws.cell(row=student_start, column=student_index).border = border_all
|
||||||
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=student_index, end_column=student_index)
|
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=student_index, end_column=student_index)
|
||||||
# Merge Course
|
# Merge Course
|
||||||
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=course_index, end_column=course_index)
|
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=course_index, end_column=course_index)
|
||||||
@@ -158,15 +177,22 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
# Merge Mail
|
# Merge Mail
|
||||||
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=mail_index, end_column=mail_index)
|
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=mail_index, end_column=mail_index)
|
||||||
|
|
||||||
|
# Add thick border to the last cell row of this student
|
||||||
|
for i in range(course_index, len(all_data[0])+1):
|
||||||
|
ws.cell(row=student_end, column=i).border = border_bottom
|
||||||
|
|
||||||
# Keep the largest column
|
# Keep the largest column
|
||||||
for column_cells in ws.columns:
|
for column_cells in ws.columns:
|
||||||
length: int = max(len(str(cell.value)) for cell in column_cells)
|
length: int = max(len(str(cell.value)) for cell in column_cells)
|
||||||
col_letter: str = "A"
|
col_letter: str = "A"
|
||||||
if column_cells[0].column:
|
if column_cells[0].column:
|
||||||
get_column_letter(column_cells[0].column)
|
col_letter = get_column_letter(column_cells[0].column)
|
||||||
ws.column_dimensions[col_letter].width = length
|
ws.column_dimensions[col_letter].width = length + 2
|
||||||
|
|
||||||
# Save document in HttpResponse
|
### End of Student Loop ###
|
||||||
wb.save(response)
|
|
||||||
|
|
||||||
|
# Save document in HttpResponse
|
||||||
|
wb.save(response)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
@@ -42,6 +42,17 @@ class HourBuildingLegInline(nested_admin.NestedTabularInline):
|
|||||||
fk_name = 'hb'
|
fk_name = 'hb'
|
||||||
max_num = 5
|
max_num = 5
|
||||||
|
|
||||||
|
# If user is a student deny edit permission for week past the current one
|
||||||
|
def has_change_permission(self, request: HttpRequest, obj: HourBuilding | None = None):
|
||||||
|
if hasattr(request.user, 'student') and obj:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
if not obj.DoesNotExist and current_week > obj.weekpref.week:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_delete_permission(self, request: HttpRequest, obj: HourBuilding | None = None):
|
||||||
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|
||||||
class HourBuildingInLine(nested_admin.NestedTabularInline):
|
class HourBuildingInLine(nested_admin.NestedTabularInline):
|
||||||
model = HourBuilding
|
model = HourBuilding
|
||||||
extra = 0
|
extra = 0
|
||||||
@@ -50,6 +61,17 @@ class HourBuildingInLine(nested_admin.NestedTabularInline):
|
|||||||
verbose_name_plural = "Hour Building"
|
verbose_name_plural = "Hour Building"
|
||||||
max_num = 7
|
max_num = 7
|
||||||
|
|
||||||
|
# If user is a student deny edit permission for week past the current one
|
||||||
|
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
||||||
|
if hasattr(request.user, 'student') and obj:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
if current_week > obj.week:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
||||||
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|
||||||
class TrainingInLIne(nested_admin.NestedTabularInline):
|
class TrainingInLIne(nested_admin.NestedTabularInline):
|
||||||
model = Training
|
model = Training
|
||||||
form = TrainingForm
|
form = TrainingForm
|
||||||
@@ -58,9 +80,20 @@ class TrainingInLIne(nested_admin.NestedTabularInline):
|
|||||||
verbose_name_plural = "Training Missions"
|
verbose_name_plural = "Training Missions"
|
||||||
max_num = 7
|
max_num = 7
|
||||||
|
|
||||||
|
# If user is a student deny edit permission for week past the current one
|
||||||
|
def has_change_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
||||||
|
if hasattr(request.user, 'student') and obj:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
if current_week > obj.week:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_delete_permission(self, request: HttpRequest, obj: WeekPreference | None = None):
|
||||||
|
return self.has_change_permission(request=request, obj=obj)
|
||||||
|
|
||||||
class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
|
class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
|
||||||
inlines = (TrainingInLIne, HourBuildingInLine,)
|
inlines = (TrainingInLIne, HourBuildingInLine,)
|
||||||
list_display = ("week", "student__name", "student__surname", "student__course", "course_color", "student_brief_mix",)
|
list_display = ("week", "student__surname","student__name", "student__course", "course_color", "student_brief_mix",)
|
||||||
list_filter = ("week", "student__course", "student",)
|
list_filter = ("week", "student__course", "student",)
|
||||||
actions = ("export",)
|
actions = ("export",)
|
||||||
|
|
||||||
@@ -83,14 +116,23 @@ class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
|
|||||||
return SafeText("")
|
return SafeText("")
|
||||||
return course_color(obj.student.course.color)
|
return course_color(obj.student.course.color)
|
||||||
|
|
||||||
def has_module_permission(self, request):
|
# If a user is registered as student hide filters
|
||||||
|
def get_list_filter(self, request):
|
||||||
|
list_filter = super().get_list_filter(request)
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, 'student'):
|
||||||
return False
|
return []
|
||||||
return True
|
return list_filter
|
||||||
|
|
||||||
|
# If a user is registered as student do not show actions
|
||||||
|
def get_actions(self, request):
|
||||||
|
actions = super().get_actions(request)
|
||||||
|
if hasattr(request.user, 'student'):
|
||||||
|
return []
|
||||||
|
return actions
|
||||||
|
|
||||||
|
# If a user is registered as student show only their preferences
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
qs = super().get_queryset(request)
|
qs = super().get_queryset(request)
|
||||||
# If a user is registered as student show only their preferences
|
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, 'student'):
|
||||||
return qs.filter(student=request.user.student)
|
return qs.filter(student=request.user.student)
|
||||||
# If admin show everything
|
# If admin show everything
|
||||||
@@ -98,6 +140,12 @@ class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
|
|||||||
|
|
||||||
def get_form(self, request, obj=None, **kwargs):
|
def get_form(self, request, obj=None, **kwargs):
|
||||||
form: forms.Form = super().get_form(request, obj, **kwargs)
|
form: forms.Form = super().get_form(request, obj, **kwargs)
|
||||||
|
current_week = date.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 student is current user making request
|
# If student is current user making request
|
||||||
if hasattr(request.user, 'student'):
|
if hasattr(request.user, 'student'):
|
||||||
@@ -105,15 +153,45 @@ class WeekPreferenceAdmin(nested_admin.NestedModelAdmin):
|
|||||||
if 'student' in form.base_fields:
|
if 'student' in form.base_fields:
|
||||||
form.base_fields['student'].initial = student
|
form.base_fields['student'].initial = student
|
||||||
form.base_fields['student'].disabled = True
|
form.base_fields['student'].disabled = True
|
||||||
form.base_fields['week'].disabled = True
|
form.base_fields['week'].disabled = True # student cannot change week
|
||||||
|
|
||||||
# If form contains the week field
|
|
||||||
if 'week' in form.base_fields:
|
|
||||||
# Set default value as current week
|
|
||||||
current_week = date.today().isocalendar().week
|
|
||||||
form.base_fields['week'].initial = current_week
|
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
# If user is a student deny edit permission for week past the current one
|
||||||
|
def has_change_permission(self, request, obj: WeekPreference | None = None):
|
||||||
|
if hasattr(request.user, 'student') and obj:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
if current_week > obj.week:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
# If user is a student deny edit permission for week past the current one
|
||||||
|
def has_add_permission(self, request, obj: WeekPreference | None = None):
|
||||||
|
if hasattr(request.user, 'student') and obj:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
if current_week > obj.week:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
# If user is a student deny edit permission for week past the current one
|
||||||
|
def has_delete_permission(self, request, obj: WeekPreference | None = None):
|
||||||
|
if hasattr(request.user, 'student') and obj:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
if current_week > obj.week:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def changeform_view(self, request: HttpRequest, object_id: int | None = None, form_url: str = '', extra_context=None):
|
||||||
|
extra_context = extra_context or {}
|
||||||
|
if hasattr(request.user, 'student') and object_id:
|
||||||
|
current_week = date.today().isocalendar().week
|
||||||
|
weekpref = WeekPreference.objects.get(id=object_id)
|
||||||
|
if current_week > weekpref.week:
|
||||||
|
extra_context['show_save'] = False
|
||||||
|
extra_context['show_save_and_continue'] = False
|
||||||
|
extra_context['show_save_and_add_another'] = False
|
||||||
|
extra_context['show_delete'] = False
|
||||||
|
return super().changeform_view(request, object_id, form_url, extra_context)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
# Imposta automaticamente lo studente se non è già valorizzato
|
# Imposta automaticamente lo studente se non è già valorizzato
|
||||||
if hasattr(request.user, 'student') and not obj.student_id:
|
if hasattr(request.user, 'student') and not obj.student_id:
|
||||||
|
|||||||
Reference in New Issue
Block a user