131 lines
4.7 KiB
Python
131 lines
4.7 KiB
Python
from __future__ import annotations
|
|
|
|
from app.repositories.scheme_groups import list_scheme_version_groups
|
|
from app.repositories.scheme_seats import list_scheme_version_seats
|
|
from app.repositories.scheme_sectors import list_scheme_version_sectors
|
|
from app.services.baseline_selector import select_baseline_scheme_version
|
|
|
|
|
|
def _serialize_sector(row) -> dict:
|
|
return {
|
|
"sector_record_id": row.sector_record_id,
|
|
"element_id": row.element_id,
|
|
"sector_id": row.sector_id,
|
|
"name": row.name,
|
|
"classes_raw": row.classes_raw,
|
|
}
|
|
|
|
|
|
def _serialize_group(row) -> dict:
|
|
return {
|
|
"group_record_id": row.group_record_id,
|
|
"element_id": row.element_id,
|
|
"group_id": row.group_id,
|
|
"name": row.name,
|
|
"classes_raw": row.classes_raw,
|
|
}
|
|
|
|
|
|
def _serialize_seat(row) -> dict:
|
|
return {
|
|
"seat_record_id": row.seat_record_id,
|
|
"element_id": row.element_id,
|
|
"seat_id": row.seat_id,
|
|
"sector_id": row.sector_id,
|
|
"group_id": row.group_id,
|
|
"row_label": row.row_label,
|
|
"seat_number": row.seat_number,
|
|
}
|
|
|
|
|
|
def _build_diff(before_map: dict, after_map: dict) -> list[dict]:
|
|
keys = sorted(set(before_map.keys()) | set(after_map.keys()))
|
|
result: list[dict] = []
|
|
|
|
for key in keys:
|
|
before = before_map.get(key)
|
|
after = after_map.get(key)
|
|
|
|
if before is None and after is not None:
|
|
status = "added"
|
|
elif before is not None and after is None:
|
|
status = "removed"
|
|
elif before != after:
|
|
status = "changed"
|
|
else:
|
|
status = "unchanged"
|
|
|
|
result.append(
|
|
{
|
|
"key": key,
|
|
"status": status,
|
|
"before": before,
|
|
"after": after,
|
|
}
|
|
)
|
|
return result
|
|
|
|
|
|
async def build_structure_diff(
|
|
*,
|
|
scheme_id: str,
|
|
draft_scheme_version_id: str,
|
|
baseline_override_scheme_version_id: str | None = None,
|
|
) -> dict:
|
|
baseline, baseline_strategy = await select_baseline_scheme_version(
|
|
scheme_id=scheme_id,
|
|
draft_scheme_version_id=draft_scheme_version_id,
|
|
override_scheme_version_id=baseline_override_scheme_version_id,
|
|
)
|
|
|
|
draft_sectors = await list_scheme_version_sectors(draft_scheme_version_id)
|
|
draft_groups = await list_scheme_version_groups(draft_scheme_version_id)
|
|
draft_seats = await list_scheme_version_seats(draft_scheme_version_id)
|
|
|
|
if baseline is None:
|
|
baseline_sector_map = {}
|
|
baseline_group_map = {}
|
|
baseline_seat_map = {}
|
|
baseline_scheme_version_id = None
|
|
else:
|
|
baseline_scheme_version_id = baseline.scheme_version_id
|
|
baseline_sector_map = {
|
|
row.sector_record_id: _serialize_sector(row)
|
|
for row in await list_scheme_version_sectors(baseline.scheme_version_id)
|
|
}
|
|
baseline_group_map = {
|
|
row.group_record_id: _serialize_group(row)
|
|
for row in await list_scheme_version_groups(baseline.scheme_version_id)
|
|
}
|
|
baseline_seat_map = {
|
|
row.seat_record_id: _serialize_seat(row)
|
|
for row in await list_scheme_version_seats(baseline.scheme_version_id)
|
|
}
|
|
|
|
draft_sector_map = {row.sector_record_id: _serialize_sector(row) for row in draft_sectors}
|
|
draft_group_map = {row.group_record_id: _serialize_group(row) for row in draft_groups}
|
|
draft_seat_map = {row.seat_record_id: _serialize_seat(row) for row in draft_seats}
|
|
|
|
sector_diff = _build_diff(baseline_sector_map, draft_sector_map)
|
|
group_diff = _build_diff(baseline_group_map, draft_group_map)
|
|
seat_diff = _build_diff(baseline_seat_map, draft_seat_map)
|
|
|
|
return {
|
|
"baseline_scheme_version_id": baseline_scheme_version_id,
|
|
"baseline_strategy": baseline_strategy,
|
|
"summary": {
|
|
"sectors_added": sum(1 for item in sector_diff if item["status"] == "added"),
|
|
"sectors_removed": sum(1 for item in sector_diff if item["status"] == "removed"),
|
|
"sectors_changed": sum(1 for item in sector_diff if item["status"] == "changed"),
|
|
"groups_added": sum(1 for item in group_diff if item["status"] == "added"),
|
|
"groups_removed": sum(1 for item in group_diff if item["status"] == "removed"),
|
|
"groups_changed": sum(1 for item in group_diff if item["status"] == "changed"),
|
|
"seats_added": sum(1 for item in seat_diff if item["status"] == "added"),
|
|
"seats_removed": sum(1 for item in seat_diff if item["status"] == "removed"),
|
|
"seats_changed": sum(1 for item in seat_diff if item["status"] == "changed"),
|
|
},
|
|
"sectors": sector_diff,
|
|
"groups": group_diff,
|
|
"seats": seat_diff,
|
|
}
|