187 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from django.contrib import admin
 | 
						|
from simple_history.admin import SimpleHistoryAdmin
 | 
						|
from django.utils.html import format_html
 | 
						|
from django.utils.safestring import mark_safe
 | 
						|
from .models import Process, ProcessStep, ProcessInstance, StepInstance, StepDependency, StepRejection, StepApproverRequirement, StepApproval
 | 
						|
 | 
						|
@admin.register(Process)
 | 
						|
class ProcessAdmin(SimpleHistoryAdmin):
 | 
						|
    list_display = ['name', 'is_active', 'created_by', 'created', 'steps_count']
 | 
						|
    list_filter = ['is_active', 'created']
 | 
						|
    search_fields = ['name', 'description', 'created_by__username']
 | 
						|
    prepopulated_fields = {'slug': ('name',)}
 | 
						|
    readonly_fields = ['deleted_at', 'created', 'updated']
 | 
						|
    
 | 
						|
    def steps_count(self, obj):
 | 
						|
        return obj.steps.count()
 | 
						|
    steps_count.short_description = "تعداد مراحل"
 | 
						|
 | 
						|
@admin.register(ProcessStep)
 | 
						|
class ProcessStepAdmin(SimpleHistoryAdmin):
 | 
						|
    list_display = ['name', 'process', 'order', 'is_required', 'dependencies_display', 'blocks_previous', 'can_go_back']
 | 
						|
    list_filter = ['process', 'is_required', 'blocks_previous', 'can_go_back']
 | 
						|
    search_fields = ['name', 'process__name', 'description']
 | 
						|
    prepopulated_fields = {'slug': ('name',)}
 | 
						|
    readonly_fields = ['deleted_at']
 | 
						|
    ordering = ['process', 'order']
 | 
						|
 | 
						|
    def dependencies_display(self, obj):
 | 
						|
        dependencies = obj.get_dependencies()
 | 
						|
        if dependencies:
 | 
						|
            dependency_names = ProcessStep.objects.filter(id__in=dependencies).values_list('name', flat=True)
 | 
						|
            return ", ".join(dependency_names)
 | 
						|
        return "بدون وابستگی"
 | 
						|
    dependencies_display.short_description = "وابسته به"
 | 
						|
 | 
						|
@admin.register(StepDependency)
 | 
						|
class StepDependencyAdmin(admin.ModelAdmin):
 | 
						|
    list_display = ['dependent_step', 'dependency_step', 'process_display', 'created_at']
 | 
						|
    list_filter = ['dependent_step__process', 'created_at']
 | 
						|
    search_fields = ['dependent_step__name', 'dependency_step__name']
 | 
						|
    ordering = ['dependent_step__process', 'dependent_step__order']
 | 
						|
 | 
						|
    def process_display(self, obj):
 | 
						|
        return obj.dependent_step.process.name
 | 
						|
    process_display.short_description = "فرآیند"
 | 
						|
 | 
						|
@admin.register(ProcessInstance)
 | 
						|
class ProcessInstanceAdmin(SimpleHistoryAdmin):
 | 
						|
    verbose_name = "درخواست"
 | 
						|
    verbose_name_plural = "درخواستها"
 | 
						|
    list_display = [
 | 
						|
        'code',
 | 
						|
        'current_step',
 | 
						|
        'slug', 
 | 
						|
        'well_display', 
 | 
						|
        'representative', 
 | 
						|
        'requester', 
 | 
						|
        'broker', 
 | 
						|
        'process', 
 | 
						|
        'status_display', 
 | 
						|
        'priority_display', 
 | 
						|
        'created', 
 | 
						|
        'progress_display'
 | 
						|
    ]
 | 
						|
    list_filter = [
 | 
						|
        'process', 
 | 
						|
        'status', 
 | 
						|
        'priority',
 | 
						|
        'created',
 | 
						|
        'well__representative',
 | 
						|
        'broker'
 | 
						|
    ]
 | 
						|
    search_fields = [
 | 
						|
        'code',
 | 
						|
        'slug', 
 | 
						|
        'process__name', 
 | 
						|
        'requester__username', 
 | 
						|
        'requester__first_name',
 | 
						|
        'well__water_subscription_number',
 | 
						|
        'representative__username'
 | 
						|
    ]
 | 
						|
    readonly_fields = [
 | 
						|
        'deleted_at', 
 | 
						|
        'created', 
 | 
						|
        'updated',
 | 
						|
        'completed_at'
 | 
						|
    ]
 | 
						|
    autocomplete_fields = [
 | 
						|
        'well', 
 | 
						|
        'representative', 
 | 
						|
        'requester', 
 | 
						|
        'broker',
 | 
						|
        'process', 
 | 
						|
        'current_step'
 | 
						|
    ]
 | 
						|
    ordering = ['-created']
 | 
						|
    
 | 
						|
    fieldsets = (
 | 
						|
        ('اطلاعات اصلی', {
 | 
						|
            'fields': ('code', 'slug', 'description', 'process')
 | 
						|
        }),
 | 
						|
        ('اطلاعات چاه', {
 | 
						|
            'fields': ('well', 'representative')
 | 
						|
        }),
 | 
						|
        ('اطلاعات درخواست', {
 | 
						|
            'fields': ('requester', 'broker', 'priority')
 | 
						|
        }),
 | 
						|
        ('وضعیت و پیشرفت', {
 | 
						|
            'fields': ('status', 'current_step')
 | 
						|
        }),
 | 
						|
        ('تاریخها', {
 | 
						|
            'fields': ('created', 'updated', 'completed_at'),
 | 
						|
            'classes': ('collapse',)
 | 
						|
        }),
 | 
						|
    )
 | 
						|
 | 
						|
    def well_display(self, obj):
 | 
						|
        if obj.well:
 | 
						|
            return f"{obj.well.water_subscription_number}"
 | 
						|
        return "-"
 | 
						|
    well_display.short_description = "چاه"
 | 
						|
 | 
						|
    def status_display(self, obj):
 | 
						|
        return mark_safe(obj.get_status_display_with_color())
 | 
						|
    status_display.short_description = "وضعیت"
 | 
						|
 | 
						|
    def priority_display(self, obj):
 | 
						|
        return mark_safe(obj.get_priority_display_with_color())
 | 
						|
    priority_display.short_description = "اولویت"
 | 
						|
 | 
						|
    def progress_display(self, obj):
 | 
						|
        if obj.process:
 | 
						|
            total_steps = obj.process.steps.count()
 | 
						|
            completed_steps = obj.step_instances.filter(status='completed').count()
 | 
						|
            percentage = (completed_steps / total_steps * 100) if total_steps > 0 else 0
 | 
						|
            percentage_int = int(percentage)
 | 
						|
            return format_html(
 | 
						|
                '<div class="progress" style="width: 100px;"><div class="progress-bar" style="width: {}%">{}/{} ({}%)</div></div>',
 | 
						|
                percentage_int, completed_steps, total_steps, percentage_int
 | 
						|
            )
 | 
						|
        return "-"
 | 
						|
    progress_display.short_description = "پیشرفت"
 | 
						|
 | 
						|
@admin.register(StepInstance)
 | 
						|
class StepInstanceAdmin(SimpleHistoryAdmin):
 | 
						|
    list_display = ['process_instance', 'process_instance__code', 'step', 'assigned_to', 'status_display', 'rejection_count', 'edit_count', 'started_at', 'completed_at']
 | 
						|
    list_filter = ['status', 'step__process', 'started_at']
 | 
						|
    search_fields = ['process_instance__name', 'process_instance__code', 'step__name', 'assigned_to__username']
 | 
						|
    readonly_fields = ['started_at', 'completed_at']
 | 
						|
    ordering = ['process_instance', 'step__order']
 | 
						|
 | 
						|
    def status_display(self, obj):
 | 
						|
        return mark_safe(obj.get_status_display_with_color())
 | 
						|
    status_display.short_description = "وضعیت"
 | 
						|
 | 
						|
    def rejection_count(self, obj):
 | 
						|
        count = obj.get_rejection_count()
 | 
						|
        if count > 0:
 | 
						|
            return format_html('<span class="badge bg-danger">{}</span>', count)
 | 
						|
        return format_html('<span class="badge bg-success">0</span>')
 | 
						|
    rejection_count.short_description = "تعداد رد شدنها"
 | 
						|
 | 
						|
@admin.register(StepRejection)
 | 
						|
class StepRejectionAdmin(SimpleHistoryAdmin):
 | 
						|
    list_display = ['step_instance', 'role', 'rejected_by', 'reason_short', 'created_at', 'is_deleted']
 | 
						|
    list_filter = ['role', 'rejected_by', 'created_at', 'step_instance__step__process']
 | 
						|
    search_fields = ['step_instance__step__name', 'rejected_by__username', 'reason', 'role__name']
 | 
						|
    readonly_fields = ['created_at']
 | 
						|
    ordering = ['-created_at']
 | 
						|
 | 
						|
    def reason_short(self, obj):
 | 
						|
        return obj.reason[:50] + "..." if len(obj.reason) > 50 else obj.reason
 | 
						|
    reason_short.short_description = "دلیل رد شدن"
 | 
						|
 | 
						|
 | 
						|
@admin.register(StepApproverRequirement)
 | 
						|
class StepApproverRequirementAdmin(admin.ModelAdmin):
 | 
						|
    list_display = ("step", "role", "required_count")
 | 
						|
    list_filter = ("step__process", "role")
 | 
						|
    search_fields = ("step__name", "role__name")
 | 
						|
 | 
						|
 | 
						|
@admin.register(StepApproval)
 | 
						|
class StepApprovalAdmin(admin.ModelAdmin):
 | 
						|
    list_display = ("step_instance", "role", "approved_by", "created_at", "is_deleted")
 | 
						|
    list_filter = ("role", "step_instance__step__process")
 | 
						|
    search_fields = ("step_instance__process_instance__code", "role__name", "approved_by__username")
 |