drawings: on a rev mismatch, Clerical can keep the retired rev VISUAL calls (#41)
When VISUAL calls a rev that M-Files has retired, the draft is still flagged rev_mismatch, but the drawing job now also copies the rev VISUAL calls (MFilesKit 0.1.3 DrawingLookup.revision) into drawing_revisions and visual.called. A Clerical Supervisor picks either rev on the packet: "Use latest rev N" as before, or "Use rev V as VISUAL calls it" (rev-approve with use=called), with a reason and a signature. The kept rev holds while M-Files' Effective rev stays the one chosen against: no flag, no change order. A newer Effective rev flags the packet again; a new VISUAL rev clears the choice. Migration 0009 adds drawing_revisions. Needs mfileskit 0.1.3. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -221,6 +221,49 @@ def test_rev_approve(client: TestClient, fx: Settings) -> None:
|
||||
assert p["drawing_state"] == "attached" and "rev_mismatch" not in p["flags"]
|
||||
|
||||
|
||||
def test_rev_approve_keeps_the_rev_visual_calls(client: TestClient, fx: Settings) -> None:
|
||||
run_feed(fx, 1)
|
||||
run_drawings(fx)
|
||||
with app_conn(fx) as conn:
|
||||
pid = packet_id(conn, gen.KEY_TWO_OPS) # VISUAL rev 2 (Retired in M-Files), M-Files rev 3
|
||||
nf = packet_id(conn, gen.KEY_NOT_FOUND)
|
||||
body = {"reason": "Engineering says build lot 1 to rev 2", "sign": SIGN, "use": "called"}
|
||||
as_user(client, "clerk.leo")
|
||||
r = client.post(f"/api/packets/{nf}/rev-approve", json=body)
|
||||
assert r.status_code == 409 and r.json()["code"] == "nothing_staged", r.text
|
||||
r = client.post(f"/api/packets/{pid}/rev-approve", json={**body, "use": "oldest"})
|
||||
assert r.status_code == 422, r.text
|
||||
r = client.post(f"/api/packets/{pid}/rev-approve", json=body)
|
||||
assert r.status_code == 200, r.text
|
||||
with app_conn(fx) as conn:
|
||||
p = packet_row(conn, pid)
|
||||
assert p["drawing_state"] == "attached" and "rev_mismatch" not in p["flags"]
|
||||
ok = p["visual"]["rev_ok"]
|
||||
assert (ok["rev"], ok["vis_rev"], ok["use"], ok["latest"], ok["controlled"]) == (
|
||||
"2",
|
||||
"2",
|
||||
"called",
|
||||
"3",
|
||||
"Retired",
|
||||
)
|
||||
assert p["visual"]["rev_confirmed"] is True
|
||||
pages = drawing_pages(conn, pid)
|
||||
assert pages and all(pg[1] == "2" for pg in pages)
|
||||
log = conn.execute(
|
||||
"SELECT note FROM packet_log WHERE packet_id = %s AND action = 'Rev VISUAL calls kept by hand'", (pid,)
|
||||
).fetchall()
|
||||
assert len(log) == 1 and "Retired in M-Files" in log[0][0] and "M-Files has rev 3" in log[0][0]
|
||||
# the drawing job leaves the kept rev alone while M-Files' Effective rev is still 3
|
||||
with app_conn(fx) as conn:
|
||||
conn.execute("UPDATE drawing_lookups SET checked_at = now() - interval '2 days', next_check_at = now()")
|
||||
run_drawings(fx)
|
||||
with app_conn(fx) as conn:
|
||||
p = packet_row(conn, pid)
|
||||
assert p["drawing_state"] == "attached" and "rev_mismatch" not in p["flags"]
|
||||
assert p["visual"]["rev_confirmed"] is True and p["visual"].get("called") is None
|
||||
assert all(pg[1] == "2" for pg in drawing_pages(conn, pid))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- hand uploads
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user