Files
training-software/training/admin.py
Paperclip CTO 87cbf23a9d
Some checks failed
CI / Tests (Python 3.12) (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / OpenAPI Schema (push) Has been cancelled
feat(TRA-241): training modes and trainer signoff state machine
- TrainingRecord model with completion_mode (online/offline/blended) and CompletionStatus state machine
- TrainerSignoff model with decision, notes, trainer FK, and audit timestamp
- SignoffEvidence model for uploaded proof files
- services.py state transitions:
  - mark_in_progress: not_started → in_progress
  - mark_online_passed: online → completed; blended → pending_signoff
  - submit_trainer_signoff: offline/blended approved → completed; rejected → in_progress
  - InvalidTransitionError on illegal state moves
- IsTrainer permission class based on training:signoff capability
- API: record detail, start, mark-online-passed, trainer-signoff, pending-signoff list
- 20 unit + integration tests covering all mode paths, invalid transitions, and access control
- Blended completion requires both online pass AND trainer approval

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-07 09:20:34 +02:00

30 lines
863 B
Python

from django.contrib import admin
from .models import SignoffEvidence, TrainerSignoff, TrainingRecord
class TrainerSignoffInline(admin.TabularInline):
model = TrainerSignoff
extra = 0
readonly_fields = ("signed_off_at",)
class SignoffEvidenceInline(admin.TabularInline):
model = SignoffEvidence
extra = 0
readonly_fields = ("uploaded_at",)
@admin.register(TrainingRecord)
class TrainingRecordAdmin(admin.ModelAdmin):
list_display = ("id", "enrollment", "completion_mode", "status", "completed_at")
list_filter = ("completion_mode", "status")
inlines = [TrainerSignoffInline, SignoffEvidenceInline]
@admin.register(TrainerSignoff)
class TrainerSignoffAdmin(admin.ModelAdmin):
list_display = ("training_record", "trainer", "decision", "signed_off_at")
list_filter = ("decision",)
raw_id_fields = ("trainer",)