"""Admin for the accounting app.""" from django import forms from django.contrib import admin from django.contrib import messages from django.db.models import QuerySet from django.http import HttpRequest from django.utils.translation import gettext_lazy as _ from membership.emails import OrderEmail from . import models class OrderProductInline(admin.TabularInline): """Administer contents of an order inline.""" model = models.OrderProduct class OrderAdminForm(forms.ModelForm): """Special Form for the OrderAdmin so we don't need to require the account field.""" account = forms.ModelChoiceField( required=False, queryset=models.Account.objects.all(), help_text=_("Leave empty to auto-choose the member's own account or to create one."), ) class Meta: model = models.Order exclude = () # noqa: DJ006 def clean(self) -> None: """Clean the order.""" cd = super().clean() if not cd["account"] and cd["member"]: try: cd["account"] = models.Account.objects.get_or_create(owner=cd["member"])[0] except models.Account.MultipleObjectsReturned: cd["account"] = models.Account.objects.filter(owner=cd["member"]).first() return cd @admin.register(models.Order) class OrderAdmin(admin.ModelAdmin): """Admin for the Order model.""" inlines = (OrderProductInline,) form = OrderAdminForm actions = ("send_order",) list_display = ("member", "description", "created", "is_paid", "total_with_vat") search_fields = ("member__email", "membership__membership_type__name", "description") list_filter = ("is_paid", "membership__membership_type") @admin.action(description="Send order link to selected unpaid orders") def send_order(self, request: HttpRequest, queryset: QuerySet[models.Order]) -> None: """Send the order to the member.""" for order in queryset: if order.is_paid: messages.error( request, f"Order pk={order.id} is already marked paid, not sending email to: {order.member.email}", ) continue email = OrderEmail(order, request) email.send() messages.success(request, f"Sent an order for order pk={order.id} link to: {order.member.email}") @admin.register(models.Payment) class PaymentAdmin(admin.ModelAdmin): """Admin for the Payment model.""" list_display = ("order__member", "description", "order_id", "created") @admin.display(description=_("Order ID")) def order_id(self, instance: models.Payment) -> int: """Return the ID of the order.""" return instance.order.id @admin.register(models.Product) class ProductAdmin(admin.ModelAdmin): """Admin for the Product model.""" list_display = ("name", "price", "vat") class TransactionInline(admin.TabularInline): """Inline admin for the Transaction model.""" model = models.Transaction @admin.register(models.Account) class AccountAdmin(admin.ModelAdmin): """Admin for the Account model.""" list_display = ("owner", "balance") inlines = (TransactionInline,)