71 lines
2.8 KiB
Python
71 lines
2.8 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Add inclusive sick-note end dates, preserving existing photos and dates."""
|
||
|
|
import json
|
||
|
|
import os
|
||
|
|
import tempfile
|
||
|
|
from pb_env import http, superuser_token
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
token = superuser_token()
|
||
|
|
|
||
|
|
def get(path):
|
||
|
|
code, result = http("GET", path, token=token)
|
||
|
|
if code != 200:
|
||
|
|
raise RuntimeError(f"Read failed: HTTP {code}")
|
||
|
|
return result
|
||
|
|
|
||
|
|
def notes():
|
||
|
|
rows, page = [], 1
|
||
|
|
while True:
|
||
|
|
result = get(f"/api/collections/employee_sick_notes/records?perPage=500&page={page}&sort=id")
|
||
|
|
rows.extend(result["items"])
|
||
|
|
if page >= result["totalPages"]:
|
||
|
|
return rows
|
||
|
|
page += 1
|
||
|
|
|
||
|
|
schema = get("/api/collections/employee_sick_notes")
|
||
|
|
before = notes()
|
||
|
|
fd, backup = tempfile.mkstemp(prefix="mega-before-sick-note-ranges-", suffix=".json")
|
||
|
|
with os.fdopen(fd, "w") as file:
|
||
|
|
json.dump({"schema": schema, "notes": before}, file)
|
||
|
|
print("Private backup:", backup)
|
||
|
|
wanted = {"name": "end_date", "type": "date", "required": False}
|
||
|
|
fields = schema["fields"]
|
||
|
|
existing = next((f for f in fields if f["name"] == "end_date"), None)
|
||
|
|
if existing:
|
||
|
|
assert all(existing.get(k) == v for k, v in wanted.items()), "Incompatible end-date field"
|
||
|
|
else:
|
||
|
|
code, _ = http("PATCH", f"/api/collections/{schema['id']}", {"fields": fields + [wanted]}, token)
|
||
|
|
if code != 200:
|
||
|
|
raise RuntimeError(f"Schema update failed: HTTP {code}")
|
||
|
|
changed = 0
|
||
|
|
for row in before:
|
||
|
|
if row.get("end_date"):
|
||
|
|
continue
|
||
|
|
code, _ = http("PATCH", f"/api/collections/employee_sick_notes/records/{row['id']}", {"end_date": row["note_date"]}, token)
|
||
|
|
if code != 200:
|
||
|
|
raise RuntimeError(f"Note update failed: HTTP {code}")
|
||
|
|
changed += 1
|
||
|
|
after = notes()
|
||
|
|
by_id = {row["id"]: row for row in after}
|
||
|
|
assert len(after) == len(before)
|
||
|
|
for row in before:
|
||
|
|
current = by_id[row["id"]]
|
||
|
|
assert current["end_date"] == (row.get("end_date") or row["note_date"])
|
||
|
|
for key, value in row.items():
|
||
|
|
if key not in ("end_date", "updated"):
|
||
|
|
assert current.get(key) == value, f"Unexpected change: {key}"
|
||
|
|
actual = get("/api/collections/employee_sick_notes")
|
||
|
|
for key in ("listRule", "viewRule", "createRule", "updateRule", "deleteRule", "indexes"):
|
||
|
|
assert actual.get(key) == schema.get(key), f"Unexpected schema change: {key}"
|
||
|
|
by_name = {f["name"]: f for f in actual["fields"]}
|
||
|
|
assert all(by_name["end_date"].get(k) == v for k, v in wanted.items())
|
||
|
|
for field in fields:
|
||
|
|
assert by_name[field["name"]] == field, "Original field changed"
|
||
|
|
print(f"Verified {len(after)} notes; {changed} single-day end dates filled; photos and original fields preserved.")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|