Build Seth's changes C1 to C11 (Gitea issues 1, 8, 18, 23, 24, 25, 27, 31, 32, 33, 36)
- C1 (issue 1): over target follows VISUAL ticket hours, not the timer. - C2 (issue 24): a Q.C. reject always needs a reason; accept needs an NCR number after a reject without one. - C3 (issue 25): an incomplete unit ITP blocks filing. - C4 (issue 27): prints open the print dialog on the page, no new tab. - C5 (issue 31): filing is blocked while VISUAL shows a work order open; the feed sets vclosed on VISUAL packets. - C6 (issue 8): the data book leaves out the history pages. - C7 (issue 18): the supervisor approves each received short; accept and filing wait for it. - C8 (issue 23): per-department checklists, edited by the department supervisor or Admin, frozen at START. - C9 (issue 32): Q.C. and Clerical may run the stamp check. - C10 (issue 33): the PM screen and reports are for PS-ProjectMgmt and Admin only. - C11 (issue 36): the Stall screen lists the packets assigned to the welder, at the supervisor's stall. Migration 0011. Docs: PLAN (also issue 9 confirmed, issue 4 asked), POLICY, SECURITY, SCHEMA, FEED, README, CHANGELOG. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
"""The manufacturing data book, page for page after the old databook.js.
|
||||
|
||||
Sections, in order: 1 Drawings, 2 Material traceability, 3 Welding record, 4 Q.C. inspection, 5 Q.C. and test
|
||||
documents, 6 Material test reports, 7 Record history. Front matter (cover and index) is ours; drawings, documents
|
||||
and MTRs are copied at their own size; the heat and weld maps are rasters at the sheet's size.
|
||||
Sections, in order: 1 Drawings (with the change order record when the packet has change orders), 2 Material
|
||||
traceability, 3 Welding record, 4 Q.C. inspection, 5 Q.C. and test documents (the packet's documents, NCRs included),
|
||||
6 Material test reports. Front matter (cover and index) is ours; drawings, documents and MTRs are copied at their own
|
||||
size; the heat and weld maps are rasters at the sheet's size. The packet history pages are left out (change C6, Gitea
|
||||
issue 8): the book is the one copy and goes to the customer. History stays readable in Packet Station.
|
||||
|
||||
A part that cannot be read (a missing file, a file that is not a PDF or an image, a pypdf error) becomes a warning row
|
||||
in the index and in `Built.warnings`. Only a failure to assemble the whole book raises PdfError.
|
||||
@@ -65,7 +67,6 @@ SECTION_NAMES = (
|
||||
"Q.C. inspection",
|
||||
"Q.C. and test documents",
|
||||
"Material test reports",
|
||||
"Record history",
|
||||
)
|
||||
|
||||
|
||||
@@ -240,7 +241,6 @@ class Book:
|
||||
self.s4_qc()
|
||||
self.s5_documents()
|
||||
self.s6_mtrs()
|
||||
self.s7_history()
|
||||
size = self.drawing_size(live or void)
|
||||
|
||||
front_n = 2
|
||||
@@ -314,6 +314,8 @@ class Book:
|
||||
pg,
|
||||
void=maps.void_text(pg, self.tz),
|
||||
)
|
||||
if p.get("change_orders"):
|
||||
self.gen(1, "Change order record", self.change_orders)
|
||||
|
||||
# ------------------------------------------------------------ section 2
|
||||
|
||||
@@ -545,9 +547,9 @@ class Book:
|
||||
)
|
||||
y += 18
|
||||
y = d.section_label("Station checklist", y)
|
||||
items = checklists.checklist_for(
|
||||
weld, p.get("drawing"), p.get("rev"), p.get("wps"), checklists.load_templates(self.conn)
|
||||
)
|
||||
# change C8: the stage's checklist frozen at START, else its department's live list
|
||||
templates = checklists.stage_templates(self.conn, rec.get("id"), str(code))
|
||||
items = checklists.checklist_for(weld, p.get("drawing"), p.get("rev"), p.get("wps"), templates)
|
||||
ck = rec.get("checklist") or {}
|
||||
body = []
|
||||
for it in items:
|
||||
@@ -750,75 +752,50 @@ class Book:
|
||||
if not lines:
|
||||
self.warn(6, "No MTRs attached in Packet Station — add from the warehouse files")
|
||||
|
||||
# ------------------------------------------------------------ section 7
|
||||
# ------------------------------------------------------------ change orders (section 1)
|
||||
|
||||
def s7_history(self) -> None:
|
||||
self.gen(7, "Packet record history", self.history)
|
||||
|
||||
def history(self) -> Doc:
|
||||
def change_orders(self) -> Doc:
|
||||
"""The change orders on this packet: who issued each, what it changed and who verified it. The packet's
|
||||
history pages are not in the book (change C6); they stay readable in Packet Station."""
|
||||
p = self.p
|
||||
d = Doc(("Record History", "Section 6 • Manufacturing data book"))
|
||||
d = Doc(("Change Order Record", "Section 1 • Manufacturing data book"))
|
||||
y = 128.0
|
||||
d.tx(
|
||||
"Every action taken on this packet in Packet Station, oldest first, with the person who took it.",
|
||||
"The change orders issued on this packet, with the departments that verified each one.",
|
||||
L,
|
||||
y,
|
||||
size=8.5,
|
||||
color=GREY,
|
||||
)
|
||||
y += 18
|
||||
cos = p.get("change_orders") or []
|
||||
if cos:
|
||||
d.lbl("Change orders", L, y)
|
||||
y += 8
|
||||
body = []
|
||||
for co in cos:
|
||||
verified = co.get("verified") or {}
|
||||
req = co.get("required") or []
|
||||
ver = "\n".join(
|
||||
f"{self.dept_name(dp)}: "
|
||||
+ (
|
||||
f"{parts.name_of(self.users, verified[dp].get('by'))} {self.d(verified[dp].get('at'))}"
|
||||
if dp in verified
|
||||
else "PENDING"
|
||||
)
|
||||
for dp in req
|
||||
)
|
||||
body.append(
|
||||
[
|
||||
f"CO-{co.get('co_no')}" + (f"\n{co['ecn']}" if co.get("ecn") else ""),
|
||||
f"{self.dt(co.get('issued_at'))}\n{parts.name_emp(self.users, co.get('issued_by'))}",
|
||||
co_summary(co),
|
||||
co.get("reason") or "",
|
||||
ver or "No departments to verify",
|
||||
]
|
||||
)
|
||||
y = d.table(
|
||||
["CHANGE", "ISSUED", "DOCUMENTS", "REASON", "VERIFIED BY"],
|
||||
body,
|
||||
y,
|
||||
{0: {"w": 56, "bold": True}, 1: {"w": 96}, 4: {"w": 130}},
|
||||
size=7.4,
|
||||
)
|
||||
y += 16
|
||||
y = d.ensure_space(y, 40)
|
||||
d.lbl("Record history", L, y)
|
||||
y += 8
|
||||
body = []
|
||||
for e in parts.log_rows(self.conn, int(p["id"])):
|
||||
who = str(e.get("by_name") or "")
|
||||
if who and e.get("by") is not None:
|
||||
who += f" ({e.get('emp_no') or '?'})"
|
||||
role = parts.role_text(e.get("role"))
|
||||
for co in p.get("change_orders") or []:
|
||||
verified = co.get("verified") or {}
|
||||
req = co.get("required") or []
|
||||
ver = "\n".join(
|
||||
f"{self.dept_name(dp)}: "
|
||||
+ (
|
||||
f"{parts.name_of(self.users, verified[dp].get('by'))} {self.d(verified[dp].get('at'))}"
|
||||
if dp in verified
|
||||
else "PENDING"
|
||||
)
|
||||
for dp in req
|
||||
)
|
||||
body.append(
|
||||
[self.dt(e.get("at")), e.get("action") or "", who + (f"\n{role}" if role else ""), e.get("note") or ""]
|
||||
[
|
||||
f"CO-{co.get('co_no')}" + (f"\n{co['ecn']}" if co.get("ecn") else ""),
|
||||
f"{self.dt(co.get('issued_at'))}\n{parts.name_emp(self.users, co.get('issued_by'))}",
|
||||
co_summary(co),
|
||||
co.get("reason") or "",
|
||||
ver or "No departments to verify",
|
||||
]
|
||||
)
|
||||
d.table(
|
||||
["DATE / TIME", "EVENT", "BY", "DETAIL"],
|
||||
["CHANGE", "ISSUED", "DOCUMENTS", "REASON", "VERIFIED BY"],
|
||||
body,
|
||||
y,
|
||||
{0: {"w": 92}, 1: {"w": 150, "bold": True}, 2: {"w": 96}},
|
||||
size=7.6,
|
||||
{0: {"w": 56, "bold": True}, 1: {"w": 96}, 4: {"w": 130}},
|
||||
size=7.4,
|
||||
)
|
||||
return d
|
||||
|
||||
|
||||
Reference in New Issue
Block a user