File size: 5,218 Bytes
b4f2238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
from __future__ import annotations

from typing import TYPE_CHECKING, ClassVar, cast

from django.contrib import admin
from django.http import HttpRequest

from apps.cases.admin.base_admin import BaseModelAdmin, BaseStackedInline, BaseTabularInline
from apps.cases.admin.case_chat_admin import CaseChatInline
from apps.cases.admin.case_forms_admin import CaseAdminForm, SupervisingAuthorityInlineForm
from apps.cases.admin.mixins import (
    CaseAdminActionsMixin,
    CaseAdminSaveMixin,
    CaseAdminServiceMixin,
    CaseAdminViewsMixin,
)
from apps.cases.models import (
    Case,
    CaseAssignment,
    CaseLog,
    CaseLogAttachment,
    CaseNumber,
    CaseParty,
    SupervisingAuthority,
)
from apps.core.admin.mixins import AdminImportExportMixin

if TYPE_CHECKING:
    from django.db.models import QuerySet


class CasePartyInline(BaseTabularInline):
    """案件当事人内联编辑组件"""

    model = CaseParty
    extra = 1
    fields = ("client", "legal_status")
    classes = ["contract-party-inline"]

    class Media:
        js = (
            "cases/admin_caseparty.js",
            "cases/admin_case_form.js",
        )
        css: ClassVar[dict[str, tuple[str, ...]]] = {"all": ("cases/admin_caseparty.css",)}


class CaseAssignmentInline(BaseTabularInline):
    model = CaseAssignment
    extra = 1


class SupervisingAuthorityInline(BaseTabularInline):
    """主管机关内联"""

    model = SupervisingAuthority
    form = SupervisingAuthorityInlineForm
    extra = 1
    fields = ("name", "authority_type")


class CaseLogAttachmentInline(BaseTabularInline):
    model = CaseLogAttachment
    extra = 0


class CaseNumberInline(BaseStackedInline):
    model = CaseNumber
    extra = 1
    fieldsets = (
        (
            None,
            {
                "fields": (
                    "document_file",
                    ("number", "document_name", "is_active"),
                    "document_content",
                )
            },
        ),
        (
            None,
            {
                "classes": ("case-number-execution-fieldset",),
                "fields": (
                    ("execution_cutoff_date", "execution_paid_amount"),
                    ("execution_use_deduction_order", "execution_year_days", "execution_date_inclusion"),
                    "execution_manual_text",
                ),
            },
        ),
    )


class CaseLogInline(BaseStackedInline):
    model = CaseLog
    extra = 0
    fields = ("content", "created_at")
    exclude = ("actor",)
    readonly_fields = ("created_at",)
    show_change_link = True
    verbose_name = ""
    verbose_name_plural = "日志"

    if BaseModelAdmin is not admin.ModelAdmin:
        pass


def serialize_case_obj(obj: Case) -> dict[str, object]:
    """将单个 Case 实例序列化为 dict(供 CaseAdmin 和 ContractAdmin 共用)。"""
    from apps.cases.services.case.case_export_serializer_service import serialize_case_obj as serialize_case_obj_service

    return cast(dict[str, object], serialize_case_obj_service(obj))


@admin.register(Case)
class CaseAdmin(
    CaseAdminActionsMixin,
    CaseAdminSaveMixin,
    CaseAdminViewsMixin,
    CaseAdminServiceMixin,
    AdminImportExportMixin,
    BaseModelAdmin,
):
    form = CaseAdminForm
    list_display = ("id_link", "name_link", "status", "start_date", "effective_date", "is_archived")
    list_display_links = None
    list_filter = ("status", "is_archived")
    search_fields = ("name",)
    change_form_template = "admin/cases/case/change_form.html"
    readonly_fields = ("filing_number",)
    export_model_name = "case"
    import_required_fields = ("name",)
    actions = ["create_feishu_chat_for_selected_cases", "export_selected_as_json", "export_all_as_json"]

    class Media:
        js = (
            "cases/admin_case_form.js",
            "cases/js/autocomplete.js",
            "cases/js/autocomplete_init.js",
            "cases/js/case_log_sort.js",
            "cases/js/litigation_fee.js",
        )
        css = {"all": ("cases/css/case_log_admin.css",)}

    inlines = [
        CasePartyInline,
        CaseAssignmentInline,
        SupervisingAuthorityInline,
        CaseNumberInline,
        CaseLogInline,
        CaseChatInline,
    ]

    def handle_json_import(
        self, data_list: list[dict[str, object]], user: str, zip_file: object
    ) -> tuple[int, int, list[str]]:
        from apps.cases.services.case_import_service import build_case_import_service_for_admin

        case_svc = build_case_import_service_for_admin()
        admin_service = self._get_case_admin_service()
        return cast(
            tuple[int, int, list[str]],
            admin_service.import_cases_from_json_data(data_list, case_import_service=case_svc),
        )

    def serialize_queryset(self, queryset: QuerySet[Case]) -> list[dict[str, object]]:
        service = self._get_case_admin_service()
        return cast(list[dict[str, object]], service.serialize_queryset_for_export(queryset))

    def get_file_paths(self, queryset: QuerySet[Case]) -> list[str]:
        service = self._get_case_admin_service()
        return cast(list[str], service.collect_file_paths_for_export(queryset))