199 lines
7.3 KiB
Python
199 lines
7.3 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 _sector_compare_value(row) -> dict:
|
|
return {
|
|
"element_id": row.element_id,
|
|
"sector_id": row.sector_id,
|
|
"name": row.name,
|
|
"classes_raw": row.classes_raw,
|
|
}
|
|
|
|
|
|
def _sector_response_value(row) -> dict:
|
|
payload = _sector_compare_value(row)
|
|
payload["sector_record_id"] = row.sector_record_id
|
|
return payload
|
|
|
|
|
|
def _group_compare_value(row) -> dict:
|
|
return {
|
|
"element_id": row.element_id,
|
|
"group_id": row.group_id,
|
|
"name": row.name,
|
|
"classes_raw": row.classes_raw,
|
|
}
|
|
|
|
|
|
def _group_response_value(row) -> dict:
|
|
payload = _group_compare_value(row)
|
|
payload["group_record_id"] = row.group_record_id
|
|
return payload
|
|
|
|
|
|
def _seat_compare_value(row) -> dict:
|
|
return {
|
|
"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 _seat_response_value(row) -> dict:
|
|
payload = _seat_compare_value(row)
|
|
payload["seat_record_id"] = row.seat_record_id
|
|
return payload
|
|
|
|
|
|
def _build_diff(
|
|
*,
|
|
before_compare_map: dict,
|
|
after_compare_map: dict,
|
|
before_payload_map: dict,
|
|
after_payload_map: dict,
|
|
) -> list[dict]:
|
|
keys = sorted(set(before_payload_map.keys()) | set(after_payload_map.keys()))
|
|
result: list[dict] = []
|
|
|
|
for key in keys:
|
|
before_compare = before_compare_map.get(key)
|
|
after_compare = after_compare_map.get(key)
|
|
before_payload = before_payload_map.get(key)
|
|
after_payload = after_payload_map.get(key)
|
|
|
|
if before_compare is None and after_compare is not None:
|
|
status = "added"
|
|
elif before_compare is not None and after_compare is None:
|
|
status = "removed"
|
|
elif before_compare != after_compare:
|
|
status = "changed"
|
|
else:
|
|
status = "unchanged"
|
|
|
|
result.append(
|
|
{
|
|
"key": key,
|
|
"status": status,
|
|
"before": before_payload,
|
|
"after": after_payload,
|
|
}
|
|
)
|
|
return result
|
|
|
|
|
|
def _sector_key(row) -> str:
|
|
return row.sector_id if row.sector_id else (row.element_id if row.element_id else row.sector_record_id)
|
|
|
|
def _group_key(row) -> str:
|
|
return row.group_id if row.group_id else (row.element_id if row.element_id else row.group_record_id)
|
|
|
|
def _seat_key(row) -> str:
|
|
return row.seat_id if row.seat_id else (row.element_id if row.element_id else row.seat_record_id)
|
|
|
|
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_compare_map = {}
|
|
baseline_group_compare_map = {}
|
|
baseline_seat_compare_map = {}
|
|
baseline_sector_payload_map = {}
|
|
baseline_group_payload_map = {}
|
|
baseline_seat_payload_map = {}
|
|
baseline_scheme_version_id = None
|
|
else:
|
|
baseline_scheme_version_id = baseline.scheme_version_id
|
|
baseline_sectors = await list_scheme_version_sectors(baseline.scheme_version_id)
|
|
baseline_groups = await list_scheme_version_groups(baseline.scheme_version_id)
|
|
baseline_seats = await list_scheme_version_seats(baseline.scheme_version_id)
|
|
baseline_sector_compare_map = {
|
|
_sector_key(row): _sector_compare_value(row)
|
|
for row in baseline_sectors
|
|
}
|
|
baseline_sector_payload_map = {
|
|
_sector_key(row): _sector_response_value(row)
|
|
for row in baseline_sectors
|
|
}
|
|
baseline_group_compare_map = {
|
|
_group_key(row): _group_compare_value(row)
|
|
for row in baseline_groups
|
|
}
|
|
baseline_group_payload_map = {
|
|
_group_key(row): _group_response_value(row)
|
|
for row in baseline_groups
|
|
}
|
|
baseline_seat_compare_map = {
|
|
_seat_key(row): _seat_compare_value(row)
|
|
for row in baseline_seats
|
|
}
|
|
baseline_seat_payload_map = {
|
|
_seat_key(row): _seat_response_value(row)
|
|
for row in baseline_seats
|
|
}
|
|
|
|
draft_sector_compare_map = {_sector_key(row): _sector_compare_value(row) for row in draft_sectors}
|
|
draft_sector_payload_map = {_sector_key(row): _sector_response_value(row) for row in draft_sectors}
|
|
draft_group_compare_map = {_group_key(row): _group_compare_value(row) for row in draft_groups}
|
|
draft_group_payload_map = {_group_key(row): _group_response_value(row) for row in draft_groups}
|
|
draft_seat_compare_map = {_seat_key(row): _seat_compare_value(row) for row in draft_seats}
|
|
draft_seat_payload_map = {_seat_key(row): _seat_response_value(row) for row in draft_seats}
|
|
|
|
sector_diff = _build_diff(
|
|
before_compare_map=baseline_sector_compare_map,
|
|
after_compare_map=draft_sector_compare_map,
|
|
before_payload_map=baseline_sector_payload_map,
|
|
after_payload_map=draft_sector_payload_map,
|
|
)
|
|
group_diff = _build_diff(
|
|
before_compare_map=baseline_group_compare_map,
|
|
after_compare_map=draft_group_compare_map,
|
|
before_payload_map=baseline_group_payload_map,
|
|
after_payload_map=draft_group_payload_map,
|
|
)
|
|
seat_diff = _build_diff(
|
|
before_compare_map=baseline_seat_compare_map,
|
|
after_compare_map=draft_seat_compare_map,
|
|
before_payload_map=baseline_seat_payload_map,
|
|
after_payload_map=draft_seat_payload_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,
|
|
}
|