diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index b932693..a145697 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index cb8f7bd..fdf6df4 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 2ba60ea..bde313b 100644 --- a/core/admin.py +++ b/core/admin.py @@ -12,6 +12,8 @@ from django.core.mail import send_mail from django.conf import settings from .mail import send_html_email import logging +import csv +from django.http import HttpResponse class ProfileInline(admin.StackedInline): model = Profile @@ -22,9 +24,32 @@ class CustomUserAdmin(UserAdmin): inlines = (ProfileInline,) class ParcelAdmin(admin.ModelAdmin): - list_display = ('tracking_number', 'shipper', 'status', 'created_at') - list_filter = ('status', 'created_at') - search_fields = ('tracking_number', 'shipper__username', 'receiver_name') + list_display = ('tracking_number', 'shipper', 'carrier', 'price', 'status', 'payment_status', 'created_at') + list_filter = ('status', 'payment_status', 'created_at') + search_fields = ('tracking_number', 'shipper__username', 'receiver_name', 'carrier__username') + actions = ['export_as_csv'] + + def export_as_csv(self, request, queryset): + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="parcels_report.csv"' + writer = csv.writer(response) + + writer.writerow(['Tracking Number', 'Shipper', 'Carrier', 'Price (OMR)', 'Status', 'Payment Status', 'Created At', 'Updated At']) + + for obj in queryset: + writer.writerow([ + obj.tracking_number, + obj.shipper.username if obj.shipper else '', + obj.carrier.username if obj.carrier else '', + obj.price, + obj.get_status_display(), + obj.get_payment_status_display(), + obj.created_at, + obj.updated_at + ]) + + return response + export_as_csv.short_description = _("Export Selected to CSV") class PlatformProfileAdmin(admin.ModelAdmin): fieldsets = ( diff --git a/core/templates/core/driver_dashboard.html b/core/templates/core/driver_dashboard.html index 8c19b25..f932197 100644 --- a/core/templates/core/driver_dashboard.html +++ b/core/templates/core/driver_dashboard.html @@ -10,7 +10,10 @@ + @@ -51,7 +54,7 @@ {% endif %} - +
{% if my_parcels %}
@@ -87,6 +90,50 @@

{% trans "You haven't accepted any shipments yet." %}

{% endif %}
+ + +
+ {% if completed_parcels %} +
+
+
+ + + + + + + + + + + + + {% for parcel in completed_parcels %} + + + + + + + + + {% endfor %} + +
{% trans "Date" %}{% trans "Tracking ID" %}{% trans "From" %}{% trans "To" %}{% trans "Price" %}{% trans "Status" %}
{{ parcel.created_at|date:"Y-m-d" }}#{{ parcel.tracking_number }}{{ parcel.pickup_city.name|default:parcel.pickup_address }}{{ parcel.delivery_city.name|default:parcel.delivery_address }}{{ parcel.price }} OMR + + {{ parcel.get_status_display }} + +
+
+
+
+ {% else %} +
+

{% trans "No completed deliveries yet." %}

+
+ {% endif %} +
{% endblock %} \ No newline at end of file diff --git a/core/templates/core/shipper_dashboard.html b/core/templates/core/shipper_dashboard.html index 99e07e8..3522058 100644 --- a/core/templates/core/shipper_dashboard.html +++ b/core/templates/core/shipper_dashboard.html @@ -8,50 +8,116 @@ {% trans "New Shipment" %} - {% if parcels %} -
- {% for parcel in parcels %} -
-
-
-
- #{{ parcel.tracking_number }} - - {{ parcel.get_status_display }} - -
-
{{ parcel.description|truncatechars:30 }}
-

{% trans "From" %}: {{ parcel.pickup_address }}

-

{% trans "To" %}: {{ parcel.delivery_address }}

- -
- {{ parcel.price }} OMR - - {{ parcel.get_payment_status_display }} - -
+ + - {% if parcel.payment_status == 'pending' %} - {% if platform_profile.enable_payment %} - - {% trans "Pay Now" %} - - {% endif %} - {% endif %} +
+ + +
+ {% if active_parcels %} +
+ {% for parcel in active_parcels %} +
+
+
+
+ #{{ parcel.tracking_number }} + + {{ parcel.get_status_display }} + +
+
{{ parcel.description|truncatechars:30 }}
+

{% trans "From" %}: {{ parcel.pickup_address }}

+

{% trans "To" %}: {{ parcel.delivery_address }}

+ +
+ {{ parcel.price }} OMR + + {{ parcel.get_payment_status_display }} + +
-
-

{% trans "Receiver" %}: {{ parcel.receiver_name }}

-

{% trans "Carrier" %}: {% if parcel.carrier %}{{ parcel.carrier.get_full_name|default:parcel.carrier.username }}{% else %}{% trans "Waiting for pickup" %}{% endif %}

+ {% if parcel.payment_status == 'pending' %} + {% if payments_enabled %} + + {% trans "Pay Now" %} + + {% endif %} + {% endif %} + +
+

{% trans "Receiver" %}: {{ parcel.receiver_name }}

+

{% trans "Carrier" %}: {% if parcel.carrier %}{{ parcel.carrier.get_full_name|default:parcel.carrier.username }}{% else %}{% trans "Waiting for pickup" %}{% endif %}

+
+
+
+ {% endfor %} +
+ {% else %} +
+

{% trans "You have no active shipments." %}

+ {% trans "Send your first shipment" %} +
+ {% endif %} +
+ + +
+ {% if history_parcels %} +
+
+
+ + + + + + + + + + + + + {% for parcel in history_parcels %} + + + + + + + + + {% endfor %} + +
{% trans "Date" %}{% trans "Tracking ID" %}{% trans "Description" %}{% trans "Carrier" %}{% trans "Bid/Price" %}{% trans "Status" %}
{{ parcel.created_at|date:"Y-m-d" }}#{{ parcel.tracking_number }}{{ parcel.description|truncatechars:30 }} + {% if parcel.carrier %} + {{ parcel.carrier.get_full_name|default:parcel.carrier.username }} + {% else %} + - + {% endif %} + {{ parcel.price }} OMR + + {{ parcel.get_status_display }} + +
+
+ {% else %} +
+

{% trans "No completed transactions yet." %}

+
+ {% endif %}
- {% endfor %}
- {% else %} -
-

{% trans "You haven't sent any shipments yet." %}

- {% trans "Send your first shipment" %} -
- {% endif %}
{% endblock %} \ No newline at end of file diff --git a/core/views.py b/core/views.py index 58d1cb2..61920ea 100644 --- a/core/views.py +++ b/core/views.py @@ -123,15 +123,39 @@ def dashboard(request): profile, created = Profile.objects.get_or_create(user=request.user) if profile.role == 'shipper': - parcels = Parcel.objects.filter(shipper=request.user).order_by('-created_at') - return render(request, 'core/shipper_dashboard.html', {'parcels': parcels}) + all_parcels = Parcel.objects.filter(shipper=request.user).order_by('-created_at') + active_parcels = all_parcels.exclude(status__in=['delivered', 'cancelled']) + history_parcels = all_parcels.filter(status__in=['delivered', 'cancelled']) + + platform_profile = PlatformProfile.objects.first() + payments_enabled = platform_profile.enable_payment if platform_profile else True + + return render(request, 'core/shipper_dashboard.html', { + 'active_parcels': active_parcels, + 'history_parcels': history_parcels, + 'payments_enabled': payments_enabled, + 'platform_profile': platform_profile # Pass full profile just in case + }) else: # Car Owner view - available_parcels = Parcel.objects.filter(status='pending', payment_status='paid').order_by('-created_at') - my_parcels = Parcel.objects.filter(carrier=request.user).exclude(status='delivered').order_by('-created_at') + platform_profile = PlatformProfile.objects.first() + payments_enabled = platform_profile.enable_payment if platform_profile else True + + if payments_enabled: + available_parcels = Parcel.objects.filter(status='pending', payment_status='paid').order_by('-created_at') + else: + available_parcels = Parcel.objects.filter(status='pending').order_by('-created_at') + + # Active: Picked up or In Transit + my_parcels = Parcel.objects.filter(carrier=request.user).exclude(status__in=['delivered', 'cancelled']).order_by('-created_at') + + # History: Delivered or Cancelled + completed_parcels = Parcel.objects.filter(carrier=request.user, status__in=['delivered', 'cancelled']).order_by('-created_at') + return render(request, 'core/driver_dashboard.html', { 'available_parcels': available_parcels, - 'my_parcels': my_parcels + 'my_parcels': my_parcels, + 'completed_parcels': completed_parcels }) @login_required @@ -164,7 +188,14 @@ def accept_parcel(request, parcel_id): messages.error(request, _("Only car owners can accept shipments.")) return redirect('dashboard') - parcel = get_object_or_404(Parcel, id=parcel_id, status='pending', payment_status='paid') + platform_profile = PlatformProfile.objects.first() + payments_enabled = platform_profile.enable_payment if platform_profile else True + + if payments_enabled: + parcel = get_object_or_404(Parcel, id=parcel_id, status='pending', payment_status='paid') + else: + parcel = get_object_or_404(Parcel, id=parcel_id, status='pending') + parcel.carrier = request.user parcel.status = 'picked_up' parcel.save()