From 3da5d477dfc02490af8995cae719e7f1077eecba Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 23 Jan 2026 15:13:31 +0000 Subject: [PATCH] changes19 --- core/__pycache__/admin.cpython-311.pyc | Bin 5846 -> 6651 bytes core/__pycache__/forms.cpython-311.pyc | Bin 13305 -> 14261 bytes core/__pycache__/models.cpython-311.pyc | Bin 18005 -> 19596 bytes core/admin.py | 26 ++++++++--- core/forms.py | 19 +++++--- ...ucktype_alter_truck_truck_type_and_more.py | 41 ++++++++++++++++++ ..._truck_truck_type_and_more.cpython-311.pyc | Bin 0 -> 2088 bytes ...uck_truck_type_ar_and_more.cpython-311.pyc | Bin 0 -> 2002 bytes core/models.py | 27 +++++++++++- core/templates/core/post_shipment.html | 11 +++-- core/templates/core/shipment_detail.html | 16 +++++-- core/templates/core/truck_register.html | 23 +++++----- 12 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 core/migrations/0011_trucktype_alter_truck_truck_type_and_more.py create mode 100644 core/migrations/__pycache__/0011_trucktype_alter_truck_truck_type_and_more.cpython-311.pyc create mode 100644 core/migrations/__pycache__/0011_trucktype_remove_truck_truck_type_ar_and_more.cpython-311.pyc diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 5fb3aff3a54a0d4db197e54e66096d730d25d2cd..af6442b571008f1a9ccc85ab4f52381b5c75f172 100644 GIT binary patch delta 2136 zcmbtUO>7%Q6yDjj9Xod7zg;JGVte!7r3o#Nq*4h{(f}!h7$pQ1g38upSIIX1V|Lw= zA~ik)#I1?uT&W-dN_xzhBPT#=kcFZZNIi0@5~-pR<-ojII|`0(?0P@XyqWL4@4b1u zzl}V9rTzQ1wpNZ_Ki)HqQrk{@C%-1_oGWza#bq%sElY^gS~OoSmhV{ZKpfBM=w|26 z-T;d4JQ^5DICJ2`rHkJoj(bQS=i<3pP77>tS{r3CLRSMpYC>qIgkX)((p`)APm=tA zyeulY$9qsG$)F?&@{Xw`=fQBZgsqjtMxrC2Ulctb(BkIr`yGiP=^I1aP~Ko>wanRm-q zQ!r!>Wf=9=AxH;il0xO=ejFXFymJ^yRpt)GWMv+1hY2KdUrr0`#H zg=}6|vpBQsJ|hPr4*@htQosfvk&8Z&X%L4_hgZm+%R(1O+8yhEiSEnbfhKN7zy^>Y zU%CgK8jeur<&IXS)zRs;Bbs5Ba@h@)Jadn3UZMm$SiD`(v8t9$9YX?moLUv$4q9+d zsznb<%^8Jt+i#d^wp7B!Te_A}&Q=^GuoMSj)R5;W*Z^eu)Jor5um0oc2ekI$L}mUk zGFq8~+o}C1q(FZ6gyZdX;YDn$8U;IApOe2l!_O{SWi^xF^^V3^$WrowNYb`NISs-xr=ZxGFqKfGh9 z^RT_)EEd29@G|YW9;aCr_OJQ+5E>_+w=Vf**zhrhJA>pPB$6ks5%elS{wpX=UiUxo z;eNVCJK#EbEii>tayQTs&r*}=q9Dt11A!NqHQO0ycN-*j0;hu7IUxRgkOQaMj2iW%mrWvJ= z97oE?BCF9CV>k@kA{1=z?X|3B!n+YAUq=%Q>}v+!4fbZU_mcHKYZ!KTto$rS!{Pkx zoyZrpa!#MbUr-02%DgTRUMx>(kGTK!BM-$Jo2~;SRgrYW3n+EOorP_8H6$Oy!c%}_ zf#YK*`&&6aRFSq)+r9&osG`IX&!clk+*#OuzbXwJ!@^Sl@Y2Qh3v@=1^x>v}#vptn zY)jQ}4}>3s@MA#isG=Ci9XmP+?>#{ADvE=35rLa#xcx>|><3qi2z)Ifa7I-#+Pjo- o;!Zd~Vik$tZkD-ghF_Jd!8Ev=W$tE~J6cMIMlQy_aY3W}3mi%J7ytkO delta 1513 zcmb7DOKcle6rDF?d;Fi+GviMbrxQq`PU0j&PM}I7l#ft_nkH`34@m@5%N`OJdmPP- zNmt-S7AzB8Bz7RNfL83tqAaRPm5{nZp^}BFk=V0>MCz(YwC~Q?v<==c_8h-=&pY>? z_wMuGh2JLP-^XHMhCY+Gtm;wZAf93Gvj=Ali7*wu5~@jcc|#@)%jo1*>fpx_k_Lqx z;WJ(U?vPw4y2n&vl=hfxhj~VsIAw%?nf?y5%;rLUlu2|MSS10Hg0E>jN#kNS&JT1H z$CQyMBX^mJoX4PXeDvgZgkgT5ulKOb1*VdsigZUY8mMH}7&QxDavOw)zqkch@O?^) z{^a{CAX1Sj!km93kn@H|{47lJvr})-smeO>rlp&jhG>-Px;ae4D|Z8C8dql!vIza~ zyI;u;;Ly!8h$E#70+6r-_xPk&M1dnd3p>7?5WZ?Q%bzS%>QzJaJ7G|Q)5Qs@a)idN z@mk$+8eO^T|4&^kaTeiJ?JR`?01rdrz=}DF^HZe?7%RXxd?s^+mPt;uEzG?5ZV8oh`mF8hPF*)_P3w4&Uq&jrWmk=oU2PbSY~wj;rw*mJo%3i1LBUhcETW|x zTH1Kk()msg2B8=c$Q;~^%nZJT%2S(L!WhCRo+CVp#JnCZ9XgRW3CY7h(W?Qs+eP>w zHcqBsFSbZ>@F@0Ygl<%#N;P1v!h`rcxeU+aX=#myEFT3$QCg-ey$)l-5Sf8xVUy$z z?+6Jl@*!Q|a9g@BLpQr6VwAsuYjEnDP6X&G~yO-ZFv3^S=Wgar~oXpAk zq$On?vaz|Cw5J?H4mLL=>r>7lC(j97KPT5+;$)-ZxS`{?TkzAykc;t5z%wiShc zd=KE1?yn_&K+0YEi{H*eXx?F-v?^xPDPi@qiX76s}1;`OZ#6cJNt zSxFK*&hMCLI^>cHiQg}7%Kk2@IdHBsi2_h>WpgAb zkQSh+d^{__Rg$#r0hkxUbY5(v8HXyxAYdX*&QKlFTVY z6<v);RyO%we<}v@iQ-^&ptVt$>&tVppsPLInqcM%qK0(DDmKs=+m3p40ojevi?H{KJ>crc8Ol`br(yebuy)$&D}HR>z#F#% zGsu(U)LY-#|1^q!3Bic4L>Vs8Qt}MKF@T_sFzv^YfLgN1m(WM_t@^uQ;1OpN&u^r% ztLK@Wz*5C{Qi+W+{i-P@%Ta}pG|`lanlfepd!`exgB%6OiU6Qix}Z7#c~})fw(@A%mh3P;u$qD*v_nHF-V5;g#I;k*QRa4(^j2y(^fbdh!=9u3J zdln2IEke-eWDwz5gy(6vq0z%^;$gi{v&V@nXYpi%Q_zCRNwc0e<8C0U1}$dET9m;k zhJad+bA0my!MdepBbj;lG|plGsxh6*L@^j^<5xiug`RGDO1q^(W2=1hqxRl*Etd|a zNh%I9m4Qa$c<2{s+v>wQK^E!Z)opcfP4H8C`bTeTnf7Vd=EXfXzz4U`4{QjWVi+;g z`0BOvuRe1{@Be(QpEN(Xq8^!_v=3Qj;~*C_J+iaHfDhA+*&MX1jvSVXXbx&cG?^GZ zLpIT(|7TB=HZX!Ym@vQV;Y{(pVKsWHn%v>O0aU?0=+!P7s z5@Dgq;+q-oMV4O6p+m@j5`l#(s;p)Y?kl*eevL*GqlsKJis_c!#dCDb(l+*|O`+Q@ zH^-*N-q62oDK)H}HLjaAc9z(eJ;+T%tut9gWk$V#cgEn$VsI=b$p{h=ury^)1N`d( zSN_Zi9ua(1fg_daJkAy>%ejys_Revi4K$CBlrv+kb#OS5Nhzbb$CASe=HPgEh==6Z zKtJ>}(2!rG&Oo=$AlFgJ*F^vBHH${sB%A5Dm#u0zmKx4&-)j21fESLqzXe)CM%5xK z**HmLa*6b)YIs#iyfmCsy+nCApCF1HtqE%?Ns)FpnDhXnvJ%K7{c2W=atv(JMkl1M zF`O1m5b&`s40Lv=9mYo>OkHb9D7OISO!cOrJkHP$TP&4Z?26geH_Ew&~{hI3c zNFVABg)2dm%_$jj1#PAP13^n|9MmCic^qgj{wv6M58(pBN^f8M4sh}`zUG2<5U~PR z{O_7eJpWyKaoz5*YO!MFw%So(*;0)!=M{1;tK`UDyaU!V)ikUmGtnHxVQ{f2s1~#v zD8;H8YJ;j)ZVIsS6zZQy$n3BvzwFmJx@Y~JH4^Sx@l{SD2O&p$I*9fNlXSYnCxrC$ z9gm-W-0@Q@9Bra((vCYi9_)vlz8z>VPFb{;nf@dAT#r?@$@WQMN?d*_PC0G}a7w~Y z8$(V|rW;{hJ5m%Et>4f~rvq-+W1{XW8;*kB`p={ndh?a_9(qh~BNN3Qn+^7K&gEt^ z32af=kOkQ#yXmhytH+>|huiqd9JaS%`ChqEhJOVh3|@_VS6 z?W?SrcK=fCPjH;931RJG1C)DY{R+xkYW~o)$gOaquA*l<*NwShYc(axjTxSytT8Lt zo@4cS)3fPhKBcfOqToKZSgWNaCo;Aj&CuQjex16z_ywFGy6+>2k-5U%4bvWf^_M&c=91TTZa8BHW9%%ezBlT0E}N+AspHUpOQEq`v@I9~iq zw=7ttvSkB7KRp)SArLFQ9A0IxA^jM=6%O!r`kSychMgI40;qZ{Bt*ff=_vlIWa|;+ z>a>49nbUkId5tC_dXXXRlnU!7oR?-S2kZe z-ONKr^f-)*R~_?6U#K#7dU!l*R>tvdS9_t|0tx81s&XNEam&^|E8h=3UKz*pR}1ru Lx9|xP?9lo@F7L2l delta 3800 zcmb7HZ%kC#6`%L!|Nmit85qPF6w$}x00N3z6|-2ZZKdm~1!h^taqbfyykXe;9=l4r zf_1lAciW)XwC>6#{m^I)+t_rr*-e^e>8Jg)4JIaKU(#m3^n*#$NTeTXlcwj~2ZIjS zWbe%UIQN|M&O7(qbI!f|KL78bz#YHeV}Wt&Jx%#+^R+;g(0*-uTdQCp7GhI9Id96x zX}jvr1yTV{JJetAoNrr*OJ+0Hh}#XMM;1oHEFnaLDt1bU2~Kui*i-m}a7}bng4Z-sc*T|wsvAN6P{p3h6IrExq-{rKJ!3e|DzZv68Uq%MBh(@^ zBkW)o94!vcY%YB4cqk@OOA-xR7R(q{O{bDbYk+46Sxtn$iG=z1W}qiquRAK)SMKi! zan|J7@9hL0Ekg)1-Los!f@B>4`k?AEHSA{<3O3u=yr*spu8Uex?C&0yv!iG7=Z=hx zPw0l@xU9-qomMcbchJkdeG$|qYt7fW3YWc|f)Fpv`vk$!h*l)_xxX`n0ifSNIDoL9 z1q1PL50a=`KKMCfM+D=H)0B?0CKO?N^l z3Kd2x%0x4jLhMJ8tJyHH4TqVrv>tWJ0U(_kkjBmLm7Gtzjcgv^G*YJl3|C$sPh%>U zW-mb%!t&8?o3AA7vuL$-hsDDF8r>!l>v4-@gLTn~>}XG(=CYt(9OxL1$7e$#;`Uwh8JO8D$9 z;x>I{^VJ^nJ8&2aC6WQ?gPUOzW^ay*mrhfBA?Q9gZ4#H3SE&HOT;b=|c z&26*IpC%UuQuuvUxj!)SU|?jSWfZ?L^?po!5K|Xxn{J+*O@Df7VemElo_hWMAbl`M z7uq!Z*6R0b^#`?j!M&+fn2LwWJ&!B^SDg4U`zf~4-n+Ka#qbVW;-&(s6rl^<+y^jS z{5%q)b}+skmXNoM5GfIx?^m8qevw$&FXC~J7i{BrT+im?)afLvc@noeh=-LW>VW56 z$(>bR6f&y5&6)C&0OUsSN!jsXWjrU3=~zT&dN>U)k+m#U#&sn>W;ouIm7!ss9jiN0 zi-q+N_pG?hH2mHjAhUsodgd30YIl?vM(H7h3kcH)CD9M^EqMndDfnrBXK!ukXaCr8aVqG-Z3S4jt@Pps zb}k_gVF1mP?qUdcaXl;{Z+Qa&jq|j>1iRSJu5bGrj}i}!89EH>6I)BNrL`DWO_#^% zPtl8?0rX1V(okVLDhZVto3~JK17RAWBtSeq_M0HdvE_#8m74*3xwg8%woeJd`>b5r zH-$$TeG!2>zIH}p(HgGTCuDkFlXbcuRe0sPhh=py=YEk7n=H_F5*{&^&0G- zO>wrh>44-Wf&XV?)rVA=U1>V{+HeX+32c-KO27bSyE0axK`Dw7Cc``A{#^^dfNt(fS);1)%>~QoLjGY+WJct z3o(_jwD|zz6?pir3u5dxbe1{znIjb=HPE6qu{W9i1DD0`8I%4#-lUqp zpI0YxvUx?FLFqMw>i}>q`PHhrS$d2`Te_xZk@+Di*eKdFJh{xdG*N~WT{8ki&MLW# znjTj(Sy|)nGF;vH9Cl2t2d;M zefMx)$;$k~M%^gnWrw}TEbJ>tVbiBSLAZ+WE`Z@a1P8DA9B+*8A=7urblv3hrtkqi zaSI`az>A}@7RfuSfbMAj6`9uhe&O=2VbRBxP~0n3v;VYr))`e~Br`UYPfqBHswH)r z8PnjFfSuikR*tcOj=11w=Q|R80c7Ci(Xe5KQ-Y+MFP6{wS$PSSc-?X@)?7o+p1AhG zzdIAEe1LueQ>=9D9(&ZWsr|@;RJEq2?z*bYw5;0JNz*o`^D6YJcG1?Vf3#geMg5poW#`-% zOnA1mUij)8y0$l0ni-+PI7D)>Qf{mdY13g76$XN)kP%go}`UZc!j~yKd^1#9b;~Z-%a0 zG;|8S%0yIi+%WCR(>y7#7Q2HPwfDv}qAsq#sD-BCQBrrVMu1`F!Y~cXo9;Gv~p03qd679vBLQ278o_ z09jSeo|rk^&bmEPG%#-DWiM~ow3Lr@P&-hl3&D-xLGU6p0jz>2vKHWE`ZrrzcKYZ{ z#dPd!Y%+h=?U@OjFSzDjmvXO58l1|Xy4ikR2|HIYRFE42Bm4nMtDq6qQenT>vNSTk zKN6*W{~GM1mUr^Dsr1pNsiv8(H%ygDQ{{Q_!VtV>t)*wTCG$PAh1RLDq@j$Dw8Lj) z*Yj-5U7|NRfXsWK+nLAcVvR*+@)(Qh9kIbDI-cx!K9V#wUNbeOOpPa7XU*=(-jvxr zb9CnDdFK-kJ^9efRad)`=3Up!yHe&|C)?+8G`jjZArt0Nwy;!T(CW(PgiKH-ax09f zhi$RspIM)mSTJ5CI=T%+iC6P~OGsnlgxN|+E1ND1Rr_)DXg>`g97N~>kPRa=JR;HP z7(L8xY%MdkVhzH2)>iZ}u#2{ovkuE^WLLscY$s$-qSmS>#rsjM55PxcG6>tGi#6NI z?YluD>tV)&p*~qJ2K$212<>HITM41;5nBVfkG*OO9>Sh!HR=|$2BK0|a9G+Al!in) zj1@kFL4+`>|ftGe4f3eIt`sExkSJcK0s`FW( z@M6n|d1_+Zs5-pnEZv#@FRL&ME1$DsY0JcdjLwR((9G)2ve;(H!YjqEYGMCzt{@XEyxMvDIpHa7r$D~}RX(j;$VcaoLRj|?1w(`2*@wWl`a@yaxKst< zvATT}7!eG;Cxuy4Vanv06G+}&vvxgHbl)}M*6Bkb8jtmqKWCv4Hh*+n?4;q z1uuF4fDxB1MzJTl5+H&O%*$^Pa}YJ`ef#++i}w4tRbJ`7b?@xnz# zghvs+k8lRzM+mCedIDt#cx8y(sb$YpuHIf+d%8DeUv(+(<%3uJ$Cib+f7HA`p8(wUg6tkbO4>NeqJ=O!2h zy?IWf)4}!xnAbw_)cuOU%qFTG>_~N+6Ni>P*!L%{R@V|24}_vBq{J;sOlR{eecIx< zmAPs>R;#2Nz}qfQVxfrghigihSmS83#jPqITms%nH=tkCm(=V`hMi5||6$CH01P>eZp zQKUaOGAxCn5r3G%l`-Vg-t?sGLhUBf$lj{Gtzj2v(tA<8I1q^h`$CfFPxE{ku6I4E z_p`fwhsihD)4oIGGW){!3E)SoE69t?xaLpfm+Z|od&vu|rmm8_!tSZNk5sdt)b;Vh zN@uVqI7G^jZ}BeNw^E!{`YVJwgqILrMR*0_WrQmT=K$ma@ceLU>6l-H^GOp}f!kI# zr!C>$i}EA7S#?G)qxuU7E(Dx)^~PtxfEh(+l1WGsjY%_0N}I?fqRi z`Sl~o{-NZzCg2ap@FCKP=Wv2_;X%X~2)zeT1_&a+WKKn5-@2y>xsaHvH*3gFc4I?( z5syvjHGr8txN(FWVXtqjCx2z1ZEW-X8b^Z;o^D3qgS!KBDTEw^zagAp(ruNV-#}J2 z^n{1`vMV1Zd|nhU#lJ-Ufa(ZW6R+R4f#@*XGi@nh#SQ<00QqS{KMcUX>2@;9&TiVd zHd~MHU=zHr+@3Hv%}`XCAD~<>=k^C8foPOcSP((Zi3DKRv_ke4vX*kAK1Aui z*{63_>tNZ04-=lIK@AD8$C_Knf7zd#n;Nh`xu8#q!lCl_PzkqQ09m}j2e4M(8yo_u zoGU%pGc+nn)X$n*oTayPfLgjf8Xg^?A2Hg}rqe>~{e)dC HRgwPz@l+cc delta 3268 zcma)84Qx}_7526Lo}C{%{)rviiS0Nz1QT$eKu9}6ewyH>P}oW+;EK5>?=3h#c6$AQ zL9>ObY+_SdwLPk;fvUEvmci<6O+8KfLu=WO)U{~IN~Y}%ZPQw&Nu8=h?WUiM@N$B;rxW{O~#`6E{Bt`?Qp=E4nKrb@^u7<2p%BVji8#xcxFuI$|?RJ*xEgC z(_#fn^#{g#PzfDIH#l5ZSZ99D2oa{T;Y)hW5f78VtQv_sH_~zNPLXseu4l&kboxC;2!AmUSvn$ zWvf@e)d+uW_rcSqxI;D!nbAaRxW{FZ2){OkTou?a)|f~$QCUJ`o?`fB@hLQ^EGOLl z_T!cktnwn3QL4yQP8rY>K7|&y7V{=BM9UoztBQ%pv)%#ER)SZxg0~R^lgdg&YS)O4 zrO0tqCfVTS4gLvd377U2E;Wyv=KZJjEE%TF?cIx zFAe)x8d}!8g#DQ{8KyvI_!aEGAKqs_jh6hY1hlbxBWt0ju{o+GT^~swCpb&+HG(Gz z&Ja97aE@RSrW@8+z#2JpGnOpCpb8Vq1>?T3fgzguR@*$Y<;b~i^1ID(VSK?pS4 zoQ@^U5{4hY`p-wz4 z?rMLQ&C)4Cv`5s7gZev&Bxz2OteuqCV!>dz_$O5)9cAW>*)x0q^eG8Kn7C%b=_z zGCZ+ZQfj5H=I}6Vin+E>e5yFeGsnlU?&R`l=7g*ol9CiLt(=Ce1kH-S4_}P+3ZJ0l zI$Vk6SO7BjT@;6L%tyfA=lkpt>e2x%90Kh%YCEm%6D^rjz?@tZW$I7NJ4Q3o@ez3^ z*JIg8m1FiDnC$xxymtR1@omgEuUif0c1`YCAo<73$~0?Y_4B&baPGw9_yWm4URFNH NU~IQLe`a?j`!B$M%WePw diff --git a/core/admin.py b/core/admin.py index 833de05..40daf30 100644 --- a/core/admin.py +++ b/core/admin.py @@ -4,7 +4,7 @@ from django.shortcuts import render from django.http import HttpResponseRedirect from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country +from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country, City, TruckType from .whatsapp import send_whatsapp_message @admin.register(Country) @@ -12,6 +12,17 @@ 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', 'country_code', 'phone_number') @@ -20,20 +31,21 @@ class ProfileAdmin(admin.ModelAdmin): @admin.register(Truck) class TruckAdmin(admin.ModelAdmin): - list_display = ('truck_type', 'model', 'plate_no', 'owner', 'load_capacity') - search_fields = ('plate_no', 'owner__username', 'truck_type') + list_display = ('display_truck_type', 'model', 'plate_no', 'owner', 'load_capacity') + search_fields = ('plate_no', 'owner__username', 'model') + list_filter = ('truck_type_link', 'is_approved') @admin.register(Shipment) class ShipmentAdmin(admin.ModelAdmin): - list_display = ('origin', 'destination', 'shipper', 'status', 'delivery_date') - list_filter = ('status', 'delivery_date') - search_fields = ('origin', 'destination', 'shipper__username') + 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__origin', 'shipment__destination', 'truck_owner__username') + search_fields = ('shipment__description', 'truck_owner__username') @admin.register(Message) class MessageAdmin(admin.ModelAdmin): diff --git a/core/forms.py b/core/forms.py index c9de2b1..b48d4ec 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,5 +1,5 @@ from django import forms -from .models import Truck, Shipment, Bid, Profile, Country, OTPCode, City +from .models import Truck, Shipment, Bid, Profile, Country, OTPCode, City, TruckType from django.utils.translation import gettext_lazy as _ from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User @@ -64,13 +64,12 @@ class TruckForm(forms.ModelForm): class Meta: model = Truck fields = [ - 'truck_type', 'truck_type_ar', 'model', 'model_ar', 'year', 'plate_no', + 'truck_type_link', 'model', 'model_ar', 'year', 'plate_no', 'load_capacity', 'load_capacity_ar', 'color', 'color_ar', 'registration_expiry_date', 'truck_picture', 'registration_front', 'registration_back', 'driver_license' ] widgets = { - 'truck_type': forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('e.g. Flatbed')}), - 'truck_type_ar': forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('مثلا سطحة')}), + 'truck_type_link': forms.Select(attrs={'class': 'form-select'}), 'model': forms.TextInput(attrs={'class': 'form-control'}), 'model_ar': forms.TextInput(attrs={'class': 'form-control'}), 'year': forms.NumberInput(attrs={'class': 'form-control'}), @@ -85,12 +84,16 @@ class TruckForm(forms.ModelForm): 'registration_back': forms.FileInput(attrs={'class': 'form-control'}), 'driver_license': forms.FileInput(attrs={'class': 'form-control'}), } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['truck_type_link'].label = _("Truck Type") class ShipmentForm(forms.ModelForm): class Meta: model = Shipment fields = [ - 'description', 'weight', + 'description', 'weight', 'required_truck_type_link', 'origin_country', 'origin_city', 'destination_country', 'destination_city', 'delivery_date' @@ -98,12 +101,17 @@ class ShipmentForm(forms.ModelForm): widgets = { 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'weight': forms.TextInput(attrs={'class': 'form-control'}), + 'required_truck_type_link': forms.Select(attrs={'class': 'form-select'}), 'origin_country': forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'origin'}), 'origin_city': forms.Select(attrs={'class': 'form-select'}), 'destination_country': forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'destination'}), 'destination_city': forms.Select(attrs={'class': 'form-select'}), 'delivery_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['required_truck_type_link'].label = _("Truck Type") class BidForm(forms.ModelForm): class Meta: @@ -127,6 +135,7 @@ class BidForm(forms.ModelForm): class ShipperOfferForm(forms.Form): description = forms.CharField(label=_('Goods Description'), widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})) weight = forms.CharField(label=_('Weight/Volume'), widget=forms.TextInput(attrs={'class': 'form-control'})) + required_truck_type_link = forms.ModelChoiceField(label=_('Required Truck Type'), queryset=TruckType.objects.all(), widget=forms.Select(attrs={'class': 'form-select'})) origin_country = forms.ModelChoiceField(queryset=Country.objects.all(), widget=forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'origin'})) origin_city = forms.ModelChoiceField(queryset=City.objects.all(), widget=forms.Select(attrs={'class': 'form-select'})) diff --git a/core/migrations/0011_trucktype_alter_truck_truck_type_and_more.py b/core/migrations/0011_trucktype_alter_truck_truck_type_and_more.py new file mode 100644 index 0000000..b09a5a6 --- /dev/null +++ b/core/migrations/0011_trucktype_alter_truck_truck_type_and_more.py @@ -0,0 +1,41 @@ +# Generated by Django 5.2.7 on 2026-01-23 15:12 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0010_shipment_destination_country_shipment_origin_country_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='TruckType', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='Name (EN)')), + ('name_ar', models.CharField(blank=True, max_length=100, verbose_name='Name (AR)')), + ], + options={ + 'verbose_name': 'Truck Type', + 'verbose_name_plural': 'Truck Types', + }, + ), + migrations.AlterField( + model_name='truck', + name='truck_type', + field=models.CharField(blank=True, max_length=100, verbose_name='Truck Type (EN)'), + ), + migrations.AddField( + model_name='shipment', + name='required_truck_type_link', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.trucktype', verbose_name='Required Truck Type'), + ), + migrations.AddField( + model_name='truck', + name='truck_type_link', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.trucktype', verbose_name='Truck Type (New)'), + ), + ] diff --git a/core/migrations/__pycache__/0011_trucktype_alter_truck_truck_type_and_more.cpython-311.pyc b/core/migrations/__pycache__/0011_trucktype_alter_truck_truck_type_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4aff7d5d5df6bc43d4ce97885ebda567a0c430fc GIT binary patch literal 2088 zcmbtVJ#5=X6h8h)7G>F%WGAu`+3_FRFiowb4LTJCoWw5DIvQdpMFrFcN_UYdQ>1dF zlGyFwp+l!OTQhWaQ^bSEj2=34=s*J;gqsSqOEwwyl&N<|QEFVH9(p9-y}Nt&z27_j zJT#O9to{CjYuMhwq%Y?sCx4#JjO?aGR7xH~xdOX9k*&|8*~ zRFlez46xeQgk;2L;`M@cHU)UbXC?O;h(G1d1a(8e?W>W0yNu^Fm zsZ4HYcld3e9?CTZji5Bj{3P#Y-(C|IY7rtDMPsKRo;!)Sd;Sy@kspqPa%fzj4EAuD zpEy+?ipF)8!LZe%_<{OJG>7u&!tTW#mZ6uuES;fo6czrb#)-2u*3@zuO|sg!M76t7 zO|Sw{s}8~R=Cy0ruR(X+Y&Nj%L4;k;v_;v#s?)MPve{pBh*>l3-n?NW*x(r2Drr?W zRyUiN$|hP}qVk>Fx=K?<%X46rV8g?R4mOF|Fc{nh-lUp~iD_8o7N)7km{c4WL)&Oz zs&e`ov50PICB{x&UM%UNnvJK>!gkGDCp_MCfD1x{L}Cl~bX}pbie=avB+Dd(*j7@Q zHpOk*8tn6~E{8Cq|I`kfR*M*xu8=fW5r1f63%PW_X@v*a#s_LY7C=vM}RQ5I$-dmWVDJA>70^ z!gkffF5#CA9lRwHdY3y%_`#>Cn`Ui+rFw~ni)y#l4HB}+1qKTEoRam;eyiAi$6L&AMU%(Ml2HqIOb*F)gtqLp7RuMnN zRi>I0pEzX0Z5mZvyId`#rlK zw|h?~4zw?%jv|l6x0gFfpk4Yd86+m#nZh5LbAIm1v&TX1$}9D^Ill~joA^2RAm;`- z*H3%xOwP~i&(8;WeQ#y|Yd^nokY5S%D}H*low?u_u0CH13Rm}T?BDVq7=EF0P^bij zil44_2Gp_PP6|xF-+uQ-C#IYm?f_0k2DRiNVC0yS&N$E}xiJ&%9J6Plot=61PLQ2> zG4^WKU;fI^t{r68g6tYY?bJOk2d+qEj-!}VVZf|w}!LMHii}!=Y zwP3O4TieIhlk)3@(~-dqyx9YNJo(* niDg}y_Q6#6w!vlpw6_zVk>VZjZ}Kb|q~{L#!tp7q!iK*A7_K*; literal 0 HcmV?d00001 diff --git a/core/migrations/__pycache__/0011_trucktype_remove_truck_truck_type_ar_and_more.cpython-311.pyc b/core/migrations/__pycache__/0011_trucktype_remove_truck_truck_type_ar_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ec66c0ec98a1a50568ca72b7f0f81a4a68e71c2 GIT binary patch literal 2002 zcmbtVJ#5=X6h2avEK;(qAKQv-*|m`%jRMDVS_6fFqNwA?rKEs5u$1mBQ>IAe zNV&1Qc<9ir-kPDa+oBpWX2_7O9ch4ra8rR!*=X2PrrsS*sZI@K=uv$4_wIY&`{C)A z;b8^Pmi^Jz|A+$cH=Bfw&Urh#PrIK01W+(QRiM3Sh^ime z64e{-j$HO>TWmz&C``fh&tf-od5<%cLqwQ`W8Lw~R=5U_J=1~{Fvo2s`e!7RY=%() z%~-hJ9O;in!x6j&^WDkIzILasV3g{g$il+^vN!rZdkv|YhSN0XGeq79b4?R3)h&$3 zy~V}5i>ke&w_C_`RETUxH+eazb*p1Kcz>{IVZEW7{dLWRYKvjW72K)sR`%P7h&rsS z5%J;uqC}Ef$FbBpMw){lNwl%v(kR?6+9$G&u&x>U0V2sgglm?KR8wmqA~E>}(&!w> zn{+sP>%nG`SE=?)HIUhGb})-J8Dfg6hC{WLtzt1kqBTP^cX5VlaJ2)4Q=4Vn4iba0 zT@(YD?7yw6ZKH!VqZq*~JtVfRBLmuG$Z7|lN7P|{l40Jd4#lJdI63y&a0h~u@i3kw zi_z1LjuBJ`hYm(q#Iad`EC$ro*T>whJk014RfZ3rMuAH$LxdVg56p+rnlT-|M6o${z~v8 z;#ll(-B*D8!4HZTpXsFwf2GIW-0h=1FL(Q;^ydw?s=6k2bM{Hj_HwqHa(d~Un=d|} z@bbkM<=5Z2`SMA=?B&aDs?tkOx`p}YYhGdg#nS6l_lf2fYA1!7SE#wEx<4e1jrd70 zcc=H^k{^wXkNALz(S)p=0xHg#@UQjBrsfIA_9-1G&JsPW5tgz4Xmq=K9f1 zFLV9Zv6mCC^4{`8Z+XjG{@VSf?E~<+_*kS}_KA4P2ScRdoC)Ur3`3mmF@w|Z zL0spE8ys;%WQZH$yNGwDGO@!)?7<(0NhrohJ}8?7SX&7Gj~2q(!Shs&$o+j@w7gD( zEPljLIMfmyy^VhwRQ_l96FQ}d1$K=JKOzVM&8#rzg4y8L1Gn6(etv9Di22~Z;z;pQ NH%{5c`4zjI!#~zy9UK4v literal 0 HcmV?d00001 diff --git a/core/models.py b/core/models.py index db726e5..7a45d31 100644 --- a/core/models.py +++ b/core/models.py @@ -32,6 +32,19 @@ class City(models.Model): def __str__(self): return f"{self.name} ({self.country.name})" +class TruckType(models.Model): + name = models.CharField(_('Name (EN)'), max_length=100) + name_ar = models.CharField(_('Name (AR)'), max_length=100, blank=True) + + class Meta: + verbose_name = _('Truck Type') + verbose_name_plural = _('Truck Types') + + def __str__(self): + if get_language() == 'ar' and self.name_ar: + return self.name_ar + return self.name + class Profile(models.Model): ROLE_CHOICES = ( ('SHIPPER', _('Shipper (Need Goods Moved)')), @@ -73,8 +86,11 @@ class OTPCode(models.Model): class Truck(models.Model): owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='trucks') + # Using a fresh name to avoid conflict with partially created fields + truck_type_link = models.ForeignKey(TruckType, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Truck Type (New)')) + # English fields - truck_type = models.CharField(_('Truck Type (EN)'), max_length=100) + truck_type = models.CharField(_('Truck Type (EN)'), max_length=100, blank=True) model = models.CharField(_('Model (EN)'), max_length=100) load_capacity = models.CharField(_('Load Capacity (EN)'), max_length=100) color = models.CharField(_('Color (EN)'), max_length=50) @@ -99,10 +115,14 @@ class Truck(models.Model): created_at = models.DateTimeField(auto_now_add=True) def __str__(self): - return f"{self.display_truck_type} - {self.plate_no}" + if self.truck_type_link: + return f"{self.truck_type_link} - {self.plate_no}" + return f"{self.truck_type} - {self.plate_no}" @property def display_truck_type(self): + if self.truck_type_link: + return str(self.truck_type_link) if get_language() == 'ar' and self.truck_type_ar: return self.truck_type_ar return self.truck_type @@ -136,6 +156,9 @@ class Shipment(models.Model): description = models.TextField(_('Goods Description')) weight = models.CharField(_('Weight/Volume'), max_length=100) + # Using a fresh name + required_truck_type_link = models.ForeignKey(TruckType, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Required Truck Type')) + origin_country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, related_name='shipments_origin') origin_city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True, related_name='shipments_origin') destination_country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, related_name='shipments_destination') diff --git a/core/templates/core/post_shipment.html b/core/templates/core/post_shipment.html index 2a11611..62f7932 100644 --- a/core/templates/core/post_shipment.html +++ b/core/templates/core/post_shipment.html @@ -20,13 +20,18 @@
-
+
{{ form.weight }} {% if form.weight.errors %}
{{ form.weight.errors }}
{% endif %}
-
- +
+ + {{ form.required_truck_type_link }} + {% if form.required_truck_type_link.errors %}
{{ form.required_truck_type_link.errors }}
{% endif %} +
+
+ {{ form.delivery_date }} {% if form.delivery_date.errors %}
{{ form.delivery_date.errors }}
{% endif %}
diff --git a/core/templates/core/shipment_detail.html b/core/templates/core/shipment_detail.html index c14a45d..76bcd38 100644 --- a/core/templates/core/shipment_detail.html +++ b/core/templates/core/shipment_detail.html @@ -17,11 +17,21 @@
{% trans "Shipment Details" %}

{{ shipment.description }}

-
+
{% trans "Weight / Volume" %} {{ shipment.weight }}
-
+
+ {% trans "Required Truck Type" %} + + {% if shipment.required_truck_type_link %} + {{ shipment.required_truck_type_link }} + {% else %} + {% trans "Any" %} + {% endif %} + +
+
{% trans "Requested Delivery Date" %} {{ shipment.delivery_date }}
@@ -141,4 +151,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/core/templates/core/truck_register.html b/core/templates/core/truck_register.html index b8f625e..5a70860 100644 --- a/core/templates/core/truck_register.html +++ b/core/templates/core/truck_register.html @@ -26,14 +26,20 @@
{% csrf_token %} +
+
+
+ + {{ form.truck_type_link }} + {{ form.truck_type_link.errors }} + {% trans "Select the type of your truck from the list." %} +
+
+
+
{% trans "English Details" %}
-
- - {{ form.truck_type }} - {{ form.truck_type.errors }} -
{{ form.model }} @@ -53,11 +59,6 @@
{% trans "التفاصيل باللغة العربية" %}
-
- - {{ form.truck_type_ar }} - {{ form.truck_type_ar.errors }} -
{{ form.model_ar }} @@ -157,4 +158,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %}