82 lines
3.2 KiB
Python
82 lines
3.2 KiB
Python
# Generated for QI multi-department support.
|
|
#
|
|
# Order matters:
|
|
# 1. Add the new `departments` M2M (blank).
|
|
# 2. Copy each existing `department_id` into the M2M, then rebuild the derived
|
|
# `team_members` set from each department's champion + manager (and the
|
|
# project lead). The sync logic is inlined here (not imported from the
|
|
# model) so the migration stays stable as the model method evolves.
|
|
# 3. Remove the old single `department` FK.
|
|
|
|
from django.db import migrations, models
|
|
|
|
|
|
def copy_department_and_sync_team(apps, schema_editor):
|
|
QIProject = apps.get_model("projects", "QIProject")
|
|
Staff = apps.get_model("organizations", "Staff")
|
|
|
|
missing_manager_profile = 0
|
|
for project in QIProject.objects.exclude(department__isnull=True):
|
|
old_dept = project.department
|
|
# M2M add via the through manager (project has just been saved with the new field).
|
|
if old_dept and old_dept not in project.departments.all():
|
|
project.departments.add(old_dept)
|
|
|
|
# Rebuild derived team_members: champion (Staff) + manager.staff_profile (Staff),
|
|
# plus the project lead. De-duped; nulls skipped.
|
|
pks = set()
|
|
for dept in project.departments.all():
|
|
champion_id = getattr(dept, "champion_id", None)
|
|
if champion_id:
|
|
pks.add(champion_id)
|
|
manager_user_id = getattr(dept, "manager_id", None)
|
|
if manager_user_id:
|
|
manager_user = dept.manager
|
|
if manager_user is not None and hasattr(manager_user, "staff_profile"):
|
|
sp = manager_user.staff_profile
|
|
if sp is not None and sp.id:
|
|
pks.add(sp.id)
|
|
else:
|
|
missing_manager_profile += 1
|
|
if project.project_lead_id:
|
|
pks.add(project.project_lead_id)
|
|
|
|
if pks:
|
|
project.team_members.set(Staff.objects.filter(pk__in=pks))
|
|
|
|
if missing_manager_profile:
|
|
# Surface how many manager links could not be added (no staff_profile).
|
|
print(f" [qi_multi_department] {missing_manager_profile} department manager(s) "
|
|
f"had no staff_profile and were excluded from the derived team.")
|
|
|
|
|
|
def remove_team_backreference(apps, schema_editor):
|
|
# Reverse is a no-op: we cannot reconstruct the single FK from the M2M losslessly.
|
|
pass
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
("organizations", "0015_hospital_branding"),
|
|
("projects", "0003_alter_qiproject_project_lead_and_more"),
|
|
]
|
|
|
|
operations = [
|
|
migrations.AddField(
|
|
model_name="qiproject",
|
|
name="departments",
|
|
field=models.ManyToManyField(
|
|
blank=True,
|
|
help_text="Departments involved in this QI project. Team membership is derived from each department's champion and manager.",
|
|
related_name="qi_projects",
|
|
to="organizations.department",
|
|
),
|
|
),
|
|
migrations.RunPython(copy_department_and_sync_team, remove_team_backreference),
|
|
migrations.RemoveField(
|
|
model_name="qiproject",
|
|
name="department",
|
|
),
|
|
]
|