Separate normal task review from AQMM review
This commit is contained in:
@@ -31,6 +31,29 @@ TASK_STATUSES = [
|
||||
OPEN_TASK_STATUSES = {"pending", "in_progress", "blocked"}
|
||||
CLOSED_TASK_STATUSES = {"completed", "not_applicable", "cancelled"}
|
||||
|
||||
NORMAL_REVIEW_ROLES = {"manager", "partner", "manager_or_partner"}
|
||||
|
||||
|
||||
def normal_review_role_for_template(template) -> str | None:
|
||||
if not getattr(template, "requires_review", False):
|
||||
return None
|
||||
explicit = (getattr(template, "normal_review_role", None) or "").strip().lower()
|
||||
if explicit in NORMAL_REVIEW_ROLES:
|
||||
return explicit
|
||||
default_role = (getattr(template, "default_role_name", None) or "").strip().lower()
|
||||
eligible = {
|
||||
part.strip().lower()
|
||||
for part in (getattr(template, "eligible_role_names", None) or "").split(",")
|
||||
if part.strip()
|
||||
}
|
||||
if default_role in {"manager", "branch manager"} and "partner" in eligible:
|
||||
return "partner"
|
||||
if default_role not in {"manager", "branch manager", "partner"} and ({"manager", "branch manager"} & eligible):
|
||||
return "manager"
|
||||
if "partner" in eligible and not ({"manager", "branch manager"} & eligible):
|
||||
return "partner"
|
||||
return "manager"
|
||||
|
||||
|
||||
TASK_COMMENT_TYPES = [
|
||||
("internal_note", "Internal Note"),
|
||||
@@ -307,6 +330,9 @@ def generate_tasks_for_subscription(db: Session, *, subscription: ClientServiceS
|
||||
response_type=(getattr(template, "response_type", "NONE") or "NONE").upper(),
|
||||
evidence_required=getattr(template, "evidence_required", False),
|
||||
remarks_required_if_no=getattr(template, "remarks_required_if_no", False),
|
||||
normal_review_required=bool(getattr(template, "requires_review", False)),
|
||||
normal_review_role=normal_review_role_for_template(template),
|
||||
normal_review_status="not_ready" if getattr(template, "requires_review", False) else "not_required",
|
||||
is_aqmm_task=getattr(template, "is_aqmm_task", False),
|
||||
aqmm_mandatory=getattr(template, "aqmm_mandatory", False),
|
||||
aqmm_evidence_required=getattr(template, "aqmm_evidence_required", False),
|
||||
@@ -372,6 +398,12 @@ def _copy_template_snapshot_to_task(
|
||||
task.response_type = (getattr(template, "response_type", "NONE") or "NONE").upper()
|
||||
task.evidence_required = getattr(template, "evidence_required", False)
|
||||
task.remarks_required_if_no = getattr(template, "remarks_required_if_no", False)
|
||||
task.normal_review_required = bool(getattr(template, "requires_review", False))
|
||||
task.normal_review_role = normal_review_role_for_template(template)
|
||||
if not task.normal_review_required:
|
||||
task.normal_review_status = "not_required"
|
||||
elif (getattr(task, "normal_review_status", None) or "not_required") == "not_required":
|
||||
task.normal_review_status = "not_ready"
|
||||
task.is_aqmm_task = getattr(template, "is_aqmm_task", False)
|
||||
task.aqmm_mandatory = getattr(template, "aqmm_mandatory", False)
|
||||
task.aqmm_evidence_required = getattr(template, "aqmm_evidence_required", False)
|
||||
@@ -465,6 +497,9 @@ def sync_open_engagement_tasks_for_service(
|
||||
response_type=(getattr(template, "response_type", "NONE") or "NONE").upper(),
|
||||
evidence_required=getattr(template, "evidence_required", False),
|
||||
remarks_required_if_no=getattr(template, "remarks_required_if_no", False),
|
||||
normal_review_required=bool(getattr(template, "requires_review", False)),
|
||||
normal_review_role=normal_review_role_for_template(template),
|
||||
normal_review_status="not_ready" if getattr(template, "requires_review", False) else "not_required",
|
||||
is_aqmm_task=getattr(template, "is_aqmm_task", False),
|
||||
aqmm_mandatory=getattr(template, "aqmm_mandatory", False),
|
||||
aqmm_evidence_required=getattr(template, "aqmm_evidence_required", False),
|
||||
@@ -1323,6 +1358,11 @@ def submit_task_for_review(db: Session, *, task: ClientServiceTaskInstance, note
|
||||
now = datetime.now(timezone.utc)
|
||||
task.submitted_for_review_by_user_id = user_id
|
||||
task.submitted_for_review_at_utc = now
|
||||
if getattr(task, "normal_review_required", False):
|
||||
task.normal_review_status = "pending"
|
||||
task.normal_review_note = None
|
||||
task.normal_reviewed_by_user_id = None
|
||||
task.normal_reviewed_at_utc = None
|
||||
if getattr(task, "aqmm_manager_review_required", False) and task.manager_review_status != "reviewed":
|
||||
task.manager_review_status = "pending"
|
||||
if getattr(task, "aqmm_partner_review_required", False) and task.partner_review_status != "reviewed":
|
||||
@@ -1339,6 +1379,53 @@ def submit_task_for_review(db: Session, *, task: ClientServiceTaskInstance, note
|
||||
recalculate_task_aqmm_status(db, task)
|
||||
|
||||
|
||||
|
||||
def apply_normal_task_review(
|
||||
db: Session,
|
||||
*,
|
||||
task: ClientServiceTaskInstance,
|
||||
decision: str,
|
||||
note: str,
|
||||
user_id: int,
|
||||
) -> None:
|
||||
if getattr(task, "is_locked", False) or getattr(getattr(task, "subscription", None), "is_locked", False):
|
||||
return
|
||||
if not getattr(task, "normal_review_required", False):
|
||||
raise ValueError("Normal review is not required for this task.")
|
||||
clean_decision = (decision or "reviewed").strip().lower()
|
||||
if clean_decision not in {"reviewed", "rework_required"}:
|
||||
clean_decision = "reviewed"
|
||||
clean_note = (note or "").strip()
|
||||
if clean_decision == "rework_required" and not clean_note:
|
||||
raise ValueError("Rework reason is required.")
|
||||
now = datetime.now(timezone.utc)
|
||||
task.normal_review_status = clean_decision
|
||||
task.normal_review_note = clean_note or task.normal_review_note
|
||||
task.normal_reviewed_by_user_id = user_id
|
||||
task.normal_reviewed_at_utc = now
|
||||
if clean_decision == "rework_required":
|
||||
task.rework_status = "open"
|
||||
task.rework_reason = clean_note
|
||||
task.rework_requested_by_user_id = user_id
|
||||
task.rework_requested_at_utc = now
|
||||
task.rework_resolved_at_utc = None
|
||||
task.status = "blocked"
|
||||
comment_type = "rework_note"
|
||||
else:
|
||||
if getattr(task, "rework_status", "none") == "open":
|
||||
task.rework_status = "resolved"
|
||||
task.rework_resolved_at_utc = now
|
||||
comment_type = "manager_review_note" if (getattr(task, "normal_review_role", "") or "").startswith("manager") else "partner_review_note"
|
||||
task.updated_by_user_id = user_id
|
||||
_append_system_task_comment(
|
||||
db,
|
||||
task=task,
|
||||
comment_type=comment_type,
|
||||
message=clean_note or ("Normal review approved." if clean_decision == "reviewed" else clean_note),
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
|
||||
def apply_task_review(
|
||||
db: Session,
|
||||
*,
|
||||
|
||||
@@ -114,6 +114,7 @@ class ServiceDefaultTaskTemplate(CommonBase):
|
||||
eligible_role_names: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||
is_mandatory: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||||
requires_review: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
||||
normal_review_role: Mapped[str | None] = mapped_column(String(30), nullable=True)
|
||||
|
||||
# AQMM task tags. These flags allow the existing service checklist to become
|
||||
# the engagement quality checklist for assurance engagements, without creating
|
||||
@@ -183,6 +184,7 @@ class FirmServiceTaskTemplate(CommonBase):
|
||||
eligible_role_names: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||
is_mandatory: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||||
requires_review: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
||||
normal_review_role: Mapped[str | None] = mapped_column(String(30), nullable=True)
|
||||
|
||||
# AQMM task tags copied into generated ClientServiceTaskInstance rows.
|
||||
is_aqmm_task: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, index=True)
|
||||
@@ -783,6 +785,14 @@ class ClientServiceTaskInstance(CommonBase):
|
||||
submitted_for_review_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True, index=True)
|
||||
submitted_for_review_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# Normal operational review is intentionally separate from AQMM review.
|
||||
normal_review_required: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
|
||||
normal_review_role: Mapped[str | None] = mapped_column(String(30), nullable=True, index=True)
|
||||
normal_review_status: Mapped[str] = mapped_column(String(30), nullable=False, default="not_required", index=True)
|
||||
normal_review_note: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
normal_reviewed_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
|
||||
normal_reviewed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
manager_review_status: Mapped[str] = mapped_column(String(30), nullable=False, default="not_required", index=True)
|
||||
manager_review_note: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
manager_reviewed_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True, index=True)
|
||||
|
||||
@@ -56,6 +56,14 @@
|
||||
<input type="checkbox" name="requires_review" {% if task.requires_review %}checked{% endif %}>
|
||||
Review
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-2">
|
||||
<span>Normal reviewer</span>
|
||||
<select name="normal_review_role" class="rounded-lg border border-slate-300 px-2 py-1 text-xs">
|
||||
<option value="manager" {% if (task.normal_review_role or 'manager') == 'manager' %}selected{% endif %}>Manager</option>
|
||||
<option value="partner" {% if task.normal_review_role == 'partner' %}selected{% endif %}>Partner</option>
|
||||
<option value="manager_or_partner" {% if task.normal_review_role == 'manager_or_partner' %}selected{% endif %}>Manager / Partner</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-2">
|
||||
<input type="checkbox" name="is_active" {% if task.is_active %}checked{% endif %}>
|
||||
Active
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="mt-1 text-xs text-slate-500">
|
||||
Role: {{ task.default_role_name or '-' }} ·
|
||||
Mandatory: {{ 'Yes' if task.is_mandatory else 'No' }} ·
|
||||
Review: {{ 'Yes' if task.requires_review else 'No' }} · AQMM: {{ 'Yes' if task.is_aqmm_task else 'No' }}
|
||||
Review: {{ ((task.normal_review_role or 'manager').replace('_',' ').title()) if task.requires_review else 'No' }} · AQMM: {{ 'Yes' if task.is_aqmm_task else 'No' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -44,7 +44,7 @@
|
||||
<div><label class="mb-2 block text-sm font-medium text-slate-700">Task Name</label><input type="text" name="task_name" required class="w-full rounded-xl border border-slate-300 px-4 py-2 text-sm"></div>
|
||||
<div><label class="mb-2 block text-sm font-medium text-slate-700">Default Role</label><input type="text" name="default_role_name" class="w-full rounded-xl border border-slate-300 px-4 py-2 text-sm"></div>
|
||||
<div><label class="mb-2 block text-sm font-medium text-slate-700">Sequence No</label><input type="number" min="1" name="sequence_no" class="w-full rounded-xl border border-slate-300 px-4 py-2 text-sm"></div>
|
||||
<div class="flex items-center gap-6 pt-7 text-sm text-slate-700"><label class="inline-flex items-center gap-2"><input type="checkbox" name="is_mandatory" checked> Mandatory</label><label class="inline-flex items-center gap-2"><input type="checkbox" name="requires_review"> Review</label><label class="inline-flex items-center gap-2"><input type="checkbox" name="is_active" checked> Active</label></div>
|
||||
<div class="flex items-center gap-6 pt-7 text-sm text-slate-700"><label class="inline-flex items-center gap-2"><input type="checkbox" name="is_mandatory" checked> Mandatory</label><label class="inline-flex items-center gap-2"><input type="checkbox" name="requires_review"> Review</label><label class="inline-flex items-center gap-2">Normal reviewer <select name="normal_review_role" class="rounded border border-slate-300 px-2 py-1 text-xs"><option value="manager">Manager</option><option value="partner">Partner</option><option value="manager_or_partner">Manager / Partner</option></select></label><label class="inline-flex items-center gap-2"><input type="checkbox" name="is_active" checked> Active</label></div>
|
||||
<div class="md:col-span-2"><label class="mb-2 block text-sm font-medium text-slate-700">Description</label><textarea name="description" rows="4" class="w-full rounded-xl border border-slate-300 px-4 py-2 text-sm"></textarea></div>
|
||||
<div class="md:col-span-2 rounded-2xl border border-indigo-200 bg-indigo-50 p-4">
|
||||
<div class="text-sm font-semibold text-indigo-950">AQMM / Quality Control Tagging</div>
|
||||
|
||||
@@ -56,6 +56,14 @@
|
||||
<input type="checkbox" name="requires_review" {% if task.requires_review %}checked{% endif %}>
|
||||
Review
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-2">
|
||||
<span>Normal reviewer</span>
|
||||
<select name="normal_review_role" class="rounded-lg border border-slate-300 px-2 py-1 text-xs">
|
||||
<option value="manager" {% if (task.normal_review_role or 'manager') == 'manager' %}selected{% endif %}>Manager</option>
|
||||
<option value="partner" {% if task.normal_review_role == 'partner' %}selected{% endif %}>Partner</option>
|
||||
<option value="manager_or_partner" {% if task.normal_review_role == 'manager_or_partner' %}selected{% endif %}>Manager / Partner</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-2">
|
||||
<input type="checkbox" name="is_active" {% if task.is_active %}checked{% endif %}>
|
||||
Active
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
<label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Options</label>
|
||||
<div class="flex flex-wrap gap-3 rounded-xl border border-slate-200 px-3 py-2 text-xs text-slate-700">
|
||||
<label class="inline-flex items-center gap-1"><input type="checkbox" name="is_mandatory" checked> Mandatory</label>
|
||||
<label class="inline-flex items-center gap-1"><input type="checkbox" name="requires_review"> Review</label>
|
||||
<label class="inline-flex items-center gap-1"><input type="checkbox" name="requires_review"> Review</label><label class="inline-flex items-center gap-1">Normal reviewer <select name="normal_review_role" class="rounded border border-slate-300 px-1 py-0.5"><option value="manager">Manager</option><option value="partner">Partner</option><option value="manager_or_partner">Manager / Partner</option></select></label>
|
||||
<label class="inline-flex items-center gap-1"><input type="checkbox" name="is_active" checked> Active</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -165,7 +165,7 @@
|
||||
<td class="px-4 py-3 text-xs text-slate-600">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{% if task.is_mandatory %}<span class="rounded-full bg-slate-100 px-2 py-1">Mandatory</span>{% endif %}
|
||||
{% if task.requires_review %}<span class="rounded-full bg-amber-100 px-2 py-1 text-amber-800">Review</span>{% endif %}
|
||||
{% if task.requires_review %}<span class="rounded-full bg-amber-100 px-2 py-1 text-amber-800">Review: {{ (task.normal_review_role or "manager").replace("_"," ").title() }}</span>{% endif %}
|
||||
{% if task.is_aqmm_task %}<span class="rounded-full bg-indigo-100 px-2 py-1 text-indigo-800">AQMM</span>{% endif %}
|
||||
{% if task.aqmm_mandatory %}<span class="rounded-full bg-rose-100 px-2 py-1 text-rose-800">AQMM Mandatory</span>{% endif %}
|
||||
{% if task.aqmm_evidence_required %}<span class="rounded-full bg-sky-100 px-2 py-1 text-sky-800">Evidence</span>{% endif %}
|
||||
|
||||
@@ -138,6 +138,15 @@ def _validated_registration_type_code(db, value: str, *, existing_value: str | N
|
||||
raise ValueError("registration_type")
|
||||
|
||||
|
||||
def _normal_review_role_value(value: str, *, requires_review: bool) -> str | None:
|
||||
if not requires_review:
|
||||
return None
|
||||
clean = (value or "").strip().lower()
|
||||
if clean in {"manager", "partner", "manager_or_partner"}:
|
||||
return clean
|
||||
return "manager"
|
||||
|
||||
|
||||
def _redirect_denied():
|
||||
from app.core.http_responses import ui_access_denied
|
||||
return ui_access_denied()
|
||||
@@ -948,6 +957,7 @@ def _copy_system_defaults_if_firm_tasks_empty(
|
||||
eligible_role_names=getattr(default, "eligible_role_names", None) or default.default_role_name,
|
||||
is_mandatory=default.is_mandatory,
|
||||
requires_review=default.requires_review,
|
||||
normal_review_role=getattr(default, "normal_review_role", None),
|
||||
is_aqmm_task=getattr(default, "is_aqmm_task", False),
|
||||
aqmm_mandatory=getattr(default, "aqmm_mandatory", False),
|
||||
aqmm_evidence_required=getattr(default, "aqmm_evidence_required", False),
|
||||
@@ -1241,7 +1251,7 @@ def task_templates_detail(request: Request, catalogue_id: int):
|
||||
|
||||
|
||||
@router.post('/templates/{catalogue_id}/tasks/new')
|
||||
def task_template_create_submit(request: Request, catalogue_id: int, task_name: str = Form(...), description: str = Form(''), default_role_name: str = Form(''), eligible_roles: list[str] = Form([]), sequence_no: int | None = Form(None), is_mandatory: str | None = Form(None), requires_review: str | None = Form(None), task_category: str = Form(''), response_required: str | None = Form(None), response_type: str = Form('NONE'), evidence_required: str | None = Form(None), remarks_required_if_no: str | None = Form(None), is_aqmm_task: str | None = Form(None), aqmm_mandatory: str | None = Form(None), aqmm_evidence_required: str | None = Form(None), aqmm_manager_review_required: str | None = Form(None), aqmm_partner_review_required: str | None = Form(None), aqmm_review_partner_required: str | None = Form(None), aqmm_blocks_final_release: str | None = Form(None), aqmm_reference: str = Form(''), is_active: str | None = Form(None), csrf_token: str = Form(...)):
|
||||
def task_template_create_submit(request: Request, catalogue_id: int, task_name: str = Form(...), description: str = Form(''), default_role_name: str = Form(''), eligible_roles: list[str] = Form([]), sequence_no: int | None = Form(None), is_mandatory: str | None = Form(None), requires_review: str | None = Form(None), normal_review_role: str = Form('manager'), task_category: str = Form(''), response_required: str | None = Form(None), response_type: str = Form('NONE'), evidence_required: str | None = Form(None), remarks_required_if_no: str | None = Form(None), is_aqmm_task: str | None = Form(None), aqmm_mandatory: str | None = Form(None), aqmm_evidence_required: str | None = Form(None), aqmm_manager_review_required: str | None = Form(None), aqmm_partner_review_required: str | None = Form(None), aqmm_review_partner_required: str | None = Form(None), aqmm_blocks_final_release: str | None = Form(None), aqmm_reference: str = Form(''), is_active: str | None = Form(None), csrf_token: str = Form(...)):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
@@ -1267,6 +1277,7 @@ def task_template_create_submit(request: Request, catalogue_id: int, task_name:
|
||||
sequence_no=sequence_no or next_task_sequence(db, tenant_id=tenant_id, catalogue_id=catalogue_id),
|
||||
is_mandatory=is_mandatory is not None,
|
||||
requires_review=requires_review is not None,
|
||||
normal_review_role=_normal_review_role_value(normal_review_role, requires_review=requires_review is not None),
|
||||
task_category=task_category.strip() or None,
|
||||
response_required=response_required is not None,
|
||||
response_type=(response_type.strip().upper() or "NONE"),
|
||||
@@ -1351,7 +1362,7 @@ def default_templates_detail(request: Request, catalogue_id: int):
|
||||
|
||||
|
||||
@router.post('/catalogue/{catalogue_id}/defaults/new')
|
||||
def default_template_create_submit(request: Request, catalogue_id: int, task_name: str = Form(...), description: str = Form(''), default_role_name: str = Form(''), sequence_no: int | None = Form(None), is_mandatory: str | None = Form(None), requires_review: str | None = Form(None), task_category: str = Form(''), response_required: str | None = Form(None), response_type: str = Form('NONE'), evidence_required: str | None = Form(None), remarks_required_if_no: str | None = Form(None), is_aqmm_task: str | None = Form(None), aqmm_mandatory: str | None = Form(None), aqmm_evidence_required: str | None = Form(None), aqmm_manager_review_required: str | None = Form(None), aqmm_partner_review_required: str | None = Form(None), aqmm_review_partner_required: str | None = Form(None), aqmm_blocks_final_release: str | None = Form(None), aqmm_reference: str = Form(''), is_active: str | None = Form(None), csrf_token: str = Form(...)):
|
||||
def default_template_create_submit(request: Request, catalogue_id: int, task_name: str = Form(...), description: str = Form(''), default_role_name: str = Form(''), sequence_no: int | None = Form(None), is_mandatory: str | None = Form(None), requires_review: str | None = Form(None), normal_review_role: str = Form('manager'), task_category: str = Form(''), response_required: str | None = Form(None), response_type: str = Form('NONE'), evidence_required: str | None = Form(None), remarks_required_if_no: str | None = Form(None), is_aqmm_task: str | None = Form(None), aqmm_mandatory: str | None = Form(None), aqmm_evidence_required: str | None = Form(None), aqmm_manager_review_required: str | None = Form(None), aqmm_partner_review_required: str | None = Form(None), aqmm_review_partner_required: str | None = Form(None), aqmm_blocks_final_release: str | None = Form(None), aqmm_reference: str = Form(''), is_active: str | None = Form(None), csrf_token: str = Form(...)):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
@@ -1364,7 +1375,7 @@ def default_template_create_submit(request: Request, catalogue_id: int, task_nam
|
||||
catalogue = get_catalogue(db, catalogue_id)
|
||||
if not catalogue:
|
||||
return RedirectResponse(url='/services/defaults', status_code=303)
|
||||
row = ServiceDefaultTaskTemplate(service_catalogue_id=catalogue_id, task_name=task_name.strip(), description=description.strip() or None, default_role_name=default_role_name.strip() or None, sequence_no=sequence_no or next_default_task_sequence(db, catalogue_id=catalogue_id), is_mandatory=is_mandatory is not None, requires_review=requires_review is not None, task_category=task_category.strip() or None, response_required=response_required is not None, response_type=(response_type.strip().upper() or "NONE"), evidence_required=evidence_required is not None, remarks_required_if_no=remarks_required_if_no is not None, is_aqmm_task=is_aqmm_task is not None, aqmm_mandatory=aqmm_mandatory is not None, aqmm_evidence_required=aqmm_evidence_required is not None, aqmm_manager_review_required=aqmm_manager_review_required is not None, aqmm_partner_review_required=aqmm_partner_review_required is not None, aqmm_review_partner_required=aqmm_review_partner_required is not None, aqmm_blocks_final_release=aqmm_blocks_final_release is not None, aqmm_reference=aqmm_reference.strip() or None, is_active=is_active is not None)
|
||||
row = ServiceDefaultTaskTemplate(service_catalogue_id=catalogue_id, task_name=task_name.strip(), description=description.strip() or None, default_role_name=default_role_name.strip() or None, sequence_no=sequence_no or next_default_task_sequence(db, catalogue_id=catalogue_id), is_mandatory=is_mandatory is not None, requires_review=requires_review is not None, normal_review_role=_normal_review_role_value(normal_review_role, requires_review=requires_review is not None), task_category=task_category.strip() or None, response_required=response_required is not None, response_type=(response_type.strip().upper() or "NONE"), evidence_required=evidence_required is not None, remarks_required_if_no=remarks_required_if_no is not None, is_aqmm_task=is_aqmm_task is not None, aqmm_mandatory=aqmm_mandatory is not None, aqmm_evidence_required=aqmm_evidence_required is not None, aqmm_manager_review_required=aqmm_manager_review_required is not None, aqmm_partner_review_required=aqmm_partner_review_required is not None, aqmm_review_partner_required=aqmm_review_partner_required is not None, aqmm_blocks_final_release=aqmm_blocks_final_release is not None, aqmm_reference=aqmm_reference.strip() or None, is_active=is_active is not None)
|
||||
db.add(row); db.commit()
|
||||
return RedirectResponse(url=f'/services/catalogue/{catalogue_id}/defaults', status_code=303)
|
||||
finally:
|
||||
@@ -1403,6 +1414,7 @@ def copy_defaults_to_firm(request: Request, catalogue_id: int, csrf_token: str =
|
||||
default_role_name=d.default_role_name,
|
||||
is_mandatory=d.is_mandatory,
|
||||
requires_review=d.requires_review,
|
||||
normal_review_role=getattr(d, "normal_review_role", None),
|
||||
task_category=getattr(d, "task_category", None),
|
||||
response_required=getattr(d, "response_required", False),
|
||||
response_type=getattr(d, "response_type", "NONE") or "NONE",
|
||||
@@ -1707,6 +1719,7 @@ def firm_task_template_edit_submit(
|
||||
sequence_no: int = Form(1),
|
||||
is_mandatory: str | None = Form(None),
|
||||
requires_review: str | None = Form(None),
|
||||
normal_review_role: str = Form('manager'),
|
||||
task_category: str = Form(''),
|
||||
response_required: str | None = Form(None),
|
||||
response_type: str = Form('NONE'),
|
||||
@@ -1753,6 +1766,7 @@ def firm_task_template_edit_submit(
|
||||
task.sequence_no = sequence_no
|
||||
task.is_mandatory = is_mandatory is not None
|
||||
task.requires_review = requires_review is not None
|
||||
task.normal_review_role = _normal_review_role_value(normal_review_role, requires_review=task.requires_review)
|
||||
task.task_category = task_category.strip() or None
|
||||
task.response_required = response_required is not None
|
||||
task.response_type = response_type.strip().upper() or "NONE"
|
||||
@@ -1849,6 +1863,7 @@ def default_task_template_edit_submit(
|
||||
sequence_no: int = Form(1),
|
||||
is_mandatory: str | None = Form(None),
|
||||
requires_review: str | None = Form(None),
|
||||
normal_review_role: str = Form('manager'),
|
||||
task_category: str = Form(''),
|
||||
response_required: str | None = Form(None),
|
||||
response_type: str = Form('NONE'),
|
||||
@@ -1895,6 +1910,7 @@ def default_task_template_edit_submit(
|
||||
task.sequence_no = sequence_no
|
||||
task.is_mandatory = is_mandatory is not None
|
||||
task.requires_review = requires_review is not None
|
||||
task.normal_review_role = _normal_review_role_value(normal_review_role, requires_review=task.requires_review)
|
||||
task.task_category = task_category.strip() or None
|
||||
task.response_required = response_required is not None
|
||||
task.response_type = response_type.strip().upper() or "NONE"
|
||||
|
||||
Reference in New Issue
Block a user