From 7e8ed2b3cb7cbd1e924adf72ca3094ae50b6d390 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 25 Jan 2026 17:15:46 +0000 Subject: [PATCH] adding reports --- core/__pycache__/admin.cpython-311.pyc | Bin 8864 -> 10232 bytes core/__pycache__/views.cpython-311.pyc | Bin 22875 -> 24075 bytes core/admin.py | 31 ++++- core/templates/core/driver_dashboard.html | 51 +++++++- core/templates/core/shipper_dashboard.html | 144 +++++++++++++++------ core/views.py | 43 +++++- 6 files changed, 219 insertions(+), 50 deletions(-) diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index b93269356986b47662b9dd37ee8ba503785ecd3e..a145697c9bedf365ef189404695e7e208ad26bcb 100644 GIT binary patch delta 3099 zcmai0O>7&-72e_hk4P>_NtQ@UqW(q6mZcOn4A?HLNUrU~A_YrMTNMdGaYxiD{LAdp zwg}l|3nNh6B6cz^nj#ma2d8O$XrV)U4bU8VlLDe;7YL9Z3Iq*M$cPU`+e6({C)FgH!uA&?)})~aY;~q9KWgNLhpGy$eH(sKkHT`#h2+@?1Q(Q>CX-< z4iL#CU6vI8JxK}hH%PcVB=jKYt(y%vqMTOTf@ap&< zUZcXR6TCu)y}Fx%jX~v!Mn{_`d9OLhKPBz%1KT*-%o4S}Z*FTg_e<14qmNB63wY{< zNJm17<~(V7E+qfy3v7RU-UfZN(9!?jM_8gBI@au`_~xZ(cq?Xh5IIVWmMgkmxK6b~ zKBrOsnq}7&f>ASs0H3o?+6IKm|9ZTWZ(2{CIgV-@FzjkBqvoi_`q3mB45BpL zfMeWh>xqa8w58zLFOALq<~#h~$HV0`S+ptEd(xua1WT#d9urtfc=g9JCJ-h8q82vBe`6ag8~(j;i9}JOESJnu!$WTu z@=Q-8wM0t0nQF`o2keFi^>5yWx%^Dh_h%$Y3VC8WI?Fp|#k_7-Ea#ztekjW7KBdMo=mOa2A+#7s~L(raiOmuNTDSd#T^-kmVKq*G&U^f z^pi6x@Lf}NHJ^(*O1_0X%0yy&l$mc(X1Y$9l6wv*6B&umUXL2Kc|n|#cdkyH$e!++ zuJa}`rI%bc3JP)vWJ8L2SO?6~FvBp6vh5aAb)cc6{?6ZGV^GO3zZi}Nm)J?PjiW7) zrgd%>wS)o#&m`B35ZVs&_MlGC)NmE+{Ue8MhDD>9Wy8+sTSZ#dbi)B}wx&^#*xu1+ z7qBmLerZ+1y^n~(#4$b%da3i!F&jU^^9WRHUjbC4FM>V4T-*+x-3gwp2G4FdYNIzc z9NYe(9mnt&{?hxdW+zHe8OIs^G1XVDeC?mSSoFYn$`w zDEcB`cGg}6sO$YwIUJ#ukp zXsS9iRhg|?`nScup14Q1zH9%~MB=>D^*hqTcU+S$HjVwx0C2y%)h0NR;$!X;sf$mz z+xVu(L1y_Uo*zNT6W&eYVdq4gx%m77Ti}24DP)14lP{1QUz1-VY5qj+{MP>9*aA4S zx3GmdtEC~|<8i;OKgVYk#vbAUe}LTJgZ{rkXYRn)#D;yb9RE+SN@n;@>la_0pS=z5JB|hymUK7>zl>EXqYvfF%7GAgfv1C!4D9%9xNqW1A{>*y9I9z)9|4a zw+d=$U@nu?m-%V8EbA2LL$gUWlenqUTPs_n{pY695_rJ{6@V9$5s*evQ@xMNAZvJE zL?UdE|Dj`s{E$04V}SuM8TP3<`xZVS>>gJ;KmI`+%}+Eidt3Vs_>}s@)>c9u@_@e^TDXV}>;*K|lk7wkUNvJ?XHf~g3& z8tfjzH2^*l?k4Z>c(^Sj`ox>`Vx3Ac^g%eYbvOJvseih};L|1FItf--n)lH|$QJgH zD_z4ew8WzJ=D}P+$Eygh02m%|fT^PD$)yZ!K9>*B58(s;m##54&QPe)Q{3165$WZ> z?cOXiyv+@_vYO1L^W!V<)m6U~JaBuY-lWP^@eL(Dyu^o-;hN1Wd*3zU(2JRgxRB4` z27w%(V>At!1uv6^)HJq#InHPEN-;xQzRi9G1HjeN{;~C0&malcBv(cJYSO^=(Leut m#gy=^A delta 1703 zcmah}PfT1z7=N>WVd=8VF1xTGu!NeNLBqm-wdC|l}<3;D21xjg?&dd9~ncw{0 z_kAVSyVngWTgaqBq1|aLthVr_P9f}gZZ#nV$(a12F453rL z99Ob^@a#sXw`X@F1KTsZ?dP}E(^!*U|Mb{5E;0^<&{w1v{NWK@csRA!grCuOYm_^p z*)Ym>k#ob~cp8(*ZKif&8ZL#0$P4gs_zX$ce+u)L=VHu$VA&RgfK{TIzuS_=`t6E`i;n>X`#xCLXDnbF_GD4dK-OCbo zg}Yk1%CSVz5IpR8jjY3|-h2d)sqmjJW1M{P9$^*uy!UQ!T+(b4|97(~nD2|el*GZ| zC^sY_n%699o18j(S=x_wFX3Ejwo;g;R!q}@_!@lMx0pxYI?3yy!v|GzDsbjtZyEuU z&E^qs^{gU6wDI*Sa}1O6GPBe!!&0($7#)h>-tm+5WE+M~8V88TsaG4DIEH2rdg@;! zS4pEJ$FL+JnObUBb>w0npi1>U?0xto)t^TuultXNJB-2+gi#41Xj|MdsA)OHl1-1+ z+!pE(uET$+!4}*DHPnY-Jbjxa;n(!ehzKq?vi_+#t*#Vx2dR5R1kP8@y=y{Mu384$ zg0C~l^yBx=zfC7Ms%FimFSA?H2`-=iTz6%&1kU7^$K51P{?eX~H?j{RslV0aKZhlO M`cJtG@nFpV14|%zV*mgE diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index cb8f7bd4be5f3e3f5f727ce579d74753f639fb00..fdf6df421170ed360d04a0c805b967ea45ca8fb0 100644 GIT binary patch delta 2856 zcmai0eQaA-6@S+s&tHiXCygC{BzcYVAvbPl(k5%tG;Lu^M!IDw$+~n>ry<`>|t$lbKW4y!N816Whrm)i($VU49b#+ zm3rhhtHn92QSP zqI~6aP>j70p&{Qijl2*D%Itu>ZJy3SLE#}fzes67rXCfY2M?VAIOp(3sQf93;;ej< z7@ay95vkNZ6$=GD>bymq5d%R?UV5rAv^fKdKN6Y_$}w3ghCSufjJZ1i^5v6q%okzr z+FMO|oqX0GJT1wznjLC$&f{zLm}nPrCy=Z2Q(1&Wd6O6n7PHYa7(a_}4q+DI0>VoO zUj&Ha1`{?L?Z(KdBH-9)3+(m_+y^{Y+i-b4Yul5yF`vUdZ*^S`XRU2%Yuir-Z#<<~ z+fvp;8S9~}btr8e`sMzV^;pJwEMdyoo3eIq+U~vWy!&}&@8=Y|H)S8q*hdrQoTEAG z@TMK5ki(mDjAk68iHZl#9T{h5*10$B+?#UtW}Ll>zBboCtT@LNXB&3s;T{_Y?}Lh( zOOr}NU#{MpYiQ32yWmxC&+!F z<$LC=(3KXtZXZ*gJFW;_DPdqDBTQt4$+R%3Or1^%GZ|qT3u|-;hKN;gmN;ZjD?k&CsQ?%Oid(Pb2eRbb`>@l8C0!tob^f7 z!vZFZFsjadbvWzlNV__2w=R2?F`ps^mC=ym>PWf58CN*#I+J#tfzh*M07usi;%Goc zZ{MiazTEcCoTCYFRj1k354FY|pcCr2_|1~s6S(&?* z{j0vp^bP2K2kxkquzt5E`9y<}sD@Rblkbo%nl=w2r~ysWJfdmZIc;1^?H`wdm;(}S zv^bG?Nw=uKrU7k(d%ex^VcRE-STsB;ARv6)sn(J-#(5tevO<%L(5oo+;{0osMGdYb zT+CezfZFoRURP(YDth8vtTc?{Bolj2=u>&hSY6}(<}vyr&}baMqoyL-s3G(`I#e4D zMjLkxS8pD7`ms_Y*@>_dVK)LUo>n7#6(ND3MJPuo2+|yTud(_lh&g!jhIQTZ1*C#N z(87z`Q~@t=qB?+$qhC1p`Et?km#1SJ`a!=1@!Lo=wPF{pkuh+t=xlIuw1>%kOXKU^-w)h1D9@izEMm$cW-MZYPw)>)0n1Rz zGL*3lCHR%(b@wVU71q)NkEL_$ht0>y9MiXW$R*a<(y6@y?o=|+Qm(1O5*Mo*MfQ1? z*s-kJC=dH-VbOHpuVNpeg0Ks_Um*+3zNdlzF*vr7WdEKJAxq5C zbDSBvzo2pv7Vq{~eHn+i06hGdzw7|@!WgBr*{GJ zygv{N$Wi(>dY0May@K{vU^cKo@1OY}p>u(a?`tsr8q8MsZ$q!Mm-b1;$Y1tt*S-Uh z9Z5?cQB~bS{s6+$05Hj0tf~Ja<8RP|urt|mAVk~?U`8PqC#>(lvW+jVZzdq0p=k&l zOx`>=qiy&tm^6z}Na{l?hp>cjj~yOZA@4Hp;4FEYT^oE#`#!iIPkuP~6i~`%E)3-oAx?6yx~erCTSmKJe=!`}sl{Cz!=u%~nP%+CM?$ z#pK^crZn@YnuWtfub_pSvap*9TZrPep|}GmR-a(^b delta 1805 zcmah}eN0nV6o0qvYiUbqc~U6ypyfkq!D(T^fk~AG@5Ln2DXTgII^I)EJl|s*(>YTrbcJ7WFLPltIJHB%d*|m0$bc4yXpPC zbARV|&+R$)y!X}&xpj%;oimvX92@3Mkzl1~GH(5vM>;#AT!0T~qv{|TQ*+!no7vIM&2Rd}R%p}(awha+EZDdTj`I$17n{|Z ze}d*4#t8GVnH^{Kkk1!r0>+74*jv<4%Rh3UDXNL`fxJ_yM~`%w;rpe_z+FOFsbzjuRxj8216Adau}v6 zR`Ev|`G)*sMH5loB(ToD1Hx6&txFg?Kf(nI7RN;iw!wsMOv5gc&Fna!iE=M3wnS9p zGcI@nIc${+mYr@@xD>v1xQH3-)kQ=PVk1S6UW9CmZ zF*R$qP)!#ZhFFb@ybgcV)bsB!`jT86x+sm0T{8Ko{&wqV(4$VOm8!xR~T2MzU> zMOh|cdJ@*Gt}widDuk5Wv-&DA9>X<4nuAr1?~zfs*=X0EXT*I@{<*QAka4)y(go9N z_No5lptjjB9K*)xQFH(6!nP*O{5aK2Y=mxLX4Yo|CQR z{0-(Y%GX+nN|;1_8^Trw?Eg=~SL+`bK1T*2PyTvCKdBsLW(Yra^Uakzf04dOP#UIR zFh{v8ZH(}Cg_$&lkO}HTYYt%?VHO@fbC-Mxw>Ix5GvM8_g}=k-W%AgT*K|!uX138@ z)CCa|2>%lgCEtLwYb&_}@~-E!Svll;ZI*wXnpHJ{% trans "Available Shipments" %} + @@ -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()