foerderbarometer/input/admin.py

321 lines
9.5 KiB
Python
Raw Normal View History

2020-11-24 12:44:07 +00:00
import csv
2020-09-21 12:27:16 +00:00
from django.contrib import admin
2025-10-17 12:15:56 +00:00
from django.db import models, transaction
2020-11-24 12:44:07 +00:00
from django.http import HttpResponse
2025-10-17 13:14:16 +00:00
from input.utils.mail import send_decision_mails
2025-10-17 12:15:56 +00:00
from .forms import BaseProjectForm
from .models import (
Account,
Project,
ProjectCategory,
ProjectRequest,
ProjectDeclined,
WikimediaProject,
HonoraryCertificate,
Library,
ELiterature,
Software,
IFG,
Travel,
Email,
BusinessCard,
List,
Literature,
2025-10-17 12:15:56 +00:00
TYPE_PROJ,
)
2020-10-06 12:55:46 +00:00
2020-11-24 12:44:07 +00:00
class RequestURLBeforeInternNotesMixin:
"""
Ensures that 'request_url' appears directly before 'intern_notes'.
Works whether 'fields' is explicitly defined or derived from the Model/Form.
"""
def get_fields(self, request, obj=None):
fields = [*super().get_fields(request, obj)]
fields.remove('request_url')
index = fields.index('intern_notes')
2020-11-24 12:44:07 +00:00
fields.insert(index, 'request_url')
return fields
def export_as_csv(self, request, queryset):
2020-11-24 12:44:07 +00:00
meta = self.model._meta
field_names = [field.name for field in meta.fields]
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
writer = csv.writer(response)
writer.writerow(field_names)
for obj in queryset:
row = writer.writerow([getattr(obj, field) for field in field_names])
return response
export_as_csv.short_description = "Ausgewähltes zu CSV exportieren"
2020-11-24 12:44:07 +00:00
admin.site.add_action(export_as_csv)
@admin.register(ProjectCategory, WikimediaProject)
class ProjectCategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'order', 'project_count']
def get_queryset(self, request):
return super().get_queryset(request).annotate(
project_count=models.Count('projects'),
)
@admin.display(description='# Projekte', ordering='project_count')
def project_count(self, obj):
return obj.project_count
class ProjectAdminForm(BaseProjectForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field, model in self.categories.items():
2025-10-17 12:18:20 +00:00
if self.initial.get(f'{field}_other'):
self.initial[field] = [*self.initial[field], model.other]
2025-10-16 14:44:00 +00:00
def clean(self):
cleaned_data = BaseProjectForm.clean(self)
if self.errors:
return cleaned_data
if cleaned_data['granted']:
for field in 'granted_date', 'granted_from', 'account':
if not cleaned_data[field]:
self.add_error(field, 'Dieses Feld ist erforderlich, um dieses Projekt zu bewilligen.')
return cleaned_data
2025-10-17 12:15:56 +00:00
class BaseProjectAdmin(admin.ModelAdmin):
2020-11-19 13:41:31 +00:00
save_as = True
form = ProjectAdminForm
search_fields = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status', 'end_quartal')
list_display = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status', 'end_quartal')
date_hierarchy = 'end'
readonly_fields = ('end_quartal', 'project_of_year', 'pid', 'finance_id')
fieldsets = [
('Kontakt', {'fields': (
'realname',
'email',
)}),
('Projekt', {'fields': (
'name',
'description',
'start',
'end',
'otrs',
'plan',
'page',
'urls',
'group',
'location',
'participants_estimated',
'participants_real',
'insurance',
'insurance_technic',
'support',
'cost',
'categories',
'categories_other',
'wikimedia_projects',
'wikimedia_projects_other',
'notes',
)}),
('Mailing', {'fields': (
'mail_state',
'end_mail_send',
'survey_mail_send',
'survey_mail_date',
)}),
('Bewilligung', {'fields': (
'granted',
'granted_date',
'granted_from',
'intern_notes',
)}),
('Accounting', {'fields': (
'account',
'status',
*readonly_fields,
)}),
]
class Media:
js = ('dropdown/js/otrs_link.js',)
2025-10-17 12:15:56 +00:00
granted: bool
def get_queryset(self, request):
return super().get_queryset(request).filter(granted=self.granted)
2025-10-17 12:15:56 +00:00
@admin.register(Project)
class ProjectAdmin(BaseProjectAdmin):
granted = True
@admin.register(ProjectRequest)
2025-10-17 12:15:56 +00:00
class ProjectRequestAdmin(BaseProjectAdmin):
granted = None
2025-10-17 12:15:56 +00:00
def save_model(self, request, obj: ProjectRequest, form: ProjectAdminForm, change: bool):
super().save_model(request, obj, form, change)
if obj.granted is None:
return None
2025-10-17 13:14:16 +00:00
transaction.on_commit(lambda: send_decision_mails(obj))
2025-10-17 12:15:56 +00:00
return obj.granted
@admin.register(ProjectDeclined)
2025-10-17 12:15:56 +00:00
class ProjectDeclinedAdmin(BaseProjectAdmin):
granted = False
2025-10-17 12:18:20 +00:00
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return False
@admin.register(BusinessCard)
class BusinessCardAdmin(RequestURLBeforeInternNotesMixin, admin.ModelAdmin):
2025-08-19 12:10:15 +00:00
save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date', 'project')
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project', 'terms_accepted')
list_display_links = ('realname', 'service_id')
# action = ['export_as_csv']
date_hierarchy = 'granted_date'
readonly_fields = ['service_id']
class Media:
js = ('dropdown/js/base.js', 'dropdown/js/otrs_link.js')
@admin.register(Literature)
class LiteratureAdmin(RequestURLBeforeInternNotesMixin, admin.ModelAdmin):
save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'terms_accepted')
list_display_links = ('realname', 'service_id')
date_hierarchy = 'granted_date'
readonly_fields = ['service_id']
class Media:
js = ('dropdown/js/otrs_link.js',)
@admin.register(Account)
class AccountAdmin(admin.ModelAdmin):
save_as = True
@admin.register(HonoraryCertificate)
class HonoraryCertificateAdmin(admin.ModelAdmin):
save_as = True
search_fields = ['realname', 'granted', 'project__name', 'project__pid']
list_display = ('realname', 'granted', 'project')
date_hierarchy = 'granted_date'
autocomplete_fields = ['project']
class Media:
js = ('dropdown/js/otrs_link.js',)
@admin.register(Library, ELiterature, Software)
class LibraryAdmin(RequestURLBeforeInternNotesMixin, admin.ModelAdmin):
save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
list_display = ('realname', 'service_id', 'granted', 'granted_date')
list_display_links = ('realname', 'service_id')
date_hierarchy = 'granted_date'
readonly_fields = ['service_id']
exclude = ['type']
class Media:
js = ('dropdown/js/otrs_link.js',)
def get_queryset(self, request):
return super().get_queryset(request).filter(type=self.model.TYPE)
def formfield_for_dbfield(self, db_field, request, **kwargs):
if db_field.name == 'library':
kwargs['label'] = self.model.LIBRARY_LABEL
kwargs['help_text'] = self.model.LIBRARY_HELP_TEXT
elif db_field.name == 'duration':
kwargs['help_text'] = self.model.DURATION_HELP_TEXT
return super().formfield_for_dbfield(db_field, request, **kwargs)
@admin.register(IFG)
class IFGAdmin(RequestURLBeforeInternNotesMixin, admin.ModelAdmin):
save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
list_display = ('realname', 'service_id', 'granted', 'granted_date')
list_display_links = ('realname', 'service_id')
date_hierarchy = 'granted_date'
readonly_fields = ['service_id']
class Media:
js = ('dropdown/js/otrs_link.js',)
@admin.register(Travel)
class TravelAdmin(admin.ModelAdmin):
save_as = True
search_fields = ['realname', 'service_id', 'granted_date', 'project__name', 'project__pid']
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project_end', 'project',
'project_end_quartal')
list_display_links = ('realname', 'project')
date_hierarchy = 'project_end'
autocomplete_fields = ['project']
2025-08-19 12:10:36 +00:00
readonly_fields = ['service_id', 'project_end', 'project_end_quartal']
class Media:
js = ('dropdown/js/otrs_link.js',)
@admin.register(Email)
class EmailAdmin(RequestURLBeforeInternNotesMixin, admin.ModelAdmin):
save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'terms_accepted')
list_display_links = ('realname', 'service_id')
date_hierarchy = 'granted_date'
radio_fields = {'adult': admin.VERTICAL}
readonly_fields = ['service_id']
2023-02-27 17:09:29 +00:00
class Media:
js = ('dropdown/js/base.js', 'dropdown/js/otrs_link.js')
2020-10-06 11:17:28 +00:00
@admin.register(List)
class ListAdmin(RequestURLBeforeInternNotesMixin, admin.ModelAdmin):
save_as = True
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'terms_accepted')
list_display_links = ('realname', 'service_id')
date_hierarchy = 'granted_date'
readonly_fields = ['service_id']