подправил создание правил расписания

This commit is contained in:
Zuev
2026-05-08 13:41:25 +03:00
parent e12a5bcccd
commit 02c5ea9118
20 changed files with 592 additions and 126 deletions

View File

@@ -515,7 +515,6 @@ CREATE TABLE IF NOT EXISTS schedule_rule_slots (
day_of_week INT NOT NULL,
parity VARCHAR(10) NOT NULL,
time_slot_id BIGINT NOT NULL REFERENCES time_slots(id),
subgroup_id BIGINT NULL REFERENCES subgroups(id) ON DELETE SET NULL,
teacher_id BIGINT NOT NULL REFERENCES users(id),
classroom_id BIGINT NOT NULL REFERENCES classrooms(id),
lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id),
@@ -528,34 +527,84 @@ CREATE TABLE IF NOT EXISTS schedule_rule_slots (
CREATE INDEX IF NOT EXISTS idx_schedule_rule_slots_rule ON schedule_rule_slots(schedule_rule_id);
CREATE INDEX IF NOT EXISTS idx_schedule_rule_slots_teacher ON schedule_rule_slots(teacher_id);
CREATE INDEX IF NOT EXISTS idx_schedule_rule_slots_classroom ON schedule_rule_slots(classroom_id);
CREATE INDEX IF NOT EXISTS idx_schedule_rule_slots_subgroup ON schedule_rule_slots(subgroup_id);
CREATE INDEX IF NOT EXISTS idx_schedule_rule_slots_time ON schedule_rule_slots(day_of_week, parity, time_slot_id);
CREATE OR REPLACE FUNCTION validate_schedule_rule_slot_subgroup()
CREATE TABLE IF NOT EXISTS schedule_rule_slot_subgroups (
schedule_rule_slot_id BIGINT NOT NULL REFERENCES schedule_rule_slots(id) ON DELETE CASCADE,
subgroup_id BIGINT NOT NULL REFERENCES subgroups(id) ON DELETE CASCADE,
PRIMARY KEY (schedule_rule_slot_id, subgroup_id)
);
CREATE INDEX IF NOT EXISTS idx_schedule_rule_slot_subgroups_subgroup ON schedule_rule_slot_subgroups(subgroup_id);
CREATE OR REPLACE FUNCTION validate_schedule_rule_slot_subgroups()
RETURNS TRIGGER AS $$
DECLARE
lesson_type_name VARCHAR(50);
rule_id BIGINT;
subgroup_group_id BIGINT;
has_group_duplicate BOOLEAN;
BEGIN
IF NEW.subgroup_id IS NULL THEN
RETURN NEW;
END IF;
SELECT name INTO lesson_type_name
FROM lesson_types
WHERE id = NEW.lesson_type_id;
SELECT slot.schedule_rule_id, type.name INTO rule_id, lesson_type_name
FROM schedule_rule_slots slot
JOIN lesson_types type ON type.id = slot.lesson_type_id
WHERE slot.id = NEW.schedule_rule_slot_id;
IF lesson_type_name IS NULL OR LOWER(lesson_type_name) NOT LIKE '%лаб%' THEN
RAISE EXCEPTION 'Подгруппы можно выбирать только для лабораторных занятий';
END IF;
SELECT group_id INTO subgroup_group_id
FROM subgroups
WHERE id = NEW.subgroup_id;
IF subgroup_group_id IS NULL THEN
RAISE EXCEPTION 'Подгруппа не найдена';
END IF;
IF NOT EXISTS (
SELECT 1
FROM schedule_rule_groups rule_group
WHERE rule_group.schedule_rule_id = rule_id
AND rule_group.group_id = subgroup_group_id
) THEN
RAISE EXCEPTION 'Подгруппа должна относиться к одной из групп правила';
END IF;
IF TG_OP = 'UPDATE' THEN
SELECT EXISTS (
SELECT 1
FROM schedule_rule_slot_subgroups slot_subgroup
JOIN subgroups subgroup ON subgroup.id = slot_subgroup.subgroup_id
WHERE slot_subgroup.schedule_rule_slot_id = NEW.schedule_rule_slot_id
AND subgroup.group_id = subgroup_group_id
AND NOT (
slot_subgroup.schedule_rule_slot_id = OLD.schedule_rule_slot_id
AND slot_subgroup.subgroup_id = OLD.subgroup_id
)
) INTO has_group_duplicate;
ELSE
SELECT EXISTS (
SELECT 1
FROM schedule_rule_slot_subgroups slot_subgroup
JOIN subgroups subgroup ON subgroup.id = slot_subgroup.subgroup_id
WHERE slot_subgroup.schedule_rule_slot_id = NEW.schedule_rule_slot_id
AND subgroup.group_id = subgroup_group_id
) INTO has_group_duplicate;
END IF;
IF has_group_duplicate THEN
RAISE EXCEPTION 'В одном слоте можно выбрать не больше одной подгруппы каждой группы';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER validate_schedule_rule_slot_subgroup
BEFORE INSERT OR UPDATE ON schedule_rule_slots
CREATE TRIGGER validate_schedule_rule_slot_subgroups
BEFORE INSERT OR UPDATE ON schedule_rule_slot_subgroups
FOR EACH ROW
EXECUTE FUNCTION validate_schedule_rule_slot_subgroup();
EXECUTE FUNCTION validate_schedule_rule_slot_subgroups();
CREATE TEMP TABLE tmp_default_rules AS
SELECT
@@ -712,6 +761,7 @@ COMMENT ON TABLE student_group_calendar_assignments IS 'Назначения к
COMMENT ON TABLE schedule_rules IS 'Правила динамической генерации расписания';
COMMENT ON TABLE schedule_rule_groups IS 'Привязка правил расписания к учебным группам';
COMMENT ON TABLE schedule_rule_slots IS 'Слоты проведения занятий внутри правила расписания';
COMMENT ON TABLE schedule_rule_slot_subgroups IS 'Подгруппы лабораторных слотов правила расписания';
COMMENT ON COLUMN schedule_rules.lecture_academic_hours IS 'Лимит академических часов лекций';
COMMENT ON COLUMN schedule_rules.laboratory_academic_hours IS 'Лимит академических часов лабораторных работ';
COMMENT ON COLUMN schedule_rules.practice_academic_hours IS 'Лимит академических часов практик';