adding reports

This commit is contained in:
Flatlogic Bot 2026-01-26 08:25:00 +00:00
parent 595ca7c1fe
commit a094518411
12 changed files with 316 additions and 110 deletions

View File

@ -1,4 +1,4 @@
{% extends "admin/index.html" %}
{% extends "admin/base_site.html" %}
{% load i18n static dashboard_stats %}
{% block extrastyle %}
@ -243,8 +243,10 @@
</div>
<!-- Standard Admin Index Content -->
{{ block.super }}
<!-- Standard Admin App List -->
<div id="content-main">
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js" integrity="sha512-d9xgZrVZpmmQlfonhQUvTR7lMPtO7NkZMkA0ABN3PHCbKA5nqylQ/yWlFAyY6hYgdF1Qh6nYiuADWwKB4C2WSw==" crossorigin="anonymous"></script>
<script>

View File

@ -80,6 +80,9 @@
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto align-items-center">
<li class="nav-item">
<a class="nav-link px-3" href="{% url 'track' %}">{% trans "Track" %}</a>
</li>
<li class="nav-item">
<a class="nav-link px-3" href="{% url 'index' %}#how-it-works">{% trans "How it Works" %}</a>
</li>

View File

@ -17,30 +17,13 @@
<div class="col-lg-5 offset-lg-1">
<div class="glass-card">
<h3 class="mb-4">{% trans "Track your Parcel" %}</h3>
<form method="GET" action="{% url 'index' %}">
<form method="GET" action="{% url 'track' %}">
<div class="input-group mb-3">
<input type="text" name="tracking_id" class="form-control tracking-input" placeholder="{% trans 'Enter Tracking ID (e.g. 5A2B...)' %}" value="{{ tracking_id|default:'' }}">
<input type="text" name="tracking_number" class="form-control tracking-input" placeholder="{% trans 'Enter Tracking ID (e.g. 5A2B...)' %}" value="{{ tracking_number|default:'' }}">
<button class="btn btn-masarx-primary px-4" type="submit">{% trans "Track" %}</button>
</div>
</form>
{% if parcel %}
<div class="mt-4 p-3 bg-white bg-opacity-10 rounded-3 text-start" dir="ltr">
<div class="d-flex justify-content-between align-items-center mb-3">
<span class="text-uppercase small opacity-75">{% trans "Status" %}</span>
<span class="parcel-status-badge status-{{ parcel.status }}">{{ parcel.get_status_display }}</span>
</div>
<h5 class="mb-1">{{ parcel.description|truncatechars:30 }}</h5>
<p class="small mb-0 opacity-75">{% trans "From" %}: {{ parcel.pickup_address }}</p>
<p class="small mb-0 opacity-75">{% trans "To" %}: {{ parcel.delivery_address }}</p>
</div>
{% elif error %}
<div class="mt-3 text-danger small">
<i class="bi bi-exclamation-circle me-1"></i> {{ error }}
</div>
{% else %}
<p class="small opacity-50 mt-3 mb-0">{% trans "Enter your 10-character tracking ID to see live updates." %}</p>
{% endif %}
</div>
</div>
</div>

View File

@ -1,10 +1,10 @@
{% load static %}
{% load i18n %}
<!DOCTYPE html>
<html lang="{{ request.LANGUAGE_CODE }}" dir="{% if request.LANGUAGE_CODE == 'ar' %}rtl{% else %}ltr{% endif %}">
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>{% trans "Tax Invoice" %} - {{ parcel.tracking_number }}</title>
<title>Invoice {{ parcel.tracking_number }}</title>
<style>
@page {
size: A4;
@ -14,45 +14,59 @@
font-family: sans-serif;
font-size: 14px;
color: #333;
line-height: 1.5;
line-height: 1.4;
}
.header {
width: 100%;
margin-bottom: 40px;
overflow: hidden;
margin-bottom: 30px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid #eee;
padding-bottom: 20px;
}
.logo {
float: {% if request.LANGUAGE_CODE == 'ar' %}right{% else %}left{% endif %};
width: 150px;
.logo-section {
width: 40%;
}
.company-info {
float: {% if request.LANGUAGE_CODE == 'ar' %}left{% else %}right{% endif %};
text-align: {% if request.LANGUAGE_CODE == 'ar' %}left{% else %}right{% endif %};
width: 50%;
text-align: right;
font-size: 12px;
}
.title {
clear: both;
text-align: center;
font-size: 24px;
font-weight: bold;
margin-bottom: 30px;
text-transform: uppercase;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
background-color: #f9f9f9;
padding: 10px;
border: 1px solid #eee;
}
.title span.ar { display: block; font-size: 18px; font-weight: normal; margin-top: 5px; }
.details-grid {
display: table;
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 30px;
}
.details-col {
display: table-cell;
width: 50%;
vertical-align: top;
width: 48%;
background: #fdfdfd;
padding: 15px;
border: 1px solid #eee;
border-radius: 4px;
}
.label {
font-weight: bold;
color: #666;
margin-bottom: 2px;
margin-bottom: 5px;
font-size: 11px;
text-transform: uppercase;
border-bottom: 1px solid #ddd;
padding-bottom: 2px;
display: flex;
justify-content: space-between;
}
.value {
margin-bottom: 10px;
@ -63,22 +77,23 @@
margin-bottom: 30px;
}
th, td {
padding: 10px;
padding: 12px;
border-bottom: 1px solid #eee;
text-align: left;
}
th {
background-color: #f9f9f9;
text-align: {% if request.LANGUAGE_CODE == 'ar' %}right{% else %}left{% endif %};
background-color: #f5f5f5;
font-weight: bold;
font-size: 12px;
}
.text-right {
text-align: {% if request.LANGUAGE_CODE == 'ar' %}left{% else %}right{% endif %};
}
th span.ar { display: block; font-weight: normal; font-size: 11px; color: #555; }
.text-right { text-align: right; }
.total-row td {
font-weight: bold;
font-size: 16px;
border-top: 2px solid #333;
border-bottom: none;
background-color: #f9f9f9;
}
.footer {
margin-top: 50px;
@ -98,14 +113,15 @@
}
.paid { color: #0f9d58; border: 1px solid #0f9d58; }
.pending { color: #f4b400; border: 1px solid #f4b400; }
.ar-text { direction: rtl; unicode-bidi: embed; }
</style>
</head>
<body>
<div class="header">
<div class="logo">
<div class="logo-section">
{% if logo_base64 %}
<img src="data:image/jpeg;base64,{{ logo_base64 }}" style="max-width: 100%; max-height: 80px;">
<img src="data:image/jpeg;base64,{{ logo_base64 }}" style="max-width: 200px; max-height: 80px;">
{% else %}
<h2>{{ platform_profile.name }}</h2>
{% endif %}
@ -114,28 +130,41 @@
<strong>{{ platform_profile.name }}</strong><br>
{{ platform_profile.address|linebreaksbr }}<br>
{% if platform_profile.vat_number %}
{% trans "VAT Number" %}: {{ platform_profile.vat_number }}<br>
VAT / الرقم الضريبي: {{ platform_profile.vat_number }}<br>
{% endif %}
{{ platform_profile.phone_number }}
Tel: {{ platform_profile.phone_number }}
</div>
</div>
<div class="title">{% trans "Tax Invoice" %}</div>
<div class="title">
TAX INVOICE
<span class="ar ar-text">فاتورة ضريبية</span>
</div>
<div class="details-grid">
<div class="details-col">
<div class="label">{% trans "Invoice Details" %}</div>
<div class="label">
<span>INVOICE DETAILS</span>
<span class="ar-text">تفاصيل الفاتورة</span>
</div>
<div class="value">
{% trans "Invoice No" %}: #{{ parcel.id }}<br>
{% trans "Date" %}: {{ parcel.created_at|date:"Y-m-d" }}<br>
{% trans "Status" %}:
<strong>No / رقم:</strong> #{{ parcel.id }}<br>
<strong>Date / التاريخ:</strong> {{ parcel.created_at|date:"Y-m-d" }}<br>
<strong>Status / الحالة:</strong>
<span class="status-badge {% if parcel.payment_status == 'paid' %}paid{% else %}pending{% endif %}">
{{ parcel.get_payment_status_display }}
{% if parcel.payment_status == 'paid' %}
PAID / مدفوع
{% else %}
PENDING / غير مدفوع
{% endif %}
</span>
</div>
</div>
<div class="details-col text-right">
<div class="label">{% trans "Bill To" %}</div>
<div class="details-col">
<div class="label">
<span>BILL TO (Shipper)</span>
<span class="ar-text">فاتورة إلى (الشاحن)</span>
</div>
<div class="value">
<strong>{{ parcel.shipper.first_name }} {{ parcel.shipper.last_name }}</strong><br>
{{ parcel.shipper.profile.address }}<br>
@ -148,15 +177,30 @@
<table>
<thead>
<tr>
<th>{% trans "Description" %}</th>
<th>{% trans "Tracking Number" %}</th>
<th>{% trans "Weight" %}</th>
<th class="text-right">{% trans "Amount" %} (OMR)</th>
<th width="50%">
Description
<span class="ar ar-text">الوصف</span>
</th>
<th>
Tracking No
<span class="ar ar-text">رقم التتبع</span>
</th>
<th>
Weight
<span class="ar ar-text">الوزن</span>
</th>
<th class="text-right">
Amount (OMR)
<span class="ar ar-text">المبلغ</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>{% trans "Delivery Service" %} - {{ parcel.description|truncatechars:50 }}</td>
<td>
Delivery Service / خدمة توصيل<br>
<small>{{ parcel.description|truncatechars:50 }}</small>
</td>
<td>{{ parcel.tracking_number }}</td>
<td>{{ parcel.weight }} kg</td>
<td class="text-right">{{ parcel.price }}</td>
@ -164,18 +208,21 @@
</tbody>
<tfoot>
<tr class="total-row">
<td colspan="3" class="text-right">{% trans "Total" %}</td>
<td colspan="3" class="text-right">
TOTAL / الإجمالي
</td>
<td class="text-right">{{ parcel.price }} OMR</td>
</tr>
</tfoot>
</table>
<div class="footer">
<p>{% trans "Thank you for using" %} {{ platform_profile.name }}!</p>
<p>Thank you for using {{ platform_profile.name }}!</p>
<p class="ar-text">شكراً لاستخدامكم {{ platform_profile.name }}!</p>
{% if platform_profile.registration_number %}
<p>{% trans "CR No" %}: {{ platform_profile.registration_number }}</p>
<p>CR No / السجل التجاري: {{ platform_profile.registration_number }}</p>
{% endif %}
</div>
</body>
</html>
</html>

View File

@ -1,6 +1,6 @@
{% load i18n %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}" dir="{{ LANGUAGE_BIDI|yesno:'rtl,ltr' }}">
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Label {{ parcel.tracking_number }}</title>
@ -10,20 +10,21 @@
margin: 0;
}
body {
font-family: sans-serif;
font-family: sans-serif; /* WeasyPrint uses system fonts. Ensure Arabic font is available. */
margin: 0;
padding: 5mm;
font-size: 12px;
color: #000;
}
.container {
border: 2px solid #000;
height: 138mm; /* Adjusted slightly */
height: 138mm;
display: flex;
flex-direction: column;
}
.header {
border-bottom: 2px solid #000;
padding: 10px;
padding: 5px;
text-align: center;
height: 20mm;
display: flex;
@ -36,16 +37,20 @@
max-width: 80mm;
}
.big-code {
font-size: 24px;
font-size: 20px;
font-weight: bold;
text-align: center;
padding: 10px;
padding: 8px;
border-bottom: 2px solid #000;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
.address-box {
border-bottom: 1px solid #000;
padding: 10px;
padding: 8px;
flex-grow: 1;
}
.main-info {
@ -53,13 +58,14 @@
border-bottom: 2px solid #000;
}
.section {
padding: 10px;
padding: 8px;
flex: 1;
border-right: 1px solid #000;
text-align: center;
}
.section:last-child {
border-right: none;
}
/* RTL support for border */
html[dir="ltr"] .section-right { border-left: 2px solid #000; }
html[dir="rtl"] .section-right { border-right: 2px solid #000; }
.qr-code {
text-align: center;
padding: 10px;
@ -78,67 +84,107 @@
.footer {
padding: 5px;
text-align: center;
font-size: 10px;
font-size: 9px;
}
h3 {
margin: 0 0 5px 0;
font-size: 10px;
text-transform: uppercase;
color: #333;
border-bottom: 1px dotted #ccc;
padding-bottom: 2px;
display: flex;
justify-content: space-between;
}
h3 span.ar { font-weight: normal; }
p { margin: 0 0 2px 0; line-height: 1.2; }
.bold { font-weight: bold; font-size: 13px; }
.dual-text {
display: flex;
flex-direction: row;
gap: 5px;
}
.ar-text {
font-family: sans-serif;
direction: rtl;
}
h3 { margin: 0 0 5px 0; font-size: 10px; text-transform: uppercase; color: #555; }
p { margin: 0 0 2px 0; }
.bold { font-weight: bold; font-size: 14px; }
</style>
</head>
<body>
<div class="container">
<!-- Platform Header -->
<div class="header">
{% if logo_base64 %}
<img src="data:image/jpeg;base64,{{ logo_base64 }}" alt="MasarX">
<img src="data:image/jpeg;base64,{{ logo_base64 }}" alt="Logo">
{% else %}
<h1>{{ platform_profile.name|default:"MASARX" }}</h1>
{% endif %}
</div>
<!-- Destination City Code -->
<div class="big-code">
{{ parcel.delivery_city.name|upper }}
<span>{{ parcel.delivery_city.name_en|upper }}</span>
<span class="ar-text">/ {{ parcel.delivery_city.name_ar }}</span>
</div>
<!-- Receiver Info -->
<div class="address-box">
<h3>{% trans "TO (Receiver)" %}</h3>
<h3>
<span>TO (Receiver)</span>
<span class="ar-text">إلى (المستلم)</span>
</h3>
<p class="bold">{{ parcel.receiver_name }}</p>
<p>{{ parcel.delivery_address }}</p>
<p>{{ parcel.delivery_city.name }}, {{ parcel.delivery_governate.name }}</p>
<p>{{ parcel.delivery_country.name }}</p>
<p>{% trans "Tel" %}: {{ parcel.receiver_phone }}</p>
<p>
{{ parcel.delivery_city.name_en }} / <span class="ar-text">{{ parcel.delivery_city.name_ar }}</span>
</p>
<p>
{{ parcel.delivery_governate.name_en }} / <span class="ar-text">{{ parcel.delivery_governate.name_ar }}</span> - {{ parcel.delivery_country.name_en }}
</p>
<p><strong>Tel / هاتف:</strong> {{ parcel.receiver_phone }}</p>
</div>
<!-- Sender Info -->
<div class="address-box">
<h3>{% trans "FROM (Sender)" %}</h3>
<h3>
<span>FROM (Sender)</span>
<span class="ar-text">من (المرسل)</span>
</h3>
<p class="bold">{{ parcel.shipper.get_full_name|default:parcel.shipper.username }}</p>
<p>{{ parcel.pickup_address }}</p>
<p>{{ parcel.pickup_city.name }}, {{ parcel.pickup_governate.name }}</p>
<p>{% trans "Tel" %}: {{ parcel.shipper.profile.phone_number }}</p>
<p>
{{ parcel.pickup_city.name_en }} / <span class="ar-text">{{ parcel.pickup_city.name_ar }}</span>
</p>
<p><strong>Tel / هاتف:</strong> {{ parcel.shipper.profile.phone_number }}</p>
</div>
<!-- Info Row: Date, Weight, Price -->
<div class="main-info">
<div class="section">
<h3>{% trans "Date" %}</h3>
<h3>Date / التاريخ</h3>
<p class="bold">{{ parcel.created_at|date:"Y-m-d" }}</p>
</div>
<div class="section section-right">
<h3>{% trans "Weight" %}</h3>
<div class="section">
<h3>Weight / الوزن</h3>
<p class="bold">{{ parcel.weight }} KG</p>
</div>
<div class="section section-right">
<h3>{% trans "Price" %}</h3>
<div class="section">
<h3>COD / الدفع</h3>
<p class="bold">{{ parcel.price }} OMR</p>
</div>
</div>
<!-- Tracking & QR -->
<div class="qr-code">
<img src="data:image/png;base64,{{ qr_code }}" alt="QR Code">
<div class="tracking-number">{{ parcel.tracking_number }}</div>
</div>
<!-- Footer -->
<div class="footer">
{% trans "Thank you for shipping with us." %}
Thank you for shipping with us.<br>
<span class="ar-text">شكراً لاستخدامكم خدماتنا.</span>
</div>
</div>
</body>
</html>
</html>

View File

@ -0,0 +1,110 @@
{% extends 'base.html' %}
{% load static i18n %}
{% block title %}{% trans "Track Shipment" %} - MasarX{% endblock %}
{% block content %}
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow-sm border-0 rounded-4">
<div class="card-body p-4 p-md-5">
<h2 class="text-center mb-4">{% trans "Track Your Shipment" %}</h2>
<!-- Search Form -->
<form method="GET" action="{% url 'track' %}" class="mb-5">
<div class="input-group input-group-lg">
<input type="text" name="tracking_number" class="form-control border-end-0" placeholder="{% trans 'Enter Tracking ID (e.g. TRK123456789)' %}" value="{{ tracking_number|default:'' }}" required>
<button class="btn btn-primary px-4" type="submit">
<i class="bi bi-search me-2"></i>{% trans "Track" %}
</button>
</div>
</form>
{% if error %}
<div class="alert alert-danger rounded-3" role="alert">
<i class="bi bi-exclamation-triangle-fill me-2"></i> {{ error }}
</div>
{% endif %}
{% if parcel %}
<!-- Status Timeline -->
<div class="mb-5">
<h5 class="mb-4 text-muted">{% trans "Shipment Status" %}</h5>
<div class="position-relative m-4">
<div class="progress" style="height: 4px;">
<div class="progress-bar {% if parcel.status == 'delivered' %}bg-success{% else %}bg-primary{% endif %}" role="progressbar" style="width:
{% if parcel.status == 'pending' %}10%
{% elif parcel.status == 'picked_up' %}50%
{% elif parcel.status == 'in_transit' %}75%
{% elif parcel.status == 'delivered' %}100%
{% else %}0%{% endif %}
" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<!-- Steps -->
<div class="position-absolute top-0 start-0 translate-middle btn btn-sm rounded-pill {% if parcel.status != 'cancelled' %}btn-primary{% else %}btn-secondary{% endif %}" style="width: 2rem; height:2rem;">1</div>
<div class="position-absolute top-0 start-50 translate-middle btn btn-sm rounded-pill {% if parcel.status in 'picked_up,in_transit,delivered' %}btn-primary{% else %}btn-secondary{% endif %}" style="width: 2rem; height:2rem;">2</div>
<div class="position-absolute top-0 start-100 translate-middle btn btn-sm rounded-pill {% if parcel.status == 'delivered' %}btn-success{% else %}btn-secondary{% endif %}" style="width: 2rem; height:2rem;">3</div>
<!-- Labels -->
<div class="d-flex justify-content-between mt-2">
<small class="fw-bold">{% trans "Order Placed" %}</small>
<small class="fw-bold">{% trans "On the Way" %}</small>
<small class="fw-bold">{% trans "Delivered" %}</small>
</div>
</div>
</div>
<!-- Parcel Details Card -->
<div class="bg-light p-4 rounded-3 border">
<div class="row g-4">
<div class="col-md-6">
<h6 class="text-uppercase text-muted small mb-2">{% trans "Tracking Number" %}</h6>
<p class="fw-bold fs-5 mb-0">{{ parcel.tracking_number }}</p>
</div>
<div class="col-md-6">
<h6 class="text-uppercase text-muted small mb-2">{% trans "Current Status" %}</h6>
<span class="badge {% if parcel.status == 'delivered' %}bg-success{% elif parcel.status == 'cancelled' %}bg-danger{% else %}bg-primary{% endif %} fs-6">
{{ parcel.get_status_display }}
</span>
</div>
<div class="col-12"><hr class="my-1"></div>
<!-- From / To (Public View: Only City/Governate) -->
<div class="col-md-6">
<h6 class="text-uppercase text-muted small mb-2">{% trans "From" %}</h6>
<p class="mb-0 fw-medium">{{ parcel.pickup_city.name }}</p>
<small class="text-muted">{{ parcel.pickup_governate.name }}</small>
</div>
<div class="col-md-6">
<h6 class="text-uppercase text-muted small mb-2">{% trans "To" %}</h6>
<p class="mb-0 fw-medium">{{ parcel.delivery_city.name }}</p>
<small class="text-muted">{{ parcel.delivery_governate.name }}</small>
</div>
<div class="col-12"><hr class="my-1"></div>
<div class="col-md-6">
<h6 class="text-uppercase text-muted small mb-2">{% trans "Last Updated" %}</h6>
<p class="mb-0">{{ parcel.updated_at|date:"d M Y, h:i A" }}</p>
</div>
<div class="col-md-6">
<h6 class="text-uppercase text-muted small mb-2">{% trans "Description" %}</h6>
<p class="mb-0">{{ parcel.description }}</p>
</div>
</div>
</div>
{% else %}
<!-- Empty State / Instructions -->
<div class="text-center text-muted py-5">
<i class="bi bi-box-seam display-1 opacity-25"></i>
<p class="mt-3">{% trans "Enter your tracking number above to see shipment details." %}</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -12,7 +12,7 @@ register = template.Library()
def get_dashboard_stats():
# User Stats
total_users = User.objects.count()
drivers_count = Profile.objects.filter(role='driver').count()
drivers_count = Profile.objects.filter(role='car_owner').count()
shippers_count = Profile.objects.filter(role='shipper').count()
# Parcel Stats
@ -21,6 +21,9 @@ def get_dashboard_stats():
pending_parcels = Parcel.objects.filter(status='pending').count()
# Financials
# Summing price of delivered parcels (assuming delivered = revenue realized)
# If payments are enabled, we might want to check payment_status='paid' as well.
# For now, sticking to delivered as a safe proxy for completed business.
total_revenue = Parcel.objects.filter(status='delivered').aggregate(Sum('price'))['price__sum'] or 0
# Recent Activity
@ -32,6 +35,7 @@ def get_dashboard_stats():
daily_counts = []
for date_str in dates:
# We'll use created_at__date lookup
count = Parcel.objects.filter(created_at__date=date_str).count()
daily_counts.append(count)

View File

@ -34,6 +34,7 @@ urlpatterns = [
path('dashboard/', views.dashboard, name='dashboard'),
path('scan-qr/', views.scan_qr_view, name='scan_qr'),
path('shipment-request/', views.shipment_request, name='shipment_request'),
path('track/', views.track_parcel, name='track'),
path('accept-parcel/<int:parcel_id>/', views.accept_parcel, name='accept_parcel'),
path('update-status/<int:parcel_id>/', views.update_status, name='update_status'),
path('rate-driver/<int:parcel_id>/', views.rate_driver, name='rate_driver'),

View File

@ -35,14 +35,10 @@ from io import BytesIO
import base64
def index(request):
# If tracking_id is present, redirect to the new track view
tracking_id = request.GET.get('tracking_id')
parcel = None
error = None
if tracking_id:
try:
parcel = Parcel.objects.get(tracking_number=tracking_id)
except Parcel.DoesNotExist:
error = _("Parcel not found.")
return redirect(f"{reverse('track')}?tracking_number={tracking_id}")
testimonials = Testimonial.objects.filter(is_active=True)
@ -58,14 +54,28 @@ def index(request):
).order_by('-shipment_count')[:5]
return render(request, 'core/index.html', {
'parcel': parcel,
'error': error,
'tracking_id': tracking_id,
'testimonials': testimonials,
'top_drivers': top_drivers,
'top_shippers': top_shippers
})
def track_parcel(request):
tracking_number = request.GET.get('tracking_number')
parcel = None
error = None
if tracking_number:
try:
parcel = Parcel.objects.get(tracking_number__iexact=tracking_number.strip())
except Parcel.DoesNotExist:
error = _("Parcel not found with this Tracking ID.")
return render(request, 'core/track.html', {
'parcel': parcel,
'error': error,
'tracking_number': tracking_number
})
def register(request):
if request.method == 'POST':
form = UserRegistrationForm(request.POST)