from django.contrib import admin
from django.shortcuts import redirect
from django.urls import path, reverse
from django.utils import timezone
from django.utils.html import format_html
from .models import Claim, ClaimLog, Project
class ClaimLogInline(admin.TabularInline):
model = ClaimLog
extra = 0
readonly_fields = ("action", "from_status", "to_status", "note", "performed_by", "created_at")
can_delete = False
@admin.register(Claim)
class ClaimAdmin(admin.ModelAdmin):
list_display = ("full_name", "amount", "currency", "project", "status", "paid", "created_at", "submitted_by")
list_filter = ("status", "created_at", "project", "paid_at")
search_fields = ("full_name", "email", "description")
base_readonly = ("created_at", "updated_at", "paid_at", "paid_by", "reset_paid_button")
readonly_fields = base_readonly
inlines = [ClaimLogInline]
actions = ("mark_as_paid", "mark_as_unpaid")
@admin.display(boolean=True, description="Betald")
def paid(self, obj):
return obj.is_paid
@admin.display(description="Återställ betalning")
def reset_paid_button(self, obj):
if not obj.is_paid:
return "Ej betald"
url = reverse("admin:claims_claim_reset_payment", args=[obj.pk])
return format_html(
'Resetta',
url,
)
@admin.action(description="Markera valda som betalda")
def mark_as_paid(self, request, queryset):
count = 0
for claim in queryset.filter(status=Claim.Status.APPROVED, paid_at__isnull=True):
claim.paid_at = timezone.now()
claim.paid_by = request.user
claim.save(update_fields=["paid_at", "paid_by"])
claim.add_log(
action=ClaimLog.Action.MARKED_PAID,
performed_by=request.user,
note="Markerad som betald via Django admin.",
)
count += 1
if count:
self.message_user(request, f"{count} utlägg markerades som betalda.")
else:
self.message_user(request, "Inga utlägg markerades – kontrollera status/betalning.", level="warning")
@admin.action(description="Återställ betalningsstatus (markera som obetalda)")
def mark_as_unpaid(self, request, queryset):
count = 0
for claim in queryset.filter(paid_at__isnull=False):
claim.paid_at = None
claim.paid_by = None
claim.save(update_fields=["paid_at", "paid_by"])
claim.add_log(
action=ClaimLog.Action.MARKED_PAID,
performed_by=request.user,
note="Betalningsstatus återställd via Django admin.",
)
count += 1
if count:
self.message_user(request, f"{count} utlägg markerades som obetalda.")
else:
self.message_user(request, "Inga utlägg behövde återställas.", level="warning")
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
"/reset-payment/",
self.admin_site.admin_view(self.reset_payment_view),
name="claims_claim_reset_payment",
),
]
return custom_urls + urls
def reset_payment_view(self, request, claim_id):
claim = Claim.objects.filter(pk=claim_id).first()
if not claim:
self.message_user(request, "Utlägget hittades inte.", level="error")
return redirect("admin:claims_claim_changelist")
claim.paid_at = None
claim.paid_by = None
claim.save(update_fields=["paid_at", "paid_by"])
claim.add_log(
action=ClaimLog.Action.MARKED_PAID,
performed_by=request.user,
note="Betalningsstatus återställd via reset-knapp i admin.",
)
self.message_user(request, f"{claim} markerades som obetald.")
return redirect("admin:claims_claim_change", claim_id)
def get_readonly_fields(self, request, obj=None):
if obj and obj.is_paid:
return self.base_readonly + ("status", "decision_note")
return self.base_readonly
@admin.register(ClaimLog)
class ClaimLogAdmin(admin.ModelAdmin):
list_display = ("claim", "action", "from_status", "to_status", "performed_by", "created_at")
list_filter = ("action", "to_status", "created_at")
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
list_display = ("name", "code", "is_active", "updated_at")
list_filter = ("is_active",)
search_fields = ("name", "code")