2020-11-24 12:44:07 +00:00
|
|
|
import csv
|
|
|
|
|
|
2020-09-21 12:27:16 +00:00
|
|
|
from django.contrib import admin
|
2025-11-10 11:05:40 +00:00
|
|
|
from django.db import models
|
2020-11-24 12:44:07 +00:00
|
|
|
from django.http import HttpResponse
|
2025-09-28 22:25:16 +00:00
|
|
|
|
2025-11-10 10:03:41 +00:00
|
|
|
from input.utils.list import reorder_value
|
2025-10-17 12:15:56 +00:00
|
|
|
|
2025-10-16 10:16:08 +00:00
|
|
|
from .forms import BaseProjectForm
|
2025-08-20 10:06:43 +00:00
|
|
|
from .models import (
|
|
|
|
|
Account,
|
|
|
|
|
Project,
|
2025-10-16 10:16:08 +00:00
|
|
|
ProjectCategory,
|
2025-10-16 13:38:41 +00:00
|
|
|
ProjectRequest,
|
|
|
|
|
ProjectDeclined,
|
2025-10-16 10:16:08 +00:00
|
|
|
WikimediaProject,
|
2025-08-20 10:06:43 +00:00
|
|
|
HonoraryCertificate,
|
|
|
|
|
Library,
|
|
|
|
|
ELiterature,
|
|
|
|
|
Software,
|
|
|
|
|
IFG,
|
|
|
|
|
Travel,
|
|
|
|
|
Email,
|
|
|
|
|
BusinessCard,
|
|
|
|
|
List,
|
|
|
|
|
Literature,
|
|
|
|
|
)
|
2020-10-06 12:55:46 +00:00
|
|
|
|
2020-11-24 12:44:07 +00:00
|
|
|
|
2025-11-10 10:03:41 +00:00
|
|
|
class WMDEAdmin(admin.ModelAdmin):
|
2025-10-08 10:34:17 +00:00
|
|
|
|
|
|
|
|
def get_fields(self, request, obj=None):
|
2025-11-10 10:03:41 +00:00
|
|
|
fields = super().get_fields(request, obj=obj)
|
2025-10-16 14:31:35 +00:00
|
|
|
|
2025-11-10 10:03:41 +00:00
|
|
|
if 'username' in fields:
|
|
|
|
|
fields = reorder_value(fields, 'username', after='email')
|
2025-10-16 14:31:35 +00:00
|
|
|
|
2025-11-10 10:03:41 +00:00
|
|
|
fields = reorder_value(fields, 'request_url', before='intern_notes')
|
2020-11-24 12:44:07 +00:00
|
|
|
|
2025-11-10 10:03:41 +00:00
|
|
|
if 'terms_accepted' in fields:
|
|
|
|
|
fields = reorder_value(fields, 'terms_accepted', before='request_url')
|
2025-10-08 10:34:17 +00:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2025-10-08 10:34:17 +00:00
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
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)
|
|
|
|
|
|
2025-10-16 10:16:08 +00:00
|
|
|
|
|
|
|
|
@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'):
|
2025-10-16 10:16:08 +00:00
|
|
|
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-16 10:16:08 +00:00
|
|
|
|
2025-10-17 12:15:56 +00:00
|
|
|
class BaseProjectAdmin(admin.ModelAdmin):
|
2020-11-19 13:41:31 +00:00
|
|
|
save_as = True
|
2025-10-16 10:16:08 +00:00
|
|
|
form = ProjectAdminForm
|
2023-02-27 17:09:29 +00:00
|
|
|
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')
|
2023-02-27 17:09:29 +00:00
|
|
|
date_hierarchy = 'end'
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ('end_quartal', 'project_of_year', 'pid', 'finance_id')
|
2025-10-16 10:16:08 +00:00
|
|
|
fieldsets = [
|
|
|
|
|
('Kontakt', {'fields': (
|
|
|
|
|
'realname',
|
|
|
|
|
'email',
|
2025-11-07 16:12:22 +00:00
|
|
|
'username',
|
2025-10-16 10:16:08 +00:00
|
|
|
)}),
|
|
|
|
|
('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,
|
|
|
|
|
)}),
|
|
|
|
|
]
|
2023-02-27 17:09:28 +00:00
|
|
|
|
2023-12-30 19:01:06 +00:00
|
|
|
class Media:
|
|
|
|
|
js = ('dropdown/js/otrs_link.js',)
|
|
|
|
|
|
2025-10-17 12:15:56 +00:00
|
|
|
granted: bool
|
2025-10-16 13:38:41 +00:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
2025-10-16 13:38:41 +00:00
|
|
|
@admin.register(ProjectRequest)
|
2025-10-17 12:15:56 +00:00
|
|
|
class ProjectRequestAdmin(BaseProjectAdmin):
|
2025-10-16 13:38:41 +00:00
|
|
|
granted = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@admin.register(ProjectDeclined)
|
2025-10-17 12:15:56 +00:00
|
|
|
class ProjectDeclinedAdmin(BaseProjectAdmin):
|
2025-10-16 13:38:41 +00:00
|
|
|
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
|
|
|
|
|
|
2023-12-30 19:01:06 +00:00
|
|
|
|
2023-02-27 17:09:28 +00:00
|
|
|
@admin.register(BusinessCard)
|
2025-11-10 10:03:41 +00:00
|
|
|
class BusinessCardAdmin(WMDEAdmin):
|
2025-08-19 12:10:15 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ('realname', 'service_id', 'granted', 'granted_date', 'project')
|
2025-08-26 11:53:39 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project', 'terms_accepted')
|
2023-02-27 17:09:28 +00:00
|
|
|
list_display_links = ('realname', 'service_id')
|
2023-02-27 17:09:28 +00:00
|
|
|
# action = ['export_as_csv']
|
2023-02-27 17:09:29 +00:00
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ['service_id']
|
2025-09-30 13:46:23 +00:00
|
|
|
|
2023-02-27 17:09:28 +00:00
|
|
|
class Media:
|
2025-09-30 13:46:23 +00:00
|
|
|
js = ('dropdown/js/base.js', 'dropdown/js/otrs_link.js')
|
|
|
|
|
|
2023-02-27 17:09:28 +00:00
|
|
|
|
2023-02-27 17:09:28 +00:00
|
|
|
@admin.register(Literature)
|
2025-11-10 10:03:41 +00:00
|
|
|
class LiteratureAdmin(WMDEAdmin):
|
2023-02-27 17:09:29 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
|
2025-08-26 11:53:39 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'terms_accepted')
|
2023-02-27 17:09:29 +00:00
|
|
|
list_display_links = ('realname', 'service_id')
|
|
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ['service_id']
|
2023-02-27 17:09:28 +00:00
|
|
|
|
2025-09-30 13:46:23 +00:00
|
|
|
class Media:
|
|
|
|
|
js = ('dropdown/js/otrs_link.js',)
|
|
|
|
|
|
2023-02-27 17:09:28 +00:00
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
@admin.register(Account)
|
|
|
|
|
class AccountAdmin(admin.ModelAdmin):
|
|
|
|
|
save_as = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@admin.register(HonoraryCertificate)
|
|
|
|
|
class HonoraryCertificateAdmin(admin.ModelAdmin):
|
|
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ['realname', 'granted', 'project__name', 'project__pid']
|
2025-10-08 10:34:17 +00:00
|
|
|
list_display = ('realname', 'granted', 'project')
|
2023-02-27 17:09:29 +00:00
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
autocomplete_fields = ['project']
|
2025-10-08 10:34:17 +00:00
|
|
|
|
2025-02-27 09:15:25 +00:00
|
|
|
class Media:
|
|
|
|
|
js = ('dropdown/js/otrs_link.js',)
|
2023-02-27 17:09:29 +00:00
|
|
|
|
2025-08-20 10:06:43 +00:00
|
|
|
|
|
|
|
|
@admin.register(Library, ELiterature, Software)
|
2025-11-10 10:03:41 +00:00
|
|
|
class LibraryAdmin(WMDEAdmin):
|
2023-02-27 17:09:29 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
|
2023-02-27 17:09:29 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date')
|
|
|
|
|
list_display_links = ('realname', 'service_id')
|
|
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ['service_id']
|
2025-08-20 10:06:43 +00:00
|
|
|
exclude = ['type']
|
|
|
|
|
|
2025-09-30 13:46:23 +00:00
|
|
|
class Media:
|
|
|
|
|
js = ('dropdown/js/otrs_link.js',)
|
|
|
|
|
|
2025-08-20 10:06:43 +00:00
|
|
|
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)
|
|
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
|
|
|
|
|
@admin.register(IFG)
|
2025-11-10 10:03:41 +00:00
|
|
|
class IFGAdmin(WMDEAdmin):
|
2023-02-27 17:09:29 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
|
2023-02-27 17:09:29 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date')
|
|
|
|
|
list_display_links = ('realname', 'service_id')
|
|
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ['service_id']
|
2023-02-27 17:09:29 +00:00
|
|
|
|
2025-09-30 13:46:23 +00:00
|
|
|
class Media:
|
|
|
|
|
js = ('dropdown/js/otrs_link.js',)
|
|
|
|
|
|
2025-10-08 10:34:17 +00:00
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
@admin.register(Travel)
|
2025-11-10 10:03:41 +00:00
|
|
|
class TravelAdmin(WMDEAdmin):
|
2023-02-27 17:09:29 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ['realname', 'service_id', 'granted_date', 'project__name', 'project__pid']
|
2025-10-08 10:34:17 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project_end', 'project',
|
|
|
|
|
'project_end_quartal')
|
2023-02-27 17:09:29 +00:00
|
|
|
list_display_links = ('realname', 'project')
|
2023-02-27 17:09:29 +00:00
|
|
|
date_hierarchy = 'project_end'
|
2023-02-27 17:09:29 +00:00
|
|
|
autocomplete_fields = ['project']
|
2025-08-19 12:10:36 +00:00
|
|
|
readonly_fields = ['service_id', 'project_end', 'project_end_quartal']
|
2023-02-27 17:09:29 +00:00
|
|
|
|
2025-02-26 12:13:46 +00:00
|
|
|
class Media:
|
|
|
|
|
js = ('dropdown/js/otrs_link.js',)
|
|
|
|
|
|
|
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
@admin.register(Email)
|
2025-11-10 10:03:41 +00:00
|
|
|
class EmailAdmin(WMDEAdmin):
|
2023-02-27 17:09:29 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
|
2025-08-26 11:53:39 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'terms_accepted')
|
2023-02-27 17:09:29 +00:00
|
|
|
list_display_links = ('realname', 'service_id')
|
|
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
radio_fields = {'adult': admin.VERTICAL}
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ['service_id']
|
2025-09-30 13:46:23 +00:00
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
class Media:
|
2025-09-30 13:46:23 +00:00
|
|
|
js = ('dropdown/js/base.js', 'dropdown/js/otrs_link.js')
|
2023-02-27 17:09:29 +00:00
|
|
|
|
2020-10-06 11:17:28 +00:00
|
|
|
|
2023-02-27 17:09:29 +00:00
|
|
|
@admin.register(List)
|
2025-11-10 10:03:41 +00:00
|
|
|
class ListAdmin(WMDEAdmin):
|
2023-02-27 17:09:29 +00:00
|
|
|
save_as = True
|
2023-02-27 17:09:29 +00:00
|
|
|
search_fields = ('realname', 'service_id', 'granted', 'granted_date')
|
2025-08-26 11:53:39 +00:00
|
|
|
list_display = ('realname', 'service_id', 'granted', 'granted_date', 'terms_accepted')
|
2023-02-27 17:09:29 +00:00
|
|
|
list_display_links = ('realname', 'service_id')
|
|
|
|
|
date_hierarchy = 'granted_date'
|
2023-02-27 17:09:29 +00:00
|
|
|
readonly_fields = ['service_id']
|