Cell formatting OK, notes with hb details
This commit is contained in:
@@ -3,14 +3,15 @@ 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
|
||||||
|
from openpyxl.utils import get_column_letter
|
||||||
|
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
import calendar
|
|
||||||
|
|
||||||
from ..models.weekpref import WeekPreference
|
from ..models.weekpref import WeekPreference
|
||||||
from ..models.missions import Training
|
from ..models.missions import Training
|
||||||
from ..models.hourbuildings import HourBuilding
|
from ..models.hourbuildings import HourBuilding,HourBuildingLeg
|
||||||
|
|
||||||
|
|
||||||
def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> HttpResponse:
|
def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> HttpResponse:
|
||||||
|
|
||||||
@@ -20,9 +21,10 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
# Init Variables
|
# Init Variables
|
||||||
year = date.today().year
|
year = date.today().year
|
||||||
week = queryset.first().week if queryset.first() else date.today().isocalendar().week
|
week = queryset.first().week if queryset.first() else date.today().isocalendar().week
|
||||||
|
weeks = queryset.order_by("week").distinct("week").all()
|
||||||
|
|
||||||
# Prepare export filename and http content
|
# Prepare export filename and http content
|
||||||
filename = f"{year}-week{week}_export.xlsx"
|
filename = f"{year}_week{'+'.join([str(w.week) for w in weeks])}_export.xlsx"
|
||||||
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||||
response['Content-Disposition'] = f'attachment; filename="{filename}"'
|
response['Content-Disposition'] = f'attachment; filename="{filename}"'
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
ws = wb.active
|
ws = wb.active
|
||||||
if not ws:
|
if not ws:
|
||||||
raise Exception("Export: cannot select active workbook")
|
raise Exception("Export: cannot select active workbook")
|
||||||
ws.title = f"{year} Week {week} Preferences"
|
ws.title = f"Week Preferences"
|
||||||
|
|
||||||
# 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)]
|
||||||
@@ -56,11 +58,9 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
cell.font = bold_white
|
cell.font = bold_white
|
||||||
cell.alignment = center
|
cell.alignment = center
|
||||||
|
|
||||||
# Scrittura dati
|
# Fill worksheet with EVERY training and hb for every student
|
||||||
row: int = 2
|
row: int = 2
|
||||||
row_offset: int = 0
|
row_offset: int = 0
|
||||||
|
|
||||||
# Fill worksheet with EVERY training and hb for every student
|
|
||||||
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):
|
||||||
student_data: List[str]
|
student_data: List[str]
|
||||||
student_phone: str = q.student.phone if q.student.phone else ""
|
student_phone: str = q.student.phone if q.student.phone else ""
|
||||||
@@ -89,7 +89,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
mission_name if t.sunday else ""
|
mission_name if t.sunday else ""
|
||||||
]
|
]
|
||||||
mission_notes = t.notes if t.notes else "--"
|
mission_notes = t.notes if t.notes else "--"
|
||||||
mission_data.append([str(week), *student_data, *mission_days, student_phone, student_email, mission_notes])
|
mission_data.append([str(q.week), *student_data, *mission_days, student_phone, student_email, mission_notes])
|
||||||
|
|
||||||
# Fill HourBuilding rows
|
# Fill HourBuilding rows
|
||||||
hb_name: str
|
hb_name: str
|
||||||
@@ -97,7 +97,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
hb_notes: str
|
hb_notes: str
|
||||||
hb_data: List[List[str]] = []
|
hb_data: List[List[str]] = []
|
||||||
for h in HourBuilding.objects.filter(weekpref = q.id):
|
for h in HourBuilding.objects.filter(weekpref = q.id):
|
||||||
hb_name = f"HB-{h.aircraft}"
|
hb_name = f"HB-{h.aircraft}\nVedi Note ->"
|
||||||
hb_days = [
|
hb_days = [
|
||||||
hb_name if h.monday else "",
|
hb_name if h.monday else "",
|
||||||
hb_name if h.tuesday else "",
|
hb_name if h.tuesday else "",
|
||||||
@@ -107,18 +107,18 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
hb_name if h.saturday else "",
|
hb_name if h.saturday else "",
|
||||||
hb_name if h.sunday else ""
|
hb_name if h.sunday else ""
|
||||||
]
|
]
|
||||||
hb_notes = h.notes if h.notes else "--"
|
hb_notes = f"{h.notes}\n----\n" if h.notes else ""
|
||||||
hb_data.append([str(week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes])
|
hb_legs = HourBuildingLeg.objects.filter(hb_id = h.id)
|
||||||
|
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.strip('\r')
|
||||||
|
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
|
||||||
|
all_data: List[List[str]] = mission_data + hb_data
|
||||||
student_start: int = row + row_offset
|
student_start: int = row + row_offset
|
||||||
for r in mission_data + hb_data:
|
for r in all_data:
|
||||||
prev_cell_val: str | None = None
|
|
||||||
merge_start: bool = False
|
|
||||||
merge_col_start: int = 1
|
|
||||||
for j, c in enumerate(r, start=1):
|
for j, c in enumerate(r, start=1):
|
||||||
if prev_cell_val is None:
|
|
||||||
prev_cell_val = c
|
|
||||||
cell = ws.cell(row = row + row_offset, column = j, value = c)
|
cell = ws.cell(row = row + row_offset, column = j, value = c)
|
||||||
cell.alignment = center
|
cell.alignment = center
|
||||||
# Format Student Name
|
# Format Student Name
|
||||||
@@ -127,21 +127,27 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
|
|||||||
# Format Course Column
|
# Format Course Column
|
||||||
if j == course_index and q.student.course:
|
if j == course_index and q.student.course:
|
||||||
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]
|
||||||
|
merge_start: bool = False
|
||||||
|
merge_col_start: int = 1
|
||||||
|
for c, v in enumerate(r, start=1):
|
||||||
# Merge cells in the row
|
# Merge cells in the row
|
||||||
if c == prev_cell_val and not merge_start:
|
if v == prev_cell_val and not merge_start:
|
||||||
merge_start = True
|
merge_start = True
|
||||||
merge_col_start = max(j-1, 1)
|
merge_col_start = c-1 # start merge from previous column
|
||||||
elif c != prev_cell_val and merge_start:
|
elif v != prev_cell_val and merge_start:
|
||||||
merge_start = False
|
merge_start = False
|
||||||
ws.merge_cells(start_row=row+row_offset,
|
ws.merge_cells(start_row=row+row_offset,
|
||||||
end_row=row+row_offset,
|
end_row=row+row_offset,
|
||||||
start_column=merge_col_start,
|
start_column=max(merge_col_start,1),
|
||||||
end_column=max(j-1,1))
|
end_column=max(c-1,1)) # end merge to previous column
|
||||||
|
prev_cell_val = v
|
||||||
|
|
||||||
# Incement row counter
|
# Incement row counter
|
||||||
row_offset += 1
|
row_offset += 1
|
||||||
|
|
||||||
# End f 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 Name
|
||||||
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)
|
||||||
@@ -152,6 +158,14 @@ 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)
|
||||||
|
|
||||||
|
# Keep the largest column
|
||||||
|
for column_cells in ws.columns:
|
||||||
|
length: int = max(len(str(cell.value)) for cell in column_cells)
|
||||||
|
col_letter: str = "A"
|
||||||
|
if column_cells[0].column:
|
||||||
|
get_column_letter(column_cells[0].column)
|
||||||
|
ws.column_dimensions[col_letter].width = length
|
||||||
|
|
||||||
# Save document in HttpResponse
|
# Save document in HttpResponse
|
||||||
wb.save(response)
|
wb.save(response)
|
||||||
|
|
||||||
|
|||||||
1
techdb/static/password
Normal file
1
techdb/static/password
Normal file
@@ -0,0 +1 @@
|
|||||||
|
admin: CantorAdmin2k25
|
||||||
Reference in New Issue
Block a user