Add role profiles for the PRD user roles and lock quality decisions to QA
- Ten "Makap - ..." role profiles map the PRD Section 3 roles (sales, prepress, planner, procurement, warehouse, operator, supervisor, QC/QA, finance, management) onto standard and Makap roles. Created only if missing, so desk edits survive migrate (M6). - New Machine Operator and Prepress roles. Operators can run Job Cards, label rolls and raise in-process inspections, but cannot plan or release. - Quality eligibility, disposition and concession fields move to permlevel 1: only Quality Manager / Concession Authority can set them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ app_email = "josephnjuki833@gmail.com"
|
||||
app_license = "mit"
|
||||
|
||||
# MAKAP Module 3 child-table registration
|
||||
after_migrate = ["makap_backend.makap_backend.setup.ensure_makap_functional_roles", "makap_backend.makap_backend.setup.ensure_makap_object_permissions", "makap_backend.makap_backend.setup_module3.ensure_module3_child_tables", "makap_backend.makap_backend.setup_extensions.ensure_custom_fields", "makap_backend.makap_backend.setup_module8_dashboard.ensure_module8_number_cards", "makap_backend.makap_backend.setup_workspace_dashboard.ensure_workspace_number_cards", "makap_backend.makap_backend.workspace_setup.ensure_makap_workspace", "makap_backend.makap_backend.setup_module8_permissions.ensure_module8_role_permissions", "makap_backend.makap_backend.portal_shortcut.ensure_portal_shortcut"]
|
||||
after_migrate = ["makap_backend.makap_backend.setup.ensure_makap_functional_roles", "makap_backend.makap_backend.setup.ensure_makap_object_permissions", "makap_backend.makap_backend.setup_module3.ensure_module3_child_tables", "makap_backend.makap_backend.setup_extensions.ensure_custom_fields", "makap_backend.makap_backend.setup_module8_dashboard.ensure_module8_number_cards", "makap_backend.makap_backend.setup_workspace_dashboard.ensure_workspace_number_cards", "makap_backend.makap_backend.workspace_setup.ensure_makap_workspace", "makap_backend.makap_backend.setup_module8_permissions.ensure_module8_role_permissions", "makap_backend.makap_backend.setup_roles.ensure_shopfloor_permissions", "makap_backend.makap_backend.setup_roles.ensure_makap_role_profiles", "makap_backend.makap_backend.portal_shortcut.ensure_portal_shortcut"]
|
||||
|
||||
# MAKAP cross-module server-side controls
|
||||
doc_events = {
|
||||
|
||||
@@ -103,6 +103,9 @@ def ensure_makap_functional_roles():
|
||||
"Commercial Authority",
|
||||
# Module 8B
|
||||
"Credit Authority",
|
||||
# Shop floor and prepress (PRD Section 3)
|
||||
"Machine Operator",
|
||||
"Prepress",
|
||||
]
|
||||
created = []
|
||||
for role_name in role_names:
|
||||
|
||||
@@ -174,6 +174,15 @@ FIELDS = [
|
||||
]
|
||||
|
||||
|
||||
# Quality decisions: only roles granted permlevel 1 on Quality Inspection
|
||||
# (QA, see setup_roles) can change these.
|
||||
QUALITY_DECISION_FIELDS = {
|
||||
"makap_quality_eligibility", "makap_quality_disposition", "makap_disposition_quantity",
|
||||
"makap_disposition_uom", "makap_disposition_reason", "makap_concession_scope",
|
||||
"makap_concession_quantity", "makap_concession_uom", "makap_concession_reference",
|
||||
"makap_released_not_before",
|
||||
}
|
||||
|
||||
# Where each DocType's Makap fields live. Parent forms get one "Makap" tab;
|
||||
# child rows get a section. Operator and roll fields sit in the main view
|
||||
# because they are filled in on the shop floor, not reviewed later.
|
||||
@@ -194,9 +203,10 @@ def _end_anchor(meta):
|
||||
def build_custom_fields():
|
||||
grouped = {}
|
||||
for dt, fieldname, label, fieldtype, options, read_only in FIELDS:
|
||||
grouped.setdefault(dt, []).append(
|
||||
{"fieldname": fieldname, "label": label, "fieldtype": fieldtype, "options": options, "read_only": read_only}
|
||||
)
|
||||
field = {"fieldname": fieldname, "label": label, "fieldtype": fieldtype, "options": options, "read_only": read_only}
|
||||
if dt == "Quality Inspection" and fieldname in QUALITY_DECISION_FIELDS:
|
||||
field["permlevel"] = 1
|
||||
grouped.setdefault(dt, []).append(field)
|
||||
|
||||
result = {}
|
||||
for dt, fields in grouped.items():
|
||||
|
||||
@@ -2,15 +2,15 @@ import frappe
|
||||
from frappe.permissions import add_permission, update_permission_property
|
||||
|
||||
|
||||
def _grant(doctype, role, **flags):
|
||||
def _grant(doctype, role, permlevel=0, **flags):
|
||||
if not frappe.db.exists("DocType", doctype):
|
||||
return
|
||||
if not frappe.db.exists("Role", role):
|
||||
return
|
||||
if not frappe.db.exists("Custom DocPerm", {"parent": doctype, "role": role, "permlevel": 0}):
|
||||
add_permission(doctype, role, permlevel=0)
|
||||
if not frappe.db.exists("Custom DocPerm", {"parent": doctype, "role": role, "permlevel": permlevel}):
|
||||
add_permission(doctype, role, permlevel=permlevel)
|
||||
for ptype, value in flags.items():
|
||||
update_permission_property(doctype, role, 0, ptype, value)
|
||||
update_permission_property(doctype, role, permlevel, ptype, value)
|
||||
|
||||
|
||||
def ensure_module8_role_permissions():
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
"""Role profiles for the user roles in the PRD (Section 3), and the shop-floor
|
||||
permissions they need. Both are created only when missing, so changes Makap
|
||||
makes later in the desk are never overwritten on migrate.
|
||||
"""
|
||||
|
||||
import frappe
|
||||
|
||||
from makap_backend.makap_backend.setup_module8_permissions import _grant
|
||||
|
||||
ROLE_PROFILES = {
|
||||
"Makap - Sales / Account Manager": ["Sales User", "Commercial Reviewer"],
|
||||
"Makap - Design / Prepress": ["Prepress", "Technical Authority"],
|
||||
"Makap - Production Planner": ["Manufacturing Manager", "Production Authority", "Stock User"],
|
||||
"Makap - Procurement": ["Purchase User", "Purchase Manager", "Supply Assurance Manager", "Stock User"],
|
||||
"Makap - Warehouse": ["Stock User", "Materials Controller", "Dispatch Preparer"],
|
||||
"Makap - Machine Operator": ["Machine Operator"],
|
||||
"Makap - Shift Supervisor": ["Machine Operator", "Manufacturing User"],
|
||||
"Makap - QC / QA": ["Quality Manager", "Concession Authority"],
|
||||
"Makap - Finance": ["Accounts User", "Accounts Manager", "Credit Authority", "Commercial Authority"],
|
||||
"Makap - Management": ["Analytics", "Auditor"],
|
||||
}
|
||||
|
||||
# Operators record work on Job Cards and label rolls; they don't plan, buy or release.
|
||||
SHOPFLOOR_GRANTS = [
|
||||
("Job Card", "Machine Operator", dict(read=1, write=1, create=1, submit=1)),
|
||||
("Work Order", "Machine Operator", dict(read=1)),
|
||||
("Operation", "Machine Operator", dict(read=1)),
|
||||
("Workstation", "Machine Operator", dict(read=1)),
|
||||
("Item", "Machine Operator", dict(read=1)),
|
||||
("Batch", "Machine Operator", dict(read=1, write=1, create=1)),
|
||||
("Print Cylinder", "Machine Operator", dict(read=1)),
|
||||
("Quality Inspection", "Machine Operator", dict(read=1, write=1, create=1)),
|
||||
("Print Cylinder", "Prepress", dict(read=1, write=1, create=1)),
|
||||
("Packaging Specification", "Prepress", dict(read=1, write=1)),
|
||||
("Item", "Prepress", dict(read=1)),
|
||||
]
|
||||
|
||||
# Eligibility and disposition decide whether stock can move on or ship, so
|
||||
# only QA may set them; everyone who can open an inspection may still read them.
|
||||
QUALITY_DECISION_WRITERS = ["Quality Manager", "Concession Authority", "System Manager"]
|
||||
QUALITY_DECISION_READERS = [
|
||||
"Manufacturing User", "Manufacturing Manager", "Machine Operator", "Stock User",
|
||||
"Dispatch Preparer", "Dispatch Authority", "Production Authority",
|
||||
]
|
||||
|
||||
|
||||
def ensure_makap_role_profiles():
|
||||
created = []
|
||||
for profile, roles in ROLE_PROFILES.items():
|
||||
if frappe.db.exists("Role Profile", profile):
|
||||
continue
|
||||
doc = frappe.new_doc("Role Profile")
|
||||
doc.role_profile = profile
|
||||
for role in roles:
|
||||
if frappe.db.exists("Role", role):
|
||||
doc.append("roles", {"role": role})
|
||||
doc.insert(ignore_permissions=True)
|
||||
created.append(profile)
|
||||
return created
|
||||
|
||||
|
||||
def ensure_shopfloor_permissions():
|
||||
for doctype, role, flags in SHOPFLOOR_GRANTS:
|
||||
_grant(doctype, role, **flags)
|
||||
|
||||
for role in QUALITY_DECISION_WRITERS:
|
||||
_grant("Quality Inspection", role, permlevel=1, read=1, write=1)
|
||||
for role in QUALITY_DECISION_READERS:
|
||||
_grant("Quality Inspection", role, permlevel=1, read=1)
|
||||
return True
|
||||
Reference in New Issue
Block a user