Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
AlekSIS-App-Chronos
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
AlekSIS®
Official
AlekSIS-App-Chronos
Merge requests
!47
Advanced data in timetable views
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
Advanced data in timetable views
feature/advanced-data-timetable-views
into
master
Overview
2
Commits
18
Pipelines
0
Changes
18
Merged
Jonathan Weth
requested to merge
feature/advanced-data-timetable-views
into
master
4 years ago
Overview
2
Commits
18
Pipelines
0
Changes
2
Expand
Closes
#72 (closed)
Closes
#73 (closed)
Edited
4 years ago
by
Jonathan Weth
0
0
Merge request reports
Compare
version 2
version 10
097f53d7
4 years ago
version 9
193bcfb7
4 years ago
version 8
97995b88
4 years ago
version 7
3e3ad4ce
4 years ago
version 6
bbb98434
4 years ago
version 5
949bb6fb
4 years ago
version 4
a10cd6ec
4 years ago
version 3
1005ae50
4 years ago
version 2
32570814
4 years ago
version 1
b5c52a83
4 years ago
master (base)
and
version 5
latest version
fe3d00a7
18 commits,
4 years ago
version 10
097f53d7
17 commits,
4 years ago
version 9
193bcfb7
16 commits,
4 years ago
version 8
97995b88
15 commits,
4 years ago
version 7
3e3ad4ce
14 commits,
4 years ago
version 6
bbb98434
13 commits,
4 years ago
version 5
949bb6fb
12 commits,
4 years ago
version 4
a10cd6ec
11 commits,
4 years ago
version 3
1005ae50
10 commits,
4 years ago
version 2
32570814
9 commits,
4 years ago
version 1
b5c52a83
8 commits,
4 years ago
Show latest version
2 files
+
30
−
15
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
2
Search (e.g. *.vue) (Ctrl+P)
aleksis/apps/chronos/util/build.py
0 → 100644
+
305
−
0
Options
from
collections
import
OrderedDict
from
datetime
import
date
from
typing
import
Union
,
List
,
Tuple
from
calendarweek
import
CalendarWeek
from
django.apps
import
apps
from
aleksis.core.models
import
Person
LessonPeriod
=
apps
.
get_model
(
"
chronos
"
,
"
LessonPeriod
"
)
TimePeriod
=
apps
.
get_model
(
"
chronos
"
,
"
TimePeriod
"
)
Break
=
apps
.
get_model
(
"
chronos
"
,
"
Break
"
)
Supervision
=
apps
.
get_model
(
"
chronos
"
,
"
Supervision
"
)
LessonSubstitution
=
apps
.
get_model
(
"
chronos
"
,
"
LessonSubstitution
"
)
SupervisionSubstitution
=
apps
.
get_model
(
"
chronos
"
,
"
SupervisionSubstitution
"
)
Event
=
apps
.
get_model
(
"
chronos
"
,
"
Event
"
)
Holiday
=
apps
.
get_model
(
"
chronos
"
,
"
Holiday
"
)
def
build_timetable
(
type_
:
str
,
obj
:
Union
[
int
,
Person
],
date_ref
:
Union
[
CalendarWeek
,
date
]
):
needed_breaks
=
[]
if
not
isinstance
(
obj
,
int
):
pk
=
obj
.
pk
else
:
pk
=
obj
is_person
=
False
if
type_
==
"
person
"
:
is_person
=
True
type_
=
obj
.
timetable_type
# Get matching holidays
if
is_person
:
holiday
=
Holiday
.
on_day
(
date_ref
)
else
:
holidays_per_weekday
=
Holiday
.
in_week
(
date_ref
)
# Get matching lesson periods
if
is_person
:
lesson_periods
=
LessonPeriod
.
objects
.
daily_lessons_for_person
(
obj
,
date_ref
)
else
:
lesson_periods
=
LessonPeriod
.
objects
.
in_week
(
date_ref
).
filter_from_type
(
type_
,
obj
)
# Sort lesson periods in a dict
lesson_periods_per_period
=
{}
for
lesson_period
in
lesson_periods
:
period
=
lesson_period
.
period
.
period
weekday
=
lesson_period
.
period
.
weekday
if
period
not
in
lesson_periods_per_period
:
lesson_periods_per_period
[
period
]
=
[]
if
is_person
else
{}
if
not
is_person
and
weekday
not
in
lesson_periods_per_period
[
period
]:
lesson_periods_per_period
[
period
][
weekday
]
=
[]
if
is_person
:
lesson_periods_per_period
[
period
].
append
(
lesson_period
)
else
:
lesson_periods_per_period
[
period
][
weekday
].
append
(
lesson_period
)
# Get events
if
is_person
:
events
=
Event
.
objects
.
on_day
(
date_ref
).
filter_from_person
(
obj
)
else
:
events
=
Event
.
objects
.
in_week
(
date_ref
).
filter_from_type
(
type_
,
obj
)
# Sort events in a dict
events_per_period
=
{}
for
event
in
events
:
if
not
is_person
and
event
.
date_start
<
date_ref
[
TimePeriod
.
weekday_min
]:
# If start date not in current week, set weekday and period to min
weekday_from
=
TimePeriod
.
weekday_min
period_from_first_weekday
=
TimePeriod
.
period_min
else
:
weekday_from
=
event
.
date_start
.
weekday
()
period_from_first_weekday
=
event
.
period_from
.
period
if
not
is_person
and
event
.
date_end
>
date_ref
[
TimePeriod
.
weekday_max
]:
# If end date not in current week, set weekday and period to max
weekday_to
=
TimePeriod
.
weekday_max
period_to_last_weekday
=
TimePeriod
.
period_max
else
:
weekday_to
=
event
.
date_end
.
weekday
()
period_to_last_weekday
=
event
.
period_to
.
period
for
weekday
in
range
(
weekday_from
,
weekday_to
+
1
):
if
is_person
and
weekday
!=
date_ref
.
weekday
():
# If daily timetable for person, skip other weekdays
continue
if
weekday
==
weekday_from
:
# If start day, use start period
period_from
=
period_from_first_weekday
else
:
# If not start day, use min period
period_from
=
TimePeriod
.
period_min
if
weekday
==
weekday_to
:
# If end day, use end period
period_to
=
period_to_last_weekday
else
:
# If not end day, use max period
period_to
=
TimePeriod
.
period_max
for
period
in
range
(
period_from
,
period_to
+
1
):
if
period
not
in
events_per_period
:
events_per_period
[
period
]
=
[]
if
is_person
else
{}
if
not
is_person
and
weekday
not
in
events_per_period
[
period
]:
events_per_period
[
period
][
weekday
]
=
[]
if
is_person
:
events_per_period
[
period
].
append
(
event
)
else
:
events_per_period
[
period
][
weekday
].
append
(
event
)
if
type_
==
"
teacher
"
:
# Get matching supervisions
if
is_person
:
week
=
CalendarWeek
.
from_date
(
date_ref
)
else
:
week
=
date_ref
supervisions
=
Supervision
.
objects
.
all
().
annotate_week
(
week
).
filter_by_teacher
(
obj
)
if
is_person
:
supervisions
.
filter_by_weekday
(
date_ref
.
weekday
())
supervisions_per_period_after
=
{}
for
supervision
in
supervisions
:
weekday
=
supervision
.
break_item
.
weekday
period_after_break
=
supervision
.
break_item
.
before_period_number
print
(
supervision
,
weekday
,
period_after_break
)
if
period_after_break
not
in
needed_breaks
:
needed_breaks
.
append
(
period_after_break
)
if
(
not
is_person
and
period_after_break
not
in
supervisions_per_period_after
):
supervisions_per_period_after
[
period_after_break
]
=
{}
if
is_person
:
supervisions_per_period_after
[
period_after_break
]
=
supervision
else
:
supervisions_per_period_after
[
period_after_break
][
weekday
]
=
supervision
# Get ordered breaks
breaks
=
OrderedDict
(
sorted
(
Break
.
get_breaks_dict
().
items
()))
rows
=
[]
for
period
,
break_
in
breaks
.
items
():
# period is period after break
# Break
if
type_
==
"
teacher
"
and
period
in
needed_breaks
:
row
=
{
"
type
"
:
"
break
"
,
"
after_period
"
:
break_
.
after_period_number
,
"
before_period
"
:
break_
.
before_period_number
,
"
time_start
"
:
break_
.
time_start
,
"
time_end
"
:
break_
.
time_end
,
}
if
not
is_person
:
cols
=
[]
for
weekday
in
range
(
TimePeriod
.
weekday_min
,
TimePeriod
.
weekday_max
+
1
):
col
=
None
if
(
period
in
supervisions_per_period_after
and
weekday
not
in
holidays_per_weekday
):
if
weekday
in
supervisions_per_period_after
[
period
]:
col
=
supervisions_per_period_after
[
period
][
weekday
]
cols
.
append
(
col
)
row
[
"
cols
"
]
=
cols
else
:
col
=
None
if
period
in
supervisions_per_period_after
and
not
holiday
:
col
=
supervisions_per_period_after
[
period
]
row
[
"
col
"
]
=
col
rows
.
append
(
row
)
# Period
if
period
<=
TimePeriod
.
period_max
:
row
=
{
"
type
"
:
"
period
"
,
"
period
"
:
period
,
"
time_start
"
:
break_
.
before_period
.
time_start
,
"
time_end
"
:
break_
.
before_period
.
time_end
,
}
if
not
is_person
:
cols
=
[]
for
weekday
in
range
(
TimePeriod
.
weekday_min
,
TimePeriod
.
weekday_max
+
1
):
col
=
[]
# Add lesson periods
if
(
period
in
lesson_periods_per_period
and
weekday
not
in
holidays_per_weekday
):
if
weekday
in
lesson_periods_per_period
[
period
]:
col
+=
lesson_periods_per_period
[
period
][
weekday
]
# Add events
if
(
period
in
events_per_period
and
weekday
not
in
holidays_per_weekday
):
if
weekday
in
events_per_period
[
period
]:
col
+=
events_per_period
[
period
][
weekday
]
cols
.
append
(
col
)
row
[
"
cols
"
]
=
cols
else
:
col
=
[]
# Add lesson periods
if
period
in
lesson_periods_per_period
and
not
holiday
:
col
+=
lesson_periods_per_period
[
period
]
# Add events
if
period
in
events_per_period
and
not
holiday
:
col
+=
events_per_period
[
period
]
row
[
"
col
"
]
=
col
rows
.
append
(
row
)
return
rows
def
build_substitutions_list
(
wanted_day
:
date
)
->
List
[
dict
]:
rows
=
[]
subs
=
LessonSubstitution
.
objects
.
on_day
(
wanted_day
).
order_by
(
"
lesson_period__lesson__groups
"
,
"
lesson_period__period
"
)
for
sub
in
subs
:
if
not
sub
.
cancelled_for_teachers
:
sort_a
=
sub
.
lesson_period
.
lesson
.
group_names
else
:
sort_a
=
"
Z.{}
"
.
format
(
sub
.
lesson_period
.
lesson
.
teacher_names
)
row
=
{
"
type
"
:
"
substitution
"
,
"
sort_a
"
:
sort_a
,
"
sort_b
"
:
"
{}
"
.
format
(
sub
.
lesson_period
.
period
.
period
),
"
el
"
:
sub
,
}
rows
.
append
(
row
)
# Get supervision substitutions
super_subs
=
SupervisionSubstitution
.
objects
.
filter
(
date
=
wanted_day
)
for
super_sub
in
super_subs
:
row
=
{
"
type
"
:
"
supervision_substitution
"
,
"
sort_a
"
:
"
Z.{}
"
.
format
(
super_sub
.
teacher
),
"
sort_b
"
:
"
{}
"
.
format
(
super_sub
.
supervision
.
break_item
.
after_period_number
),
"
el
"
:
super_sub
}
rows
.
append
(
row
)
# Sort all items
def
sorter
(
row
:
dict
):
return
row
[
"
sort_a
"
]
+
row
[
"
sort_b
"
]
rows
.
sort
(
key
=
sorter
)
return
rows
def
build_weekdays
(
base
:
List
[
Tuple
[
int
,
str
]],
wanted_week
:
CalendarWeek
)
->
List
[
dict
]:
holidays_per_weekday
=
Holiday
.
in_week
(
wanted_week
)
weekdays
=
[]
for
key
,
name
in
base
[
TimePeriod
.
weekday_min
:
TimePeriod
.
weekday_max
+
1
]:
weekday
=
{
"
key
"
:
key
,
"
name
"
:
name
,
"
date
"
:
wanted_week
[
key
],
"
holiday
"
:
holidays_per_weekday
[
key
]
if
key
in
holidays_per_weekday
else
None
,
}
weekdays
.
append
(
weekday
)
return
weekdays
Loading