#!/usr/bin/env python3 """Add worker active/inactive status, preserving existing status on repeat runs. Only previously unclassified employees are set active. No rates, timesheets, clock events or assignments are modified. Run with credentials from .env.local: python3 scripts/pb-add-worker-status.py """ 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 workers(): rows = [] page = 1 while True: result = get(f"/api/collections/employees/records?perPage=500&page={page}&sort=id") rows.extend(result["items"]) if page >= result["totalPages"]: return rows page += 1 schema = get("/api/collections/employees") before = workers() fd, backup = tempfile.mkstemp(prefix="mega-before-worker-status-", suffix=".json") with os.fdopen(fd, "w") as file: json.dump({"schema": schema, "employees": before}, file) print("Private backup:", backup) expected = [ {"name": "employment_status", "type": "select", "required": False, "values": ["active", "inactive"], "maxSelect": 1}, {"name": "inactive_from", "type": "date", "required": False}, ] fields = schema["fields"] by_name = {f["name"]: f for f in fields} missing = [] for wanted in expected: if wanted["name"] not in by_name: missing.append(wanted) elif any(by_name[wanted["name"]].get(k) != v for k, v in wanted.items()): raise RuntimeError("Existing worker-status field is incompatible") if missing: code, result = http("PATCH", f"/api/collections/{schema['id']}", {"fields": fields + missing}, token) if code != 200: raise RuntimeError(f"Schema update failed: HTTP {code}") changed = 0 for row in before: if row.get("employment_status"): continue code, result = http("PATCH", f"/api/collections/employees/records/{row['id']}", {"employment_status": "active"}, token) if code != 200: raise RuntimeError(f"Worker status update failed: HTTP {code}") changed += 1 after = workers() 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["employment_status"] == (row.get("employment_status") or "active") for key, value in row.items(): if key not in ("employment_status", "updated"): assert current.get(key) == value, f"Unexpected change: {key}" actual = {f["name"]: f for f in get("/api/collections/employees")["fields"]} for wanted in expected: assert all(actual[wanted["name"]].get(k) == v for k, v in wanted.items()) print(f"Verified {len(after)} workers; {changed} set active; all other fields preserved.") if __name__ == "__main__": main()