from django.contrib import admin from django.urls import path from django.shortcuts import render from django.http import HttpResponseRedirect from django.contrib import messages from django.utils.translation import gettext_lazy as _ from django.utils import timezone from django.utils.html import format_html import os from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType, AppSetting, Banner, HomeSection from .whatsapp import send_whatsapp_message @admin.register(Country) class CountryAdmin(admin.ModelAdmin): list_display = ('name', 'code', 'is_default') list_editable = ('is_default',) @admin.register(City) class CityAdmin(admin.ModelAdmin): list_display = ('name', 'country') list_filter = ('country',) search_fields = ('name',) @admin.register(TruckType) class TruckTypeAdmin(admin.ModelAdmin): list_display = ('name', 'name_ar') search_fields = ('name', 'name_ar') @admin.register(Profile) class ProfileAdmin(admin.ModelAdmin): list_display = ('user', 'role', 'phone_number', 'subscription_plan', 'subscription_expiry', 'subscription_status') list_filter = ('role', 'subscription_plan', 'is_subscription_active') search_fields = ('user__username', 'phone_number') def subscription_status(self, obj): if obj.subscription_plan == 'NONE': return format_html('{}', _('No Plan')) if obj.is_expired(): return format_html('{}', _('Expired')) # Profile model might not have days_until_expiry, let's check # Based on models.py read earlier, it doesn't have it. # It has a commented out section that seems to be a start of it. # I'll use inline calculation if not obj.subscription_expiry: return format_html('{}', _('No Expiry')) days = (obj.subscription_expiry - timezone.now().date()).days if days <= 7: return format_html('{} ({} {})', _('Expiring soon'), days, _('days')) return format_html('{}', _('Active')) subscription_status.short_description = _('Subscription Status') @admin.register(Truck) class TruckAdmin(admin.ModelAdmin): list_display = ('display_truck_type', 'model', 'plate_no', 'owner', 'load_capacity', 'is_approved') search_fields = ('plate_no', 'owner__username', 'model') list_filter = ('truck_type_link', 'is_approved') readonly_fields = ('truck_picture_preview', 'registration_front_preview', 'registration_back_preview', 'driver_license_front_preview', 'driver_license_back_preview') def truck_picture_preview(self, obj): if obj.truck_picture: return format_html('', obj.truck_picture.url) return "-" truck_picture_preview.short_description = _("Truck Picture Preview") def _file_preview(self, field): if not field: return "-" url = field.url ext = os.path.splitext(field.name)[1].lower() if ext in ['.jpg', '.jpeg', '.png', '.webp', '.gif']: return format_html('', url, url) elif ext == '.pdf': return format_html('
{}
', url, _("View PDF Document")) return format_html('{}', url, _("View File")) def registration_front_preview(self, obj): return self._file_preview(obj.registration_front) registration_front_preview.short_description = _("Registration Front Preview") def registration_back_preview(self, obj): return self._file_preview(obj.registration_back) registration_back_preview.short_description = _("Registration Back Preview") def driver_license_front_preview(self, obj): return self._file_preview(obj.driver_license_front) driver_license_front_preview.short_description = _("Driver License Front Preview") def driver_license_back_preview(self, obj): return self._file_preview(obj.driver_license_back) driver_license_back_preview.short_description = _("Driver License Back Preview") fieldsets = ( (None, {'fields': ('owner', 'truck_type_link', 'is_approved')}), (_('Details (EN)'), {'fields': ('truck_type', 'model', 'load_capacity', 'color', 'year', 'plate_no', 'registration_expiry_date')}), (_('Details (AR)'), {'fields': ('truck_type_ar', 'model_ar', 'load_capacity_ar', 'color_ar')}), (_('Pictures & Documents'), {'fields': ( 'truck_picture', 'truck_picture_preview', 'registration_front', 'registration_front_preview', 'registration_back', 'registration_back_preview', 'driver_license_front', 'driver_license_front_preview', 'driver_license_back', 'driver_license_back_preview' )}), ) @admin.register(Shipment) class ShipmentAdmin(admin.ModelAdmin): list_display = ('display_origin', 'display_destination', 'shipper', 'status', 'delivery_date') list_filter = ('status', 'delivery_date', 'required_truck_type_link') search_fields = ('origin', 'destination', 'shipper__username', 'description') @admin.register(Bid) class BidAdmin(admin.ModelAdmin): list_display = ('shipment', 'truck_owner', 'amount', 'status') list_filter = ('status',) search_fields = ('shipment__description', 'truck_owner__username') @admin.register(Message) class MessageAdmin(admin.ModelAdmin): list_display = ('shipment', 'sender', 'timestamp') search_fields = ('content', 'sender__username') @admin.register(WhatsAppConfig) class WhatsAppConfigAdmin(admin.ModelAdmin): list_display = ('__str__', 'is_active') def has_add_permission(self, request): # Only allow one configuration record if self.model.objects.exists(): return False return super().has_add_permission(request) def get_urls(self): urls = super().get_urls() custom_urls = [ path('send-test/', self.admin_site.admin_view(self.send_test_message), name='send_test_whatsapp'), ] return custom_urls + urls def send_test_message(self, request): if request.method == 'POST': phone = request.POST.get('phone') message = request.POST.get('message') if phone and message: success = send_whatsapp_message(phone, message) if success: self.message_user(request, _("Test message sent successfully!")) else: self.message_user(request, _("Failed to send test message. Check your API credentials and logs."), level=messages.ERROR) return HttpResponseRedirect("../") context = dict( self.admin_site.each_context(request), title=_("Send Test WhatsApp Message"), opts=self.model._meta, ) return render(request, "admin/core/whatsapp_test.html", context) @admin.register(AppSetting) class AppSettingAdmin(admin.ModelAdmin): list_display = ('app_name', 'contact_phone', 'contact_email', 'subscription_enabled') fieldsets = ( (None, {'fields': ('app_name', 'logo', 'slogan')}), (_('Contact Information'), {'fields': ('contact_phone', 'contact_email', 'contact_address')}), (_('Legal'), {'fields': ('registration_number', 'tax_number', 'terms_of_service', 'privacy_policy')}), (_('Subscription Status'), {'fields': ('subscription_enabled', 'thawani_enabled')}), (_('Shipper Subscription Fees'), {'fields': ('shipper_monthly_fee', 'shipper_annual_fee')}), (_('Truck Owner Subscription Fees'), {'fields': ('truck_owner_monthly_fee', 'truck_owner_annual_fee')}), ) def has_add_permission(self, request): # Only allow one configuration record if self.model.objects.exists(): return False return super().has_add_permission(request) @admin.register(Banner) class BannerAdmin(admin.ModelAdmin): list_display = ('title', 'order', 'is_active', 'created_at') list_editable = ('order', 'is_active') search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar') @admin.register(HomeSection) class HomeSectionAdmin(admin.ModelAdmin): list_display = ('title', 'section_type', 'order', 'is_active') list_editable = ('order', 'is_active') list_filter = ('section_type', 'is_active', 'background_color') search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')