From b227d9ff5b3f8242c8a12cbd8f8fa7380a4ed5da Mon Sep 17 00:00:00 2001 From: Marwan Alwali Date: Thu, 12 Dec 2024 11:00:42 +0300 Subject: [PATCH] edit styles --- .gitignore | 2 +- .../__pycache__/settings.cpython-311.pyc | Bin 5870 -> 6028 bytes car_inventory/settings.py | 14 +- inventory/__pycache__/admin.cpython-311.pyc | Bin 5396 -> 5496 bytes inventory/__pycache__/apps.cpython-311.pyc | Bin 557 -> 747 bytes inventory/__pycache__/forms.cpython-311.pyc | Bin 11511 -> 12100 bytes inventory/__pycache__/models.cpython-311.pyc | Bin 34843 -> 37293 bytes .../__pycache__/services.cpython-311.pyc | Bin 3182 -> 5073 bytes inventory/__pycache__/urls.cpython-311.pyc | Bin 7466 -> 7845 bytes inventory/__pycache__/views.cpython-311.pyc | Bin 45871 -> 45202 bytes inventory/admin.py | 1 + inventory/apps.py | 3 + inventory/forms.py | 12 +- inventory/models.py | 85 +- inventory/signals.py | 206 +++-- inventory/urls.py | 2 + inventory/views.py | 29 +- locale/ar/LC_MESSAGES/django.mo | Bin 118769 -> 119875 bytes locale/ar/LC_MESSAGES/django.po | 778 +++++++++++------- static/images/logos/.DS_Store | Bin 10244 -> 10244 bytes templates/inventory/car_detail.html | 23 +- templates/inventory/car_inventory.html | 240 +++--- templates/inventory/car_location_form.html | 32 +- 23 files changed, 917 insertions(+), 510 deletions(-) diff --git a/.gitignore b/.gitignore index 1cf01105..36388ff7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ __pycache__ db.sqlite3 media - +./car_inventorysettings.py # Backup files # *.bak diff --git a/car_inventory/__pycache__/settings.cpython-311.pyc b/car_inventory/__pycache__/settings.cpython-311.pyc index 17f5e185a82de9a82223c9485cca3e9efd80654b..88dcf16be94f0fde465960fb127214460c1a04e6 100644 GIT binary patch delta 939 zcmZWnJ5L)y5Z=8z`wrVj3^rgeFY`7}+u#R;#4)dsC`n-;64O`?b6kwhA~I=0lt2j* zia;*XxFAF#1*QK2U7D20JyNR3KOu96h+^2gnf>PGMA`fv>T?`y3FjMr*6ISk+g3}Og|sIft^VX_en(d{T0uDzX20V5Va zd6%cdj^Y%I(cW>4!UV=JjtOc{9H+_8ltc*a;X??MMQ|1-@exenV~AoBV(7ppm?G(1 z&b);b^=lp%N`i$JEwn_drzHvER{G`I^pGG{z-M>ZX_Qu2@Od^uugkHpl`UTjF|No9 z+D0y)HOf9|K<4&h(iyb}=r!yv7mr=u@)zf<$Rp*S^~Zd6hUkiHZ0ovK*r|vssr0TC z8V^T*DK2F z)M_T3T3sw^p3LMY+G9Tboh8~`6*=cs!NH{}GhH*|?Z24+|Nn~lzF&L9{^~GusR!YM cwZp_wVqdv(HXg)}V~5G3B4UKCT zHZ0t*Xlhay-I%cP0el5FJcQu|OdM!wq|wAlzM1cw%$)hone!q0Gh=y&jc9YUnNh_Hrq|~Y4%#QjFE2*ldyWF{8 z?1hVcaC5({U>*}&68j|j;o*RAukavzJb?a^zBAZ8;V9H)f5ws*)` z1dgfd5Q25XCJtkOhcJi`!WhCZMi4=??skZW5yPnD#W2?K;~hWYkZte?;v5k~G08C` zkhC=(MM_#s38w2Bk70(#G0PK}#d0*aT9;>_{wToEe z4DwjV73VQYxGE32QP+71*ElO!#&yo&2Cv{Iui_T3!Glc{B=fdIl3S3cy@R`Tt;4oD z?4GRd*A31?f2h(A8ex5t8c&UsNv_&^U!Eo#-+YgB$~F9fkCfVw`!>z;o^6*Z`|0(j zSuA4jMX}g4Up;&Mvg|ys=(T1rNk-#W@Vi#~5h^C$N=f_g?niW`S~?N6G%pz~)pij@ R(a&~R_Z*l9X622f{RY~1n-%~7 diff --git a/car_inventory/settings.py b/car_inventory/settings.py index 06a4d1df..2208e95c 100644 --- a/car_inventory/settings.py +++ b/car_inventory/settings.py @@ -9,7 +9,7 @@ https://docs.djangoproject.com/en/5.0/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/5.0/ref/settings/ """ - +from decimal import Decimal from pathlib import Path import os from django.utils.translation import gettext_lazy as _ @@ -26,7 +26,7 @@ SECRET_KEY = 'django-insecure-gc9bh4*3=b6hihdnaom0edjsbxh$5t)aap@e8p&340r7)*)qb8 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ['10.10.1.109',"10.10.1.120", 'localhost', '127.0.0.1', '192.168.1.135', '172.20.10.4'] +ALLOWED_HOSTS = ['10.10.1.109', 'localhost', '127.0.0.1', '192.168.1.135', '172.20.10.4'] # Application definition @@ -110,9 +110,9 @@ WSGI_APPLICATION = 'car_inventory.wsgi.application' DATABASES = { "default": { "ENGINE": "django_prometheus.db.backends.postgresql", - "NAME": "haikal", - "USER": "haikal", - "PASSWORD": "haikal", + "NAME": "haikal_app", + "USER": "f95166", + "PASSWORD": "Kfsh&rc9788", "HOST": "localhost", "PORT": 5432, } @@ -255,3 +255,7 @@ LOGGING = { }, }, } + +# Global Settings +CURRENCY = _('SAR') +VAT_RATE = Decimal('0.15') \ No newline at end of file diff --git a/inventory/__pycache__/admin.cpython-311.pyc b/inventory/__pycache__/admin.cpython-311.pyc index 63a65d3b48b5e2849b94d426c0d467562cb61ad2..ec214091181ce138470aacccd657da1f395a4294 100644 GIT binary patch delta 346 zcmbQD^+StyIWI340}ur4jZDv($ScX{w^7}hdEx=p$<@r_lQWow8AT>fV3FozX<2k5L;aBr^FiXEUSx z=5(%?jEv@!19@B+4K`2XdBn)*3gn1P?&ULJwBEdrub7e1A1vS|V8G}(xm+NgQGW7u zfg3#B&WS}n`N@eTnfZB>*9n$$MF2g_2*kzTHtP%JGfr+5=I2to$e@0OLHz=Q`sR7U GWsCq!mQtPo delta 319 zcmeyNHARbeIWI340}#Bfj!bu%$ScVxuuDkWelC-<^&K+TiHP$dOZ#mNOUj~i~D zG=@qUuu2D3sM{E2Hm?(j z+2jHNk;#jB3>ft{U*UPg$mjwVIL&9kXtntdUoj)2A5g%B(PQ#ffp|u_$)bWcCjSyF Y;|d4*ml24I?{2OV%4ginBvQr*0KI=qe*gdg diff --git a/inventory/__pycache__/apps.cpython-311.pyc b/inventory/__pycache__/apps.cpython-311.pyc index b8f880533f94ecb78b454ed712eb3c1fda3d1bf1..188c57c8742bdf819edcb24e759669cc721bb157 100644 GIT binary patch delta 400 zcmZ3>@|u-*IWI340}xC*7ny!$B5$dZ43IOOA(bJDF@+(DDTOhLIfW^TC55?#A&NDH zC73~zb>ckh$Ye&4CMaM6(#$~onGZ-zXGj6+%webnl0el=enlW@O~zY-nR#WYc_sNp zm3qaQ>3NAc#hOgFSc+3~(u&xCDvCkM6ci>aGP*k7Vl7HdOsT9A^@M40&d*EBOxFVo zbAVKf0Eq^M8ypH3P|;_gID?-i+r&F|Aw}Fk_DY5#9w1c&@?{Y#j9>vWiuHg*103Fv zw79?`c7t22!Q}%BBdg*E227%eXYv$AWho($F>q6VaoFVMr0viSZbVn#P diff --git a/inventory/__pycache__/forms.cpython-311.pyc b/inventory/__pycache__/forms.cpython-311.pyc index 76217d41fd8a70f3076e812f0f3dead76caf79c2..38100be122ff22666b0c921ba3186a7573c72389 100644 GIT binary patch delta 3150 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 ZX!!rYWPBJ}_9g?2x!^?4FIAMde*kXUAzT0e diff --git a/inventory/__pycache__/models.cpython-311.pyc b/inventory/__pycache__/models.cpython-311.pyc index 08cd8d077d24c5ce19a5ed7946b32fa1a2b48f70..8b2e52417e29c3ed99903b3193cdaa86173fde31 100644 GIT binary patch delta 12524 zcmbU{3v^S*vG?k4`7eLvA2K$!W&FYBXD|kgKbQhCVDnQUitrV-j4YXz%ttlIq%@^J z9%RX{X_L0JBqX$t9yfVya?;S>d&z5?%Bf%C-d7sZp0=TF8q<(AC-1anx_qSLlVV{)0ptoHR|~nE)Fnhw1h@q;Tpi&ofGdvF%HfZxbO{Rq zQxe6bE+wi`z%7d69Loq-2Doy>MFllWaLb9V0_d!Fq+3CBl|Z*R+D7V1!c_sTns9^a z!h{;g)y61R5ycX~)x~hD30DuerBR%tk#NfZw;XZv_I3@?tpK`}ccg0~x(1+I6>TGR zE#X!Jt}%vNN4PbBYl`946K*Zw)cV!PWhmLmd?q@w<}WEZyppT%K;W z014IuxGc&E(g8=0&oeaOWyOeI$osQu8W&@-3PBA3zX-rWLt)rzFs;SOh*yon;SVr} zgZfgB^h>#DsORCtoX|?l#&wOlyA=wS!RwEgL(yzGq|TB9a$N^NPI60*9w&1Q;Gkq< zyN|itz242P<1}`;#n{^EuyuBKY_e^n!LnwoT8&@>f_dfFfu#r*^UF#9uE?(g#7)}6Ifkw9a1B@&cjI5iv2cjZF zvzZdv3hpOK8jzf{iK{aj=AVal z>@b2hepklpiXGW`OXmMok$e>EL7G|sassqI=wvQ$z^Y~+LiCiVT0THjxge^pL06Ca zpu5KzaQnPbnNb&}nOSmn`M!DQWgj$(a+_shWwT8zWo|L@bJ=;#GsUDxl7#5OQO!H; zBrHYH&3~W$j3O=xrk#28T278wM>2CD4cSybq};bf$Sy=23KQg3f@wu=0^ff)ms`x8 z)ksS7Ue+FQdWKxGX2|Of%7x^GK#vdb z^tVMSO$zEn)`7?m54l()|I5OKp+-XOa(N{mvuaocRwk|8k0~r=>k+H~0Od3rriiGV zys!<*WzAlflU){-YBW!GV_g#IU68tIL@HfZz!@0wU)F$)m>{q3>GQdJTz+On;zs^t zNq%C)a3~)xIZ<*JD{5eF`E8eV@ycvf>J65f<7G;V+!vwv1^%VdWr{4C`2L+{{%+|n z3fE&jT7_r`*iBh;9EJb`g#d7oC1(jzpw5Gd(00@ozsJkVj)N_JvFyLn^01Q5bv@?+%|aS4C8yjXmRKUdxeWW|-I__2zrRaroK8Az~({-E3I^unN3kh4S<^#6c# zFdZB6yF4C6xc% zFCfPRhq`ia%bprJc-*T*23YPBsiO z-=K>Hjx*FCdkz80iQ&-Vrzcu6LvUhrRdtzKvB|Ui>PEB5BJz54i`i!pmbQ%sQ>J%!2hyZPVjjh5catO zE_Od)Xz~XW6>67c*>JpjTCO>8StTbqhXOu_*LT$6lq7{dB}Tu~8*qErL%^v=lI;$nWIE;}9P+Kjb=>+37TH~EtKLe)}%Z+GYBqBT4yxCFZ>33inv+SQV(SF~%m zWkF`hj-u5{nz#Y$B`pk6_kPCALDt|-!K#wgJx<160lvYcYDO|}Ne*Wqh(VEMnouYd zpN{a`tcK}!y9Id2sfzb?1bn@&Kp)ts!N(+s0KL6Tabq~fFC&Os9?0hY2MT@KxVH~~ZtqyHZ@kwRHV%#% z2gi+rBP|oAl5=I_rjjqTUTyz|Exg?k_WJNQcw)?Za@>0|YzmE;LgS{;$mR)C8IqP= zZM}B*+Tj-q$2RUB-?%$$+B0U_Gj7^5vY8*RUDz&a7f%W?pwnoVO$xKYEyUfPqd*zS zk8mz(EowpdI6t+-%&*?<=8rBnjK06DLdCr+(?S_i#+A%VFb$uIO+|aAlm(L}>x^(v zl(J77?AfjyDd)6s3FPn;yvk$GrF|@&Ok4uT{}eiZdhF&i!ZFdF2X>ez8^N&JmF0mP zJ**io0~O7#n<)bS^U8X$ky{%UC8C(wuMjlyy$y?Vz5z*C9j2kN%*r2Wuw`~zwbKe{ zsjcAQ^ei3BBlz~~@B52TSDJwXUOPH2aDQk2rWwnPY^ zZ;L#o5OSQ*2T*>IC$J!z65u$H+!r6HNJt43PvM94d`;t`bp1*FQSqp7Oubh)DyoD) z$$iIjRsAOZ>Bh#i45k5k*|4j*+p(j$yN$ot*q%6T$>Jqz>RM^d$_6@?g8-e9tcH^X zS?eEyMNZcEokv{O1SO2oI9ab>)*U)Z{|y)tFlWHU&#r0iMA2Cy&xqn5{sbuUn-TM_ zL0&0nENC(BjR@B>^2aku&ln~QN&lAm$<#4}dE8(Q8_bg`1J7z&p4u?BU~@RBV4|r0 z>YlNpCVqEQt9YG%rKv@I!;s0}YARWIvAJ$TmhjyyV@sO)y9=sX64l>J)Iyr<44S70 z=N-&%;hiG@Vn!A^A%ccua}v@>Lr+A7D85+!gbFBP9strYyCG{+537e&R8K@}>k=65 z9IblN0echD>~{#zowGk6sEw%t<4?rAi{Q@){sO>{&7(jSVZO(oUuVfIK_AcEt%NU1P>w^ zQ^LmUuvERvzulUeQ4GV7H8$sf3s#E~99$#6(OQ&F$#TqB5He~E>x$;J10&c#HUDZ` zWb4=j+Z;20WK$(y(w@8$cT2LG^&XfJhaqd)C1tlAgD}wTV=X?9kNKnPK^+gYm+iqg z!FD-uE|ZxG<)@trrb9=RID_;YXR|6SMNq;2)c#G3|H2)a{MyFbmSXIV8jCduvvUHK)V|0(KRWNK~xlr^Wh>zU}*?uEs6Y%P5EorVv#9Y z(Z(_`88?7z#35LYiA)3(No9-Nk(|qSd?=iI7NxC&GhvV=`vne*Mx6~KF!Qd>2gO(U zvzznRG+@cp`7})_+L?bD3tmGI*EUWPRs>CU@boP!6=Q1Rwk?NNpf?Vxt(FRw3Mp_z zIA>Wg_KtSS3o$i&&~I(}%o zpnQ>kePb?n+WuOP0%AX=9s&p^w+#6Mz5$DEXyAa0k@{iduHaf>U4m@|IK#dC-OlRy z?Y{zA+s)T+Ylw=a7`CDhZmX)oU@j64$;my$)!|iInnNJla>NgF{r1wx4tDNX{BPKG z8U#s&G)Dq&#)3-diJX8PCtoQiMjDlHDD#R8ZtDbwUZZ>(={yl*gUJUnJRJZ?P9U*CSZn52!IdVojliH1b)+`#Q>9>m9K{A)Xw6-XM` zoW|BbNeg=|y%gDt^0#dZR>9gZEn+r8xw=2fOo*$UK(&p^PK{sfD%@&_i?|c1ek_QR zlB6W6lRR^GN4S)kxGSkVv^*;{B|0RfCjXXr==sk_%`b@Z=%8DyV zhuwf+H{o8uo+0Hzd~cTVC~1pNIUSY_o=A$!Afy;Ghn~qs-%&5@G<)F8OV)Nmngw%P z>0HBdw9jXOQojXukQN}QfqD8e)S23V%L#oh&!8jVIu?+V{e8Zp%;y_Wcp17P+2HaR zI~Q{iuMjY^xcwG5R2uX+kHhx8qQ~jA98gNJL(E#!Eho0R{5{M)h-U%8`cC@q^jM@R zti^f2HxwYA(bg@%vBxz4r|Q_<>1z^nydJFVePhdF<^tQ6EX@J-6Bti0X^YbzuV~L``BTUQrZSzMz=;}WT?>oF?XY8QRw#6*2 z;GYOA3Q4g4mt4 z7Mz#7oX{194LoJyJoQ4^~UK9SbD zCg^PZ(ByQt-$C>a6ha8iFjzQ!q%+E~_>(y14CwrbFli9dGCv)BsQYvKUrDVD8!Bmh zHf!dbF~q#il$IUpVlMUZ2f$oToMx@;MgGO1g3y#pU5`VFTQh5DcmN#O!OsGi?N%oY zi4&&W3pEp23nsF%&uu?9bbil;J(CIAMBOa`z-Z#>S zmXCN{H+Vx!9fSpZd-v7(Bfkz%?Zfc0Mg+77;+=s@hXDZd@)vhnYib}l>m(!x?0Sc* z7p?+e6Flwe@AG`Yu7*e)kTIv}l7-R;;^Kh2vB@pik7i75#gq*}CjvU4OJ~!Xbj%wY zD0dlcSPj8>c>Os5_}lBvT(|r0Mj9v<^_+)Oq0&9iq>~Sp^%3{WR*L+w#5!KPH@|*n z#0hTs0FJpQ5I<*VM(qNgm-z7Bf^tQcFc2FYAk5@JJ4YH2YvnKO%`T#Y6l+kw(P_X@-+X+{@4lwm+v7w7r4V09x0KABHwp>3s^+%-l3k&nl+~&$rs}B7lqq!%?cx$ z+GN3*HuJ)z3G>4D7Z8Fep?xlY>8||h7OYf?V9FiFse#0d;HlAcha@U-GRI@n(F=Fy zs6r1wk*rtlULyOJhXK{iK8$@okG%I`YCnQv%xW=3yS2L@byETyTr&B*0kA2{Hc$rK zIiTBRcO!5jzylp7At22qE1JVbjksHKVaY+*DB1bhp5!%3my~PHJ1J-gs=b6&`w=X~ zzBS<&5+A4}g>`h@{xR0B$J)rkX3d^cNi^$8m^ACZgY?Y^S`iE&4=;iZbbLfx@01=z zC=NJ^L!sm%r4NY)5&Q$nLrE|M-yVHU`ea0T50LUk4sK9Y;>@{;T@M=D-3+2HJX9dv zz&*}Zwt%{~&YJ+I#0QPaJ#*_-Xu;3>c z()HB_AuT5;yEYi)9b&c+P+sS6x?{5mPbwPwcZptpUw@5Q%fHi~QLqF%NQV8@+wtT8KTp_pXw5<|&_Xv)V{b4RWFJE?-PiN49jX+6&3|^NrcKeT`CriNH2!>x zr*w0i645cSJ=pTp45ag|Gl+|uizqFI;1ziN5AdH$1*5NdPKt_i3@Xks;FVONmys>q z(BV;#Y&<*!m$JA_`Ki9L^SFUTc#XhNowBZ(E|no({}tk_2!4rxH2!%^J&NG72p&PO z0{cU;yD_qEU@*T@6!=|-|5rTASF`Hcb3kJQ$ND{}ARBk#hahc?`Iut&e?m4hWc~mv z5#Qs_vW<$as`(N>7titU`zv$qLssk|Y;;ByZJ=2EJ1-Axq-%OJKNHxIKAiyDsN=s6 z8Lt6LC$7QyEb%yky>87x5XyU||{osMYuGm3`K95ss7bP#eD7(+z< zGV&)ar(Yw_bBDO6Rf_@$35YEzvFhCWC$35`L zic${`8JvNhK4#=kjuh$e<_u!Lmq+sWTO;N5EE8$ ze33MS=z9^6k>J%f-5NyBVNp`n= zXNNqlwd}jV0e*u2w{T!KsTM_XLdXu!{7nd!@XX%?KXp&$=zaGTi{g#ZZ+!Gy;;v*7 zZog-PbGt6=yM_4MQ-urbMYxHW4bEj>D7c0A+p$9a!;f97$*UD%S2i1*E4xs23-Pz7 Q3MFy$)AxQ#)S$`!Ke^0R2mk;8 delta 10412 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 diff --git a/inventory/__pycache__/services.cpython-311.pyc b/inventory/__pycache__/services.cpython-311.pyc index 2fd2882edef7b7f22786428b79491f0d46e89348..96ef9d45c83af0de97447362d9aee6575568cf1a 100644 GIT binary patch delta 2561 zcmbVO-ESL35Z}EI`_AXD#5pHU(kLHoS~pEd(hyMM1WK9;HEOF8pdV6YjPDX0>?G`6 zqf$B8MHO{XfJ9fRd8mXzh&BSGR=o77{0nwuDb}G%ec`P_hYBwh63m_*w~ z-JP4;nfdLke{Cx6_1^S&TnJkC%9+_uTx;GY{Q276=~q*pv!0aqtQR9iyo}EJ6c?ah zkpSxyH(F46#FUbwX$ zfGoN%)vvs=C3S2{9k=v?)KQd%O487lG_om;6s1T>iewL$C0};x5vZd$wYc3l5Nux_ zgK!ljWTIQn@XcR)!fk(=2`ET*))3?ojbV9J+a1BLj=}(GZ*kO zLl}(a@ybw|#-2S+++fzk?P1Pz$73W#V;5jFOGhCbXB{0V&y~*m+R^+#E3x~a)-)ts3do9$-SF$@7;ld+*_2# zO7hs2Jh3TH6y?d1JX!Ef=5z~TPq6HlS9y!Yq9^!(CWFYvF(zb)_!3VVVQI!^cuz}Z z_1^gfl8Pl07u6^w4%rRU%|;zF(n@3y|DBC*7_&@=8-j}oLz$ z$AMoiMU6vjqDzT+lU0)`7-FgHAgXpgsaH6+9m$F=OcTnsHn_Ey0J7*8UueDSYGx%< zaJFTaEX4B-WuKh$+^=g`onC9Y)>IHfxdRX@wmR{^7s%;5J)o(xId~g9=n@iW8P*Tc z`IH$J6y`EYGkG31RHv~Zwq?LKW*$>lfHoVf$=gJL2hFu9+K)48jO>UJrNtvknCoa3 zrO`QV8TRKIv%*7A5E+Dt4aQ{p`b~V{Y5yO)BFTiN#}`tI;}_eMOf7JIk>o-=mej^U z*j6}5ztIGcMTN$J%C#O_$F+{_eAq##%O+>n7~U>0rf5It%1t(wOq!0RSn|B8g;^4& zx_F7uwQCs~sBM;$z0k3N>S!te6azuZOtyaF9hl&E=`1JDMUsTQSJ~G^dE6nx5i%BL8DXdhU$-$&BJ@y1_2< zx~FCl(W;;3^UiG^xq(M~l}A2fntPa`;k9E-`l$2*g?yH#dwiShMdCCrymh)LoVHlR3zmRD41eXG_W1Qf17p z^_h~qCqG+~`^xguolr-M4bW|0k2SiS%QSBZGN6-o_p0jPE3@8H&A55{uyL zNuygBZ?2Sdoy6v~WDHKq80eg$zFjds62cM7fkGYSmZ-(E9xs#|009MCZ#fI@ez+{j zQSY+6NN%zMsJ{O<mlakGbXgUK*9J(`+KCgx|OizE?O!weas zOJd<%s^!x7Q+yfE885o}WLl8nL>J&e=$UM%%1FC9alrV})xyug*n7rLuJNF)*=RbW zQDq?>jgrGu`-l;cUeAbBr2lH{quoBT?4oa%+{!k$lS&;Y)MABS)S{j8$3g@u-}$6E zPCkG!`cFiY0O7d7*kTyW!HESRAnecj=&y{Vto>20B}XpbL*#s0RCkv|EEgFK)Du7w@*Q(duMre<#>`;%`Z!Wvc)H delta 984 zcmZXS&ui2`6vt)g7|pzndHrP^5(tF>z!YU`U6eN zAh0hlXXmdf>v|D4)_2a7G4j%D=$z(dfV!6j=Di%y@HC+52{Xvn*I%5JF%yrugx*Zu z6&Wtkvb2MK!jlC(tdT`Gs9y1%&|UP22{|-6Cyn-h%+zLgL3 zEerQS@wlVHXqjgePT3+Ysl^prA`X9VNi}TPA`>rFL#ABv7pj%OXDQEZ zxDiiLDwT-Am4@e6YM$?a&Z%Dpl0FFYQ$~jYF?z3?w+C-5+**hy5*eArJGmBMpjGI9 zQz(}bC6$vC1c=9fWRR4(zI}CSZ7QB>W%KbAvFJOsN4SURPjz*N)X2gY|Jt(jUttmy zmZs-2pXFW<*)nZq%QK|A{Y;85krIH3OC(@Q-Mt*tT#u>5kLtBB@|jw3iBk>dYLN^w zC=l#VjiMhclHCy84kMbUXLDPO9Lk=-%`>yFGqdrr54u5bsn%_o4AZ^&vEFtk(+%Q=QQ$Uwas)K{d9D?D zEpPAtP#9?L4x70ec&pI&P-*5yz!OQdGKq=`#Y98a$XBFT@^_ASGBN1Kd>LERG&XkG z_>_&A7WqL?4d)&BwH4nMm@qWLM5s9uAQLZ@>gGW_PAANv9t%Qtil{I#rFP+>Uui^4 zbc2B2G`C@cJ~8{G6R>!czB0!)x78L?9LK9w9EWU$6*5S-TE|cFi_pFi?f$h3BYfi{ zMEI_De}Acmpgl{0KSoYNjNjF01CWRq<3tc}DnT4F-LTGI>~5leJdrUTO;87F8XF1f YpseAp1a(l#;_d`>&@b}W|It3&Z(>{a1ONa4 diff --git a/inventory/__pycache__/urls.cpython-311.pyc b/inventory/__pycache__/urls.cpython-311.pyc index 973612a0cf5bb6b08b80ddf1ea0b9f832c4ce489..078b0821af10bd634544b869a260e2ff16105ad0 100644 GIT binary patch delta 750 zcmY+B&1(}u7{)W3P0c1WX|4I%jiN%DX4e>FsbaAbldY$=3Di_tvFVy!OVXOeBsCDM z2E6p*q0CJLKR_*hASE|%dKTQ2g-Q@T=pPWh3%)aJMc-w9%=66izO&1|7=Jq9dfwmf zut2px%`d+l+;sWT=k0Kf!y9Y}rEvxMY#Gg3jNld<#qYQfqs~(EBA61Ma=a%&>~>zk zI)Pv8rBu77wciXh5gKia z`x{KulTxZvf99sD8U*JGTBG}~ou&Q6#*Yp((I^%?>yBl3X#}hG1wZj5kc_{1!a%22 z1fKH7`()&1dM^CXD=}^v-}lDB|KL3X?DG*OD4RafOp5q&AjC*A?)W4){Y4q^lYQ1t zX14stfUhaLl=}jQ!5IkG(JJL)?${12czf{oKVuvjnY_Ye3 zXnb`qKC%@u#K~Q8dPkh@h-pJi>vKywt8`e!V3po=GhW3X1>RmWMIHYDv1W>!cqkaQ zH%xI0Cqb;6;x@h!40Cr(kznxS;4pWdp|>X)tOt2}%2YD`84M3jQqgjfr>enk`wfR4 B+=>7I delta 451 zcmZ2#yUL1hIWI340}$+$i%5ShFp*D!(PN`}G3VrcoNALfxYQZ*S1v6;IZ|2~!W!=0$u!51%aI>UvIn(5QqLqw>lP$z*xsriqG6HdN!{q&9 z4vbEd#MK#{CToam0m)!-LpCQyex?t6llO>gGx0l3-Y#wk6n`mh2_%&zKx8bKoGzgS zQK>b#LQ0iM+iCJU32mUPl%zI9++ec2q$-o4)8ryakjZl;b%5k4F!>!!sz@mSMO>vo z;zd%rKym??JO?KKNGSqE?nata}wqRD-->Kw%oPQ~QCKu#ruQ#JXGtU6~k sgj2&fSw>EcvlhauW1Q?QC&f_@;W$iNMeW0Mkx&!2kdN diff --git a/inventory/__pycache__/views.cpython-311.pyc b/inventory/__pycache__/views.cpython-311.pyc index 4bfb1bf5319933403104e0278b1ba9ed6e44631f..736e0f775758ec4beb982f27b2920f5d49b6adfb 100644 GIT binary patch delta 11727 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 delta 12863 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 yF1*E&pHCg)k_SG! now() @@ -233,11 +235,13 @@ class CarReservation(models.Model): class Meta: unique_together = ('car', 'reserved_until') ordering = ['-reserved_at'] + verbose_name = _("Car Reservation") + verbose_name_plural = _("Car Reservations") # Car Finance Model class CarFinance(models.Model): - car = models.ForeignKey(Car, on_delete=models.CASCADE, related_name='finances') + car = models.OneToOneField(Car, on_delete=models.CASCADE, related_name='finances') cost_price = models.DecimalField(max_digits=14, decimal_places=2, verbose_name=_("Cost Price")) selling_price = models.DecimalField(max_digits=14, decimal_places=2, verbose_name=_("Selling Price")) profit_margin = models.DecimalField(max_digits=14, @@ -258,35 +262,35 @@ class CarFinance(models.Model): default=Decimal('0.00')) custom_card_fee = models.DecimalField(max_digits=14, decimal_places=2, verbose_name=_("Custom Card Fee"), default=Decimal('0.00')) - vat_rate = models.DecimalField(max_digits=14, decimal_places=2, default=Decimal('0.15'), verbose_name=_("VAT Rate"),) total = models.DecimalField(max_digits=14, decimal_places=2, default=Decimal('0.00'), null=True, blank=True) def __str__(self): - return f"{self.selling_price}" + return f"Car: {self.car}, Selling Price: {self.selling_price}" def save(self, *args, **kwargs): + vat_rate = settings.VAT_RATE self.full_clean() try: services = self.administration_fee + self.transportation_fee + self.custom_card_fee price_after_discount = self.selling_price - self.discount_amount - total_vat_amount = (price_after_discount + services) * self.vat_rate - self.vat_amount = self.selling_price * self.vat_rate + total_vat_amount = (price_after_discount + services) * vat_rate + self.vat_amount = price_after_discount * vat_rate self.profit_margin = self.selling_price - self.cost_price - self.discount_amount - self.registration_fee self.total = price_after_discount + services + total_vat_amount + self.registration_fee - except InvalidOperation as e: raise ValidationError(_("Invalid decimal operation: %s") % str(e)) - super().save(*args, **kwargs) - class Meta: - verbose_name = _("Car Financial Details") - @property def total_vat_amount(self): + vat_rate = settings.VAT_RATE services = self.administration_fee + self.transportation_fee + self.custom_card_fee price_after_discount = self.selling_price - self.discount_amount - return (price_after_discount + services) * self.vat_rate + return (price_after_discount + services) * vat_rate + + class Meta: + verbose_name = _("Car Financial Details") + verbose_name_plural = _("Car Financial Details") class ExteriorColors(models.Model, LocalizedNameMixin): @@ -332,7 +336,7 @@ class CarColors(models.Model): # Custom Card Model class CustomCard(models.Model): - car = models.ForeignKey(Car, on_delete=models.CASCADE, related_name='custom_cards', verbose_name=_("Car")) + car = models.OneToOneField(Car, on_delete=models.CASCADE, related_name='custom_cards', verbose_name=_("Car")) custom_number = models.CharField(max_length=255, verbose_name=_("Custom Number")) custom_date = models.DateField(verbose_name=_("Custom Date")) @@ -344,6 +348,55 @@ class CustomCard(models.Model): return f"{self.car} - {self.custom_number}" +class CarLocation(models.Model): + car = models.OneToOneField( + Car, + on_delete=models.CASCADE, + related_name='location', + verbose_name=_("Car") + ) + owner = models.ForeignKey( + 'Dealer', + on_delete=models.CASCADE, + related_name='owned_cars', + verbose_name=_("Owner"), + help_text=_("Dealer who owns the car.") + ) + showroom = models.ForeignKey( + 'Dealer', + on_delete=models.CASCADE, + related_name='showroom_cars', + verbose_name=_("Showroom"), + help_text=_("Dealer where the car is displayed (can be the owner).") + ) + description = models.TextField( + blank=True, + null=True, + verbose_name=_("Description"), + help_text=_("Optional description about the showroom placement.") + ) + created_at = models.DateTimeField( + auto_now_add=True, + verbose_name=_("Created At") + ) + updated_at = models.DateTimeField( + auto_now=True, + verbose_name=_("Last Updated") + ) + + class Meta: + verbose_name = _("Car Location") + verbose_name_plural = _("Car Locations") + + def __str__(self): + return f"Car: {self.car}, Showroom: {self.showroom}, Owner: {self.owner}" + + def is_owner_showroom(self): + """ + Returns True if the showroom is the same as the owner. + """ + return self.owner == self.showroom + # Car Registration Model class CarRegistration(models.Model): car = models.ForeignKey(Car, on_delete=models.CASCADE, related_name='registrations', verbose_name=_("Car")) diff --git a/inventory/signals.py b/inventory/signals.py index a2dd8833..f6973c97 100644 --- a/inventory/signals.py +++ b/inventory/signals.py @@ -2,11 +2,27 @@ from random import randint from django.db.models.signals import post_save, post_delete from django.dispatch import receiver -from django_ledger.models import EntityModel, VendorModel, CustomerModel, UnitOfMeasureModel +from django_ledger.models import EntityModel, VendorModel, CustomerModel, UnitOfMeasureModel, AccountModel, \ + ItemModelAbstract from django.utils.translation import gettext_lazy as _ from . import models +@receiver(post_save, sender=models.Car) +def create_car_location(sender, instance, created, **kwargs): + """ + Signal to create or update the car's location when a car instance is saved. + """ + if created: + models.CarLocation.objects.create( + car=instance, + owner=instance.dealer, + showroom=instance.dealer, + description=f"Initial location set for car {instance.vin}." + ) + print("Car Location created") + + @receiver(post_save, sender=models.CarReservation) def update_car_status_on_reservation(sender, instance, created, **kwargs): if created: @@ -24,21 +40,21 @@ def update_car_status_on_reservation_delete(sender, instance, **kwargs): # Create Entity -@receiver(post_save, sender=models.Dealer) -def create_ledger_entity(sender, instance, created, **kwargs): - if created: - entity = EntityModel.objects.create( - name=instance.name, - admin=instance.user, - address_1=instance.address, - fy_start_month=1, - accrual_method=True, - depth=0, - ) - - default_coa = entity.create_chart_of_accounts(assign_as_default=True, - commit=True, - coa_name=_("Chart of Accounts")) +# @receiver(post_save, sender=models.Dealer) +# def create_ledger_entity(sender, instance, created, **kwargs): +# if created: +# entity = EntityModel.objects.create( +# name=instance.name, +# admin=instance.user, +# address_1=instance.address, +# fy_start_month=1, +# accrual_method=True, +# depth=0, +# ) +# +# default_coa = entity.create_chart_of_accounts(assign_as_default=True, +# commit=True, +# coa_name=_("Chart of Accounts")) # entity.create_account( # coa_model=coa, # code=1010, @@ -48,25 +64,56 @@ def create_ledger_entity(sender, instance, created, **kwargs): # ) # entity.create_account( # coa_model=coa, + # code=1100, + # role='asset_ca_recv', + # name=_('Accounts Receivable'), + # balance_type="debit", + # ) + # entity.create_account( + # coa_model=coa, # code=1200, # role='asset_ca_inv', # name=_('Inventory'), # balance_type="debit", # active=True) + # + # entity.create_account( + # coa_model=coa, + # code=2010, + # role='lia_cl_acc_payable', + # name=_('Accounts Payable'), + # balance_type="credit", + # active=True) + # + # entity.create_account( + # coa_model=coa, + # code=4010, + # role='in_operational', + # name=_('Sales Income'), + # balance_type="credit", + # active=True) + # + # entity.create_account( + # coa_model=coa, + # code=5010, + # role='cogs_regular', + # name=_('Cost of Goods Sold'), + # balance_type="debit", + # active=True) - if default_coa: - entity.populate_default_coa(activate_accounts=True, coa_model=default_coa) - - uom_name = _("Unit") - unit_abbr = _("U") - - entity.create_uom(uom_name, unit_abbr) - - print(f"Ledger entity created for Dealer: {instance.name}") + # if default_coa: + # entity.populate_default_coa(activate_accounts=True, coa_model=default_coa) + # + # uom_name = _("Unit") + # unit_abbr = _("U") + # + # entity.create_uom(uom_name, unit_abbr) + # + # print(f"Ledger entity created for Dealer: {instance.name}") -# # Create Vendor +# Create Vendor @receiver(post_save, sender=models.Vendor) def create_ledger_vendor(sender, instance, created, **kwargs): @@ -113,55 +160,64 @@ def create_customer(sender, instance, created, **kwargs): # Create Item -@receiver(post_save, sender=models.Car) -def create_item_model(sender, instance, created, **kwargs): - item_name = f"{instance.year} - {instance.id_car_make} - {instance.id_car_model} - {instance.id_car_trim}" - uom_name = _("Car") - unit_abbr = _("C") - - uom, uom_created = UnitOfMeasureModel.objects.get_or_create( - name=uom_name, - unit_abbr=unit_abbr - ) - - if uom_created: - print(f"UOM created: {uom_name}") - else: - print(f"Using existing UOM: {uom_name}") - - entity = EntityModel.objects.filter(name=instance.dealer.name).first() - - inventory_account = AccountModel.objects.first() - cogs_account = AccountModel.objects.first() - earnings_account = AccountModel.objects.first() - - entity.create_i - - item = ItemModel.objects.create( - entity=entity, - uom=uom, - name=item_name, - item_role=ItemModelAbstract.ITEM_ROLE_INVENTORY, - item_type=ItemModelAbstract.ITEM_TYPE_MATERIAL, - item_id=instance.vin, - sold_as_unit=True, - inventory_received=1.00, - inventory_received_value=0.00, - inventory_account=inventory_account, - for_inventory=True, - is_product_or_service=True, - cogs_account=cogs_account, - earnings_account=earnings_account, - is_active=True, - additional_info={ - "remarks": instance.remarks, - "status": instance.status, - "stock_type": instance.stock_type, - "mileage": instance.mileage, - }, - ) - - print(f"ItemModel {'created' if created else 'updated'} for Car: {item.name}") +# @receiver(post_save, sender=models.Car) +# def create_item_model(sender, instance, created, **kwargs): +# item_name = f"{instance.year} - {instance.id_car_make} - {instance.id_car_model} - {instance.id_car_trim}" +# uom_name = _("Car") +# unit_abbr = _("C") +# +# uom, uom_created = UnitOfMeasureModel.objects.get_or_create( +# name=uom_name, +# unit_abbr=unit_abbr +# ) +# +# if uom_created: +# print(f"UOM created: {uom_name}") +# else: +# print(f"Using existing UOM: {uom_name}") +# +# entity = EntityModel.objects.filter(name=instance.dealer.name).first() +# +# inventory_account = AccountModel.objects.first() +# cogs_account = AccountModel.objects.first() +# earnings_account = AccountModel.objects.first() +# +# entity.create_item_product( +# item_name=item_name, +# item_role=ItemModelAbstract.ITEM_ROLE_PRODUCT, +# item_type=ItemModelAbstract.ITEM_TYPE_MATERIAL, +# item_id=instance.vin, +# sold_as_unit=True, +# inventory_received=1.00, +# inventory_received_value=0.00, +# inventory_account=inventory_account, +# for_inventory=True,) +# +# item = ItemModel.objects.create( +# entity=entity, +# uom=uom, +# name=item_name, +# item_role=ItemModelAbstract.ITEM_ROLE_INVENTORY, +# item_type=ItemModelAbstract.ITEM_TYPE_MATERIAL, +# item_id=instance.vin, +# sold_as_unit=True, +# inventory_received=1.00, +# inventory_received_value=0.00, +# inventory_account=inventory_account, +# for_inventory=True, +# is_product_or_service=True, +# cogs_account=cogs_account, +# earnings_account=earnings_account, +# is_active=True, +# additional_info={ +# "remarks": instance.remarks, +# "status": instance.status, +# "stock_type": instance.stock_type, +# "mileage": instance.mileage, +# }, +# ) +# +# print(f"ItemModel {'created' if created else 'updated'} for Car: {item.name}") # # # # update price - CarFinance diff --git a/inventory/urls.py b/inventory/urls.py index c6bf3ac0..03bb9a9a 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -56,6 +56,8 @@ urlpatterns = [ path('cars/add/', views.CarCreateView.as_view(), name='car_add'), path('ajax/', views.AjaxHandlerView.as_view(), name='ajax_handler'), path('cars//add-color/', views.CarColorCreate.as_view(), name='add_color'), + path('car//location/add/', views.CarLocationCreateView.as_view(), name='add_car_location'), + path('car//location/update/', views.CarLocationUpdateView.as_view(), name='transfer'), # path('cars//colors//update/',views.CarColorUpdateView.as_view(),name='color_update'), path('cars/reserve//', views.reserve_car_view, name='reserve_car'), diff --git a/inventory/views.py b/inventory/views.py index 23cc9c4b..b3df66e1 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -167,7 +167,9 @@ class AjaxHandlerView(LoginRequiredMixin, View): def get_models(self, request): make_id = request.GET.get('make_id') - car_models = models.CarModel.objects.filter(id_car_make=make_id).values('id_car_model', 'name', 'arabic_name') + car_models = (models.CarModel.objects.filter(id_car_make=make_id) + .values('id_car_model', 'name', 'arabic_name') + .order_by('name')) return JsonResponse(list(car_models), safe=False) def get_series(self, request): @@ -405,6 +407,31 @@ class CarDeleteView(LoginRequiredMixin, DeleteView): return super().delete(request, *args, **kwargs) +class CarLocationCreateView(CreateView): + model = models.CarLocation + form_class = forms.CarLocationForm + template_name = 'inventory/car_location_form.html' + + def get_success_url(self): + return reverse_lazy('car_detail', kwargs={'pk': self.object.car.pk}) + + def form_valid(self, form): + form.instance.car = get_object_or_404(models.Car, pk=self.kwargs['car_pk']) + form.instance.owner = self.request.user.dealer + form.save() + messages.success(self.request, 'Car saved successfully.') + return super().form_valid(form) + + +class CarLocationUpdateView(UpdateView): + model = models.CarLocation + form_class = forms.CarLocationForm + template_name = 'inventory/car_location_form.html' + + def get_success_url(self): + return reverse_lazy('car_detail', kwargs={'pk': self.object.car.pk}) + + class CustomCardCreateView(LoginRequiredMixin, CreateView): model = models.CustomCard form_class = forms.CustomCardForm diff --git a/locale/ar/LC_MESSAGES/django.mo b/locale/ar/LC_MESSAGES/django.mo index bebe4a2245b88bed1c3f690af74ad0dfd2cdfb27..5d4127126443407b8a5ca5d5425cc4931667d305 100644 GIT binary patch delta 30654 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 Le(hJjbs7F2;c!J& diff --git a/locale/ar/LC_MESSAGES/django.po b/locale/ar/LC_MESSAGES/django.po index cdce0689..a482433e 100644 --- a/locale/ar/LC_MESSAGES/django.po +++ b/locale/ar/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-09 09:40+0300\n" +"POT-Creation-Date: 2024-12-11 21:41+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: api/models.py:6 inventory/models.py:123 +#: api/models.py:6 inventory/models.py:126 #: templates/inventory/car_detail.html:61 templates/inventory/car_form.html:83 #: templates/inventory/car_inventory.html:53 #: templates/inventory/car_list.html:67 templates/inventory/car_list.html:69 @@ -34,49 +34,62 @@ msgstr "الإنجليزية" msgid "Arabic" msgstr "العربية" -#: inventory/forms.py:102 inventory/models.py:357 +#: car_inventory/settings.py:260 templates/index.html:59 +#: templates/index.html:62 templates/index.html:80 templates/index.html:87 +#: templates/index.html:116 templates/index.html:122 templates/index.html:128 +#: templates/index.html:163 templates/index.html:171 templates/index.html:179 +msgid "SAR" +msgstr "ريال سعودي" + +#: inventory/forms.py:114 inventory/models.py:341 #: templates/inventory/car_detail.html:135 msgid "Custom Date" msgstr "تاريخ البطاقة الجمركية" -#: inventory/forms.py:151 +#: inventory/forms.py:163 msgid "Both exterior and interior colors must be selected." msgstr "يجب اختيار اللونين الخارجي والداخلي." -#: inventory/models.py:31 templates/vendors/vendors_list.html:44 +#: inventory/models.py:33 msgid "logo" msgstr "الشعار" -#: inventory/models.py:111 +#: inventory/models.py:113 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/tags/invoice_item_formset.html:21 msgid "Available" msgstr "متاح" -#: inventory/models.py:112 +#: inventory/models.py:114 msgid "Sold" msgstr "تم البيع" -#: inventory/models.py:113 +#: inventory/models.py:115 msgid "Hold" msgstr "في الانتظار" -#: inventory/models.py:114 +#: inventory/models.py:116 msgid "Damaged" msgstr "تالف" -#: inventory/models.py:118 +#: inventory/models.py:117 +#, fuzzy +#| msgid "Reserve" +msgid "Reserved" +msgstr "حجز" + +#: inventory/models.py:121 msgid "New" msgstr "جديد" -#: inventory/models.py:119 +#: inventory/models.py:122 msgid "Used" msgstr "مستعمل" -#: inventory/models.py:128 inventory/models.py:405 +#: inventory/models.py:131 inventory/models.py:438 msgid "Dealer" msgstr "المعرض" -#: inventory/models.py:137 inventory/models.py:424 +#: inventory/models.py:140 inventory/models.py:458 #: templates/inventory/car_detail.html:108 #: templates/inventory/car_form.html:230 #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:359 @@ -86,29 +99,29 @@ msgstr "المعرض" msgid "Vendor" msgstr "المورد" -#: inventory/models.py:145 templates/inventory/car_inventory.html:55 +#: inventory/models.py:148 templates/inventory/car_inventory.html:55 msgid "Make" msgstr "الصانع" -#: inventory/models.py:153 templates/inventory/car_inventory.html:56 +#: inventory/models.py:156 templates/inventory/car_inventory.html:56 msgid "Model" msgstr "الموديل" -#: inventory/models.py:155 templates/inventory/car_form.html:118 +#: inventory/models.py:158 templates/inventory/car_form.html:118 #: templates/inventory/car_inventory.html:54 msgid "Year" msgstr "السنة" -#: inventory/models.py:162 templates/inventory/car_form.html:182 +#: inventory/models.py:165 templates/inventory/car_form.html:182 msgid "Series" msgstr "السلسلة" -#: inventory/models.py:170 +#: inventory/models.py:173 msgid "Trim" msgstr "الفئة" -#: inventory/models.py:176 templates/inventory/car_detail.html:86 -#: templates/inventory/car_list.html:163 +#: inventory/models.py:179 inventory/models.py:500 +#: templates/inventory/car_detail.html:86 templates/inventory/car_list.html:163 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_table.html:10 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/card_estimate.html:12 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:12 @@ -118,258 +131,338 @@ msgstr "الفئة" msgid "Status" msgstr "الحالة" -#: inventory/models.py:182 templates/inventory/car_detail.html:90 +#: inventory/models.py:185 templates/inventory/car_detail.html:90 #: templates/inventory/car_form.html:248 templates/inventory/car_list.html:177 msgid "Stock Type" msgstr "نوع المخزون" -#: inventory/models.py:184 templates/inventory/car_detail.html:113 +#: inventory/models.py:187 inventory/models.py:499 +#: templates/inventory/car_detail.html:113 #: templates/inventory/car_form.html:301 templates/inventory/car_list.html:200 +#: templates/sales/quotation_detail.html:23 msgid "Remarks" msgstr "ملاحظات" -#: inventory/models.py:185 templates/inventory/car_detail.html:94 +#: inventory/models.py:188 templates/inventory/car_detail.html:94 #: templates/inventory/car_form.html:265 templates/inventory/car_list.html:191 #: templates/inventory/car_list.html:192 msgid "Mileage" msgstr "عدد الكيلومترات" -#: inventory/models.py:186 templates/inventory/car_detail.html:98 +#: inventory/models.py:189 templates/inventory/car_detail.html:98 #: templates/inventory/car_form.html:283 msgid "Receiving Date" msgstr "تاريخ الاستلام" -#: inventory/models.py:189 inventory/models.py:355 inventory/models.py:369 +#: inventory/models.py:192 inventory/models.py:227 inventory/models.py:339 +#: inventory/models.py:356 inventory/models.py:402 inventory/models.py:532 +#: templates/sales/sales_order_detail.html:24 msgid "Car" msgstr "السيارة" -#: inventory/models.py:190 +#: inventory/models.py:193 msgid "Cars" msgstr "السيارات" -#: inventory/models.py:237 templates/inventory/car_detail.html:160 +#: inventory/models.py:228 templates/inventory/car_detail.html:277 +msgid "Reserved By" +msgstr "محجوز بواسطة" + +#: inventory/models.py:229 +#, fuzzy +#| msgid "Reserved By" +msgid "Reserved At" +msgstr "محجوز بواسطة" + +#: inventory/models.py:230 +#, fuzzy +#| msgid "Reserved By" +msgid "Reserved Until" +msgstr "محجوز بواسطة" + +#: inventory/models.py:238 +#, fuzzy +#| msgid "Registration" +msgid "Car Reservation" +msgstr "التسجيل" + +#: inventory/models.py:239 +#, fuzzy +#| msgid "Registrations" +msgid "Car Reservations" +msgstr "تسجيل السيارات" + +#: inventory/models.py:245 templates/inventory/car_detail.html:179 msgid "Cost Price" msgstr "سعر التكلفة" -#: inventory/models.py:240 -msgid "Profit Margin" -msgstr "هامش الربح" - -#: inventory/models.py:244 templates/inventory/car_detail.html:165 +#: inventory/models.py:246 templates/inventory/car_detail.html:183 +#: templates/sales/sales_order_detail.html:25 msgid "Selling Price" msgstr "سعر البيع" -#: inventory/models.py:247 templates/inventory/car_detail.html:189 -msgid "VAT Amount" +#: inventory/models.py:249 +msgid "Profit Margin" +msgstr "هامش الربح" + +#: inventory/models.py:253 +#, fuzzy +#| msgid "VAT Amount" +msgid "Vat Amount" msgstr "مبلغ ضريبة القيمة المضافة" -#: inventory/models.py:251 templates/inventory/car_detail.html:173 -msgid "Registration Fee" -msgstr "رسوم التسجيل" - -#: inventory/models.py:255 templates/inventory/car_detail.html:169 -msgid "Administration Fee" -msgstr "الرسوم الادارية" - -#: inventory/models.py:259 templates/inventory/car_detail.html:177 -msgid "Transportation Fee" -msgstr "رسوم النقل" - -#: inventory/models.py:263 templates/inventory/car_detail.html:181 -msgid "Custom Card Fee" -msgstr "رسوم البطاقة الجمركية" - -#: inventory/models.py:267 templates/inventory/car_detail.html:185 +#: inventory/models.py:255 templates/inventory/car_detail.html:203 msgid "Discount Amount" msgstr "مبلغ الخصم" -#: inventory/models.py:271 -msgid "Total Amount" -msgstr "المبلغ الإجمالي" +#: inventory/models.py:257 templates/inventory/car_detail.html:191 +msgid "Registration Fee" +msgstr "رسوم التسجيل" -#: inventory/models.py:275 -msgid "Car Financial Details" -msgstr "تفاصيل المالية للسيارة" +#: inventory/models.py:259 templates/inventory/car_detail.html:187 +msgid "Administration Fee" +msgstr "الرسوم الادارية" -#: inventory/models.py:280 -msgid "Selling price cannot be negative." -msgstr "لا يمكن أن يكون سعر البيع سالبًا." +#: inventory/models.py:261 templates/inventory/car_detail.html:195 +msgid "Transportation Fee" +msgstr "رسوم النقل" -#: inventory/models.py:282 -msgid "Discount amount cannot be negative." -msgstr "لا يمكن أن يكون مبلغ الخصم سالبًا." +#: inventory/models.py:263 templates/inventory/car_detail.html:199 +msgid "Custom Card Fee" +msgstr "رسوم البطاقة الجمركية" -#: inventory/models.py:284 -msgid "Discount amount cannot exceed selling price." -msgstr "لا يمكن أن يتجاوز مبلغ الخصم سعر البيع." - -#: inventory/models.py:289 -msgid "Fees cannot be negative." -msgstr "لا يمكن أن تكون الرسوم سلبية." - -#: inventory/models.py:304 +#: inventory/models.py:281 #, python-format msgid "Invalid decimal operation: %s" msgstr "عملية عشرية غير صالحة: %s" -#: inventory/models.py:313 inventory/models.py:326 +#: inventory/models.py:292 inventory/models.py:293 +msgid "Car Financial Details" +msgstr "تفاصيل المالية للسيارة" + +#: inventory/models.py:297 inventory/models.py:310 #: templates/dealers/dealer_detail.html:26 -#: templates/vendors/view_vendor.html:39 +#: templates/sales/quotation_detail.html:14 +#: templates/vendors/vendors_list.html:34 templates/vendors/view_vendor.html:48 #: venv/lib/python3.11/site-packages/django_ledger/forms/coa.py:16 #: venv/lib/python3.11/site-packages/django_ledger/forms/coa.py:37 msgid "Name" msgstr "الاسم" -#: inventory/models.py:314 inventory/models.py:327 inventory/models.py:398 -#: inventory/models.py:417 +#: inventory/models.py:298 inventory/models.py:311 inventory/models.py:431 +#: inventory/models.py:450 msgid "Arabic Name" msgstr "الاسم بالعربية" -#: inventory/models.py:315 inventory/models.py:328 +#: inventory/models.py:299 inventory/models.py:312 msgid "RGB" msgstr "آر جي بي" -#: inventory/models.py:318 inventory/models.py:319 +#: inventory/models.py:302 inventory/models.py:303 +#: templates/inventory/add_colors.html:13 msgid "Exterior Colors" msgstr "الألوان الخارجية" -#: inventory/models.py:331 inventory/models.py:332 +#: inventory/models.py:315 inventory/models.py:316 +#: templates/inventory/add_colors.html:32 msgid "Interior Colors" msgstr "الألوان الداخلية" -#: inventory/models.py:345 +#: inventory/models.py:329 msgid "Color" msgstr "اللون" -#: inventory/models.py:346 +#: inventory/models.py:330 msgid "Colors" msgstr "الألوان" -#: inventory/models.py:356 templates/inventory/car_detail.html:131 +#: inventory/models.py:340 templates/inventory/car_detail.html:131 msgid "Custom Number" msgstr "رقم البطاقة الجمركية" -#: inventory/models.py:360 templates/inventory/car_detail.html:16 +#: inventory/models.py:344 templates/inventory/car_detail.html:16 #: templates/inventory/car_detail.html:141 msgid "Custom Card" msgstr "البطاقة الجمركية" -#: inventory/models.py:361 +#: inventory/models.py:345 msgid "Custom Cards" msgstr "البطاقات الجمركية" +#: inventory/models.py:362 +msgid "Owner" +msgstr "المالك" + +#: inventory/models.py:363 +msgid "Dealer who owns the car." +msgstr "التاجر الذي يمتلك السيارة." + +#: inventory/models.py:369 +msgid "Showroom" +msgstr "صالة العرض" + #: inventory/models.py:370 +msgid "Dealer where the car is displayed (can be the owner)." +msgstr "التاجر الذي تُعرض السيارة في صالته (يمكن أن يكون المالك)." + +#: inventory/models.py:375 +#: venv/lib/python3.11/site-packages/django_ledger/forms/coa.py:17 +#: venv/lib/python3.11/site-packages/django_ledger/forms/coa.py:38 +#: venv/lib/python3.11/site-packages/django_ledger/models/data_import.py:61 +#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1144 +#: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:314 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:9 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:11 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:14 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:46 +msgid "Description" +msgstr "الوصف" + +#: inventory/models.py:376 +msgid "Optional description about the showroom placement." +msgstr "وصف اختياري حول وضع السيارة في صالة العرض." + +#: inventory/models.py:380 inventory/models.py:501 inventory/models.py:563 +#: templates/sales/quotation_list.html:17 +#, fuzzy +#| msgid "Created" +msgid "Created At" +msgstr "تاريخ الإنشاء" + +#: inventory/models.py:384 +#, fuzzy +#| msgid "Updated" +msgid "Last Updated" +msgstr "تم التحديث" + +#: inventory/models.py:388 +#, fuzzy +#| msgid "actions" +msgid "Car Location" +msgstr "الإجراءات" + +#: inventory/models.py:389 +#, fuzzy +#| msgid "actions" +msgid "Car Locations" +msgstr "الإجراءات" + +#: inventory/models.py:403 msgid "Plate Number" msgstr "رقم اللوحة" -#: inventory/models.py:371 +#: inventory/models.py:404 msgid "Text 1" msgstr "النص 1" -#: inventory/models.py:372 +#: inventory/models.py:405 msgid "Text 2" msgstr "النص 2" -#: inventory/models.py:373 +#: inventory/models.py:406 msgid "Text 3" msgstr "النص 3" -#: inventory/models.py:374 +#: inventory/models.py:407 msgid "Registration Date" msgstr "تاريخ التسجيل" -#: inventory/models.py:377 +#: inventory/models.py:410 msgid "Registration" msgstr "التسجيل" -#: inventory/models.py:378 +#: inventory/models.py:411 msgid "Registrations" msgstr "تسجيل السيارات" -#: inventory/models.py:386 inventory/models.py:441 +#: inventory/models.py:419 inventory/models.py:475 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/chart_of_accounts/includes/coa_card.html:38 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_table.html:12 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:17 msgid "Created" msgstr "تاريخ الإنشاء" -#: inventory/models.py:387 +#: inventory/models.py:420 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/chart_of_accounts/includes/coa_card.html:41 msgid "Updated" msgstr "تم التحديث" -#: inventory/models.py:396 inventory/models.py:415 +#: inventory/models.py:429 inventory/models.py:448 #: templates/dealers/dealer_detail.html:30 msgid "Commercial Registration Number" msgstr "رقم السجل التجاري" -#: inventory/models.py:397 inventory/models.py:416 +#: inventory/models.py:430 inventory/models.py:449 #: templates/dealers/dealer_detail.html:34 msgid "VAT Registration Number" msgstr "رقم التسجيل في ضريبة القيمة المضافة" -#: inventory/models.py:399 inventory/models.py:418 +#: inventory/models.py:432 inventory/models.py:451 msgid "English Name" msgstr "الاسم بالإنجليزية" -#: inventory/models.py:400 inventory/models.py:420 inventory/models.py:439 +#: inventory/models.py:433 inventory/models.py:453 inventory/models.py:473 #: templates/customers/view_customer.html:53 #: templates/dealers/dealer_detail.html:38 -#: templates/vendors/view_vendor.html:44 +#: templates/vendors/view_vendor.html:54 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:113 msgid "Phone Number" msgstr "رقم الهاتف" -#: inventory/models.py:401 inventory/models.py:421 inventory/models.py:440 +#: inventory/models.py:434 inventory/models.py:454 inventory/models.py:474 #: templates/customers/view_customer.html:54 #: templates/dealers/dealer_detail.html:42 -#: templates/vendors/view_vendor.html:46 +#: templates/sales/quotation_detail.html:16 +#: templates/vendors/vendors_list.html:36 templates/vendors/view_vendor.html:60 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/tags/customer_table.html:10 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/vendor/tags/vendor_table.html:11 msgid "Address" msgstr "العنوان" -#: inventory/models.py:402 +#: inventory/models.py:435 inventory/models.py:455 +#: templates/vendors/vendors_list.html:35 msgid "Logo" msgstr "الشعار" -#: inventory/models.py:406 +#: inventory/models.py:439 msgid "Dealers" msgstr "المعارض" -#: inventory/models.py:419 templates/vendors/view_vendor.html:43 +#: inventory/models.py:452 templates/vendors/view_vendor.html:51 msgid "Contact Person" msgstr "الشخص المسؤول" -#: inventory/models.py:425 templates/header.html:85 templates/header.html:100 +#: inventory/models.py:459 templates/header.html:85 templates/header.html:100 #: templates/vendors/vendor_form.html:4 templates/vendors/vendors_list.html:4 -#: templates/vendors/vendors_list.html:5 +#: templates/vendors/vendors_list.html:5 templates/vendors/vendors_list.html:11 msgid "Vendors" msgstr "الموردين" -#: inventory/models.py:434 templates/customers/view_customer.html:46 +#: inventory/models.py:468 templates/customers/view_customer.html:46 msgid "First Name" msgstr "الاسم الأول" -#: inventory/models.py:435 templates/customers/view_customer.html:47 +#: inventory/models.py:469 templates/customers/view_customer.html:47 msgid "Middle Name" msgstr "اسم الأب" -#: inventory/models.py:436 templates/customers/view_customer.html:48 +#: inventory/models.py:470 templates/customers/view_customer.html:48 msgid "Last Name" msgstr "اسم العائلة" -#: inventory/models.py:437 templates/customers/view_customer.html:51 -#: templates/vendors/view_vendor.html:45 +#: inventory/models.py:471 templates/customers/view_customer.html:51 +#: templates/vendors/view_vendor.html:57 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:111 msgid "Email" msgstr "البريد الإلكتروني" -#: inventory/models.py:438 templates/customers/view_customer.html:52 +#: inventory/models.py:472 templates/customers/view_customer.html:52 msgid "National ID" msgstr "رقم الهوية الوطنية" -#: inventory/models.py:444 +#: inventory/models.py:478 inventory/models.py:497 +#: templates/sales/quotation_list.html:14 +#: templates/sales/sales_order_detail.html:12 #: venv/lib/python3.11/site-packages/django_ledger/models/customer.py:199 #: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:252 #: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:318 @@ -378,15 +471,78 @@ msgstr "رقم الهوية الوطنية" msgid "Customer" msgstr "العميل" -#: inventory/models.py:445 +#: inventory/models.py:479 msgid "Customers" msgstr "العملاء" -#: inventory/models.py:467 -#: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:436 -#: venv/lib/python3.11/site-packages/django_ledger/models/coa.py:152 -msgid "Chart of Accounts" -msgstr "قائمة الحسابات" +#: inventory/models.py:492 +#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:338 +#: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:223 +#: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:299 +#: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:192 +msgid "Draft" +msgstr "مسودة" + +#: inventory/models.py:493 +#, fuzzy +#| msgid "Confirm" +msgid "Confirmed" +msgstr "تأكيد" + +#: inventory/models.py:494 +#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:342 +#: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:228 +#: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:304 +#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1042 +#: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:196 +msgid "Canceled" +msgstr "ملغى" + +#: inventory/models.py:498 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:491 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/po_item_formset.html:22 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/tags/po_item_table.html:11 +msgid "Amount" +msgstr "المبلغ" + +#: inventory/models.py:502 +#, fuzzy +#| msgid "Updated" +msgid "Updated At" +msgstr "تم التحديث" + +#: inventory/models.py:507 +msgid "Only draft quotations can be confirmed." +msgstr "لا يمكن تأكيد سوى العروض التقديرية المسودة." + +#: inventory/models.py:514 +msgid "Cannot cancel a confirmed quotation." +msgstr "لا يمكن إلغاء عرض تقديري تم تأكيده." + +#: inventory/models.py:527 inventory/models.py:562 +#, fuzzy +#| msgid "Duration" +msgid "Quotation" +msgstr "المدة" + +#: inventory/models.py:535 +#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1068 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:97 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_item_formset.html:21 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_item_table.html:10 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/tags/ce_item_formset.html:19 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/invoice_detail.html:96 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/tags/invoice_item_formset.html:19 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/po_item_formset.html:20 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/po_update.html:51 +msgid "Quantity" +msgstr "الكمية" + +#: inventory/models.py:564 templates/sales/quotation_list.html:16 +#: templates/sales/sales_order_detail.html:16 +#: templates/sales/sales_order_detail.html:27 +msgid "Total Amount" +msgstr "المبلغ الإجمالي" #: inventory/utils.py:25 msgid "success" @@ -404,99 +560,109 @@ msgstr "نسيت كلمة المرور؟" msgid "You are not associated with any dealer." msgstr "أنت غير مرتبط بأي معرض." -#: inventory/views.py:260 templates/header.html:33 templates/index.html:20 +#: inventory/views.py:221 templates/header.html:33 templates/index.html:20 #: templates/inventory/car_inventory.html:5 #: templates/inventory/car_inventory.html:7 msgid "inventory" msgstr "المخزون" -#: inventory/views.py:401 +#: inventory/views.py:362 msgid "Car finance details saved successfully." msgstr "تم حفظ تفاصيل المالية للسيارة بنجاح." -#: inventory/views.py:419 +#: inventory/views.py:380 msgid "Car finance updated successfully." msgstr "تم تحديث التفاصيل المالية للسيارة بنجاح." -#: inventory/views.py:432 +#: inventory/views.py:393 msgid "Car updated successfully." msgstr "تم تحديث السيارة بنجاح" -#: inventory/views.py:445 +#: inventory/views.py:406 msgid "Car deleted successfully." msgstr "تم حذف السيارة بنجاح." -#: inventory/views.py:465 +#: inventory/views.py:451 msgid "Custom Card added successfully." msgstr "تم إضافة البطاقة الجمركية بنجاح." -#: inventory/views.py:474 +#: inventory/views.py:460 msgid "This car is already reserved." msgstr "هذه السيارة محجوزة بالفعل." -#: inventory/views.py:484 +#: inventory/views.py:470 msgid "Car reserved successfully." msgstr "تم حجز السيارة بنجاح." -#: inventory/views.py:501 +#: inventory/views.py:487 msgid "Reservation renewed successfully." msgstr "تم تجديد الحجز بنجاح" -#: inventory/views.py:506 +#: inventory/views.py:492 msgid "Reservation canceled successfully." msgstr "تم إلغاء الحجز بنجاح." -#: inventory/views.py:510 +#: inventory/views.py:496 msgid "Invalid action." msgstr "إجراء غير صالح." -#: inventory/views.py:512 +#: inventory/views.py:498 msgid "Invalid request method." msgstr "طريقة الطلب غير صالحة" -#: inventory/views.py:534 +#: inventory/views.py:520 msgid "Dealer created successfully." msgstr "تم إنشاء المعرض بنجاح." -#: inventory/views.py:545 +#: inventory/views.py:531 msgid "Dealer updated successfully." msgstr "تم تحديث المعرض بنجاح." -#: inventory/views.py:555 +#: inventory/views.py:541 msgid "Dealer deleted successfully." msgstr "تم حذف المعرض بنجاح." -#: inventory/views.py:561 templates/customers/customer_form.html:4 +#: inventory/views.py:547 templates/customers/customer_form.html:4 #: templates/customers/customer_list.html:5 #: templates/customers/customer_list.html:6 templates/header.html:59 #: templates/header.html:74 msgid "customers" msgstr "العملاء" -#: inventory/views.py:600 +#: inventory/views.py:586 msgid "Customer created successfully." msgstr "تم إنشاء العميل بنجاح." -#: inventory/views.py:616 +#: inventory/views.py:602 msgid "Customer updated successfully." msgstr "تم تحديث العميل بنجاح." -#: inventory/views.py:626 +#: inventory/views.py:612 msgid "Customer deleted successfully." msgstr "تم حذف العميل بنجاح." -#: inventory/views.py:652 +#: inventory/views.py:638 msgid "Vendor created successfully." msgstr "تم إنشاء المورد بنجاح." -#: inventory/views.py:668 +#: inventory/views.py:654 msgid "Vendor updated successfully." msgstr "تم تحديث المورد بنجاح" -#: inventory/views.py:678 +#: inventory/views.py:664 msgid "Vendor deleted successfully." msgstr "تم حذف المورد بنجاح." +#: inventory/views.py:684 +#, fuzzy +#| msgid "Customer created successfully." +msgid "Quotation created successfully." +msgstr "تم إنشاء العميل بنجاح." + +#: inventory/views.py:717 +msgid "Quotation confirmed and sales order created." +msgstr "تم تأكيد عرض السعر وإنشاء أمر البيع." + #: templates/accounts/login.html:6 templates/accounts/login.html:14 #: templates/accounts/login.html:31 templates/header.html:131 msgid "Sign In" @@ -597,12 +763,13 @@ msgid "Add Customer" msgstr "إضافة عميل" #: templates/customers/customer_form.html:31 -#: templates/inventory/add_colors.html:54 +#: templates/inventory/add_colors.html:55 #: templates/inventory/add_custom_card.html:7 #: templates/inventory/car_edit.html:41 #: templates/inventory/car_finance_form.html:40 +#: templates/inventory/car_location_form.html:17 #: templates/inventory/color_palette.html:106 -#: templates/vendors/vendor_form.html:31 +#: templates/sales/quotation_form.html:18 templates/vendors/vendor_form.html:31 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_item_formset.html:81 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/closing_entry_update.html:19 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html:78 @@ -614,14 +781,14 @@ msgid "Save" msgstr "حفظ" #: templates/customers/customer_form.html:33 -#: templates/inventory/add_colors.html:55 +#: templates/inventory/add_colors.html:56 #: templates/inventory/add_custom_card.html:8 #: templates/inventory/car_confirm_delete.html:14 -#: templates/inventory/car_detail.html:282 +#: templates/inventory/car_detail.html:301 #: templates/inventory/car_finance_form.html:41 #: templates/inventory/color_palette.html:107 #: templates/inventory/reserve_car.html:30 -#: templates/vendors/vendor_form.html:33 +#: templates/sales/quotation_form.html:19 templates/vendors/vendor_form.html:33 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_create.html:37 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:205 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/components/modals.html:11 @@ -634,7 +801,7 @@ msgstr "إلغاء" #: templates/customers/customer_list.html:20 #: templates/inventory/car_inventory.html:31 -#: templates/inventory/car_list.html:70 templates/vendors/vendors_list.html:21 +#: templates/inventory/car_list.html:70 msgid "search" msgstr "بحث" @@ -655,14 +822,12 @@ msgid "national ID" msgstr "رقم الهوية الوطنية" #: templates/customers/customer_list.html:46 -#: templates/vendors/vendors_list.html:46 msgid "actions" msgstr "الإجراءات" #: templates/customers/customer_list.html:59 #: templates/inventory/car_detail.html:124 #: templates/inventory/car_inventory.html:75 -#: templates/vendors/vendors_list.html:65 msgid "view" msgstr "عرض" @@ -675,24 +840,25 @@ msgid "Are you sure you want to delete this customer?" msgstr "هل أنت متأكد أنك تريد حذف هذا العميل؟" #: templates/customers/view_customer.html:26 -#: templates/vendors/view_vendor.html:25 +#: templates/vendors/view_vendor.html:29 #: venv/lib/python3.11/site-packages/django/forms/widgets.py:802 msgid "No" msgstr "لا" #: templates/customers/view_customer.html:31 -#: templates/vendors/view_vendor.html:30 +#: templates/vendors/view_vendor.html:32 #: venv/lib/python3.11/site-packages/django/forms/widgets.py:801 msgid "Yes" msgstr "نعم" #: templates/customers/view_customer.html:41 +#: templates/sales/quotation_detail.html:12 msgid "Customer Details" msgstr "تفاصيل العميل" #: templates/customers/view_customer.html:61 -#: templates/inventory/car_detail.html:307 -#: templates/vendors/view_vendor.html:48 +#: templates/inventory/car_detail.html:329 +#: templates/vendors/view_vendor.html:66 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/includes/card_customer.html:28 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:83 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:101 @@ -701,7 +867,7 @@ msgid "Edit" msgstr "تحديث" #: templates/customers/view_customer.html:67 -#: templates/vendors/view_vendor.html:53 +#: templates/vendors/view_vendor.html:69 #: venv/lib/python3.11/site-packages/django/forms/formsets.py:499 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_delete.html:28 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_item_formset.html:25 @@ -733,7 +899,7 @@ msgid "Delete" msgstr "حذف" #: templates/customers/view_customer.html:72 -#: templates/inventory/car_detail.html:309 +#: templates/inventory/car_detail.html:331 msgid "Back to List" msgstr "العودة إلى القائمة" @@ -816,14 +982,6 @@ msgstr "حفظ تغيير" msgid "Back" msgstr "عودة" -#: templates/footer.html:5 -msgid "All right reserved" -msgstr "جميع الحقوق محفوظة" - -#: templates/footer.html:5 -msgid "Tenhal" -msgstr "تنحل" - #: templates/header.html:25 templates/header.html:108 templates/index.html:5 msgid "home" msgstr "الرئيسية" @@ -888,13 +1046,6 @@ msgstr "قيمة المخزون" msgid "View the current value of your car inventory." msgstr "عرض القيمة الحالية لمخزون السيارات الخاص بك." -#: templates/index.html:59 templates/index.html:62 templates/index.html:80 -#: templates/index.html:87 templates/index.html:116 templates/index.html:122 -#: templates/index.html:128 templates/index.html:163 templates/index.html:171 -#: templates/index.html:179 -msgid "SAR" -msgstr "ريال سعودي" - #: templates/index.html:61 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/includes/widget_ratios.html:31 msgid "Profitability" @@ -1024,17 +1175,8 @@ msgstr "إضافة لون" msgid "Select exterior and interior colors for" msgstr "اختر الألوان الخارجية والداخلية لـ" -#: templates/inventory/add_colors.html:13 -#: templates/inventory/car_detail.html:219 -msgid "Exterior" -msgstr "الخارجي" - -#: templates/inventory/add_colors.html:32 -#: templates/inventory/car_detail.html:228 -msgid "Interior" -msgstr "الداخلي" - #: templates/inventory/car_detail.html:6 templates/inventory/car_detail.html:58 +#: templates/sales/quotation_detail.html:27 msgid "Car Details" msgstr "تفاصيل السيارة" @@ -1068,14 +1210,35 @@ msgid "Branch" msgstr "الفرع" #: templates/inventory/car_detail.html:147 +#: templates/inventory/car_detail.html:166 msgid "Add" msgstr "إضافة" -#: templates/inventory/car_detail.html:156 +#: templates/inventory/car_detail.html:153 +msgid "Showroom Location" +msgstr "موقع صالة العرض" + +#: templates/inventory/car_detail.html:157 +msgid "Our Showroom" +msgstr "معرضنا" + +#: templates/inventory/car_detail.html:163 +#, fuzzy +#| msgid "No options available." +msgid "No location available." +msgstr "لا توجد سيارات متاحة." + +#: templates/inventory/car_detail.html:175 msgid "Financial Details" msgstr "التفاصيل المالية" -#: templates/inventory/car_detail.html:193 +#: templates/inventory/car_detail.html:207 +#: templates/sales/quotation_detail.html:66 +#: templates/sales/sales_order_detail.html:26 +msgid "VAT Amount" +msgstr "مبلغ ضريبة القيمة المضافة" + +#: templates/inventory/car_detail.html:211 #: templates/inventory/inventory_stats.html:61 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:98 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:127 @@ -1094,44 +1257,50 @@ msgstr "التفاصيل المالية" msgid "Total" msgstr "الإجمالي" -#: templates/inventory/car_detail.html:200 +#: templates/inventory/car_detail.html:218 msgid "Edit Finance Details" msgstr "تعديل التفاصيل المالية" -#: templates/inventory/car_detail.html:204 +#: templates/inventory/car_detail.html:222 msgid "No finance details available." msgstr "لا توجد تفاصيل مالية متاحة." -#: templates/inventory/car_detail.html:207 +#: templates/inventory/car_detail.html:225 msgid "Add Finance Details" msgstr "إضافة التفاصيل المالية" -#: templates/inventory/car_detail.html:213 +#: templates/inventory/car_detail.html:231 msgid "Colors Details" msgstr "تفاصيل الألوان" -#: templates/inventory/car_detail.html:240 +#: templates/inventory/car_detail.html:237 +msgid "Exterior" +msgstr "الخارجي" + +#: templates/inventory/car_detail.html:246 +msgid "Interior" +msgstr "الداخلي" + +#: templates/inventory/car_detail.html:258 msgid "No colors available for this car." msgstr "لا تتوفر ألوان لهذه السيارة." -#: templates/inventory/car_detail.html:247 +#: templates/inventory/car_detail.html:265 msgid "Get Colors" msgstr "الحصول على الألوان" -#: templates/inventory/car_detail.html:254 +#: templates/inventory/car_detail.html:272 msgid "Reservations Details" msgstr "تفاصيل الحجز" -#: templates/inventory/car_detail.html:259 -msgid "Reserved By" -msgstr "محجوز بواسطة" - -#: templates/inventory/car_detail.html:260 +#: templates/inventory/car_detail.html:278 msgid "Expires At" msgstr "ينتهي في" -#: templates/inventory/car_detail.html:261 +#: templates/inventory/car_detail.html:279 #: templates/inventory/car_inventory.html:57 +#: templates/sales/quotation_list.html:18 +#: templates/vendors/vendors_list.html:37 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/account_txs_table.html:29 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:29 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:92 @@ -1158,27 +1327,31 @@ msgstr "ينتهي في" msgid "Actions" msgstr "الإجراءات" -#: templates/inventory/car_detail.html:276 -msgid "renew" +#: templates/inventory/car_detail.html:295 +msgid "Renew" msgstr "تجديد" -#: templates/inventory/car_detail.html:293 +#: templates/inventory/car_detail.html:305 +msgid "Expired" +msgstr "ينتهي في" + +#: templates/inventory/car_detail.html:315 #: templates/inventory/reserve_car.html:29 msgid "Reserve" msgstr "حجز" -#: templates/inventory/car_detail.html:305 +#: templates/inventory/car_detail.html:327 #: templates/inventory/transfer_car.html:23 msgid "transfer" msgstr "نقل" -#: templates/inventory/car_detail.html:394 +#: templates/inventory/car_detail.html:416 #: templates/inventory/car_list.html:542 #: templates/partials/specifications_modal.html:11 msgid "No specifications available." msgstr "لا توجد مواصفات متاحة." -#: templates/inventory/car_detail.html:398 +#: templates/inventory/car_detail.html:420 #: templates/inventory/car_list.html:546 msgid "Error loading specifications." msgstr "حدث خطأ أثناء تحميل المواصفات." @@ -1215,14 +1388,14 @@ msgstr "رقم الهيكل سيظهر هنا." msgid "Use OCR Fallback" msgstr "التعرف الآلي على الحروف" -#: templates/inventory/car_form.html:100 +#: templates/inventory/car_form.html:100 templates/vendors/vendors_list.html:15 msgid "Search" msgstr "بحث" #: templates/inventory/car_form.html:165 templates/inventory/car_form.html:187 -#: templates/inventory/car_form.html:209 templates/inventory/car_form.html:519 -#: templates/inventory/car_form.html:536 templates/inventory/car_form.html:537 -#: templates/inventory/car_form.html:555 +#: templates/inventory/car_form.html:209 templates/inventory/car_form.html:525 +#: templates/inventory/car_form.html:544 templates/inventory/car_form.html:545 +#: templates/inventory/car_form.html:563 msgid "Select" msgstr "اختيار" @@ -1242,15 +1415,15 @@ msgstr "الرجاء الإنتظار" msgid "Loading" msgstr "تحميل" -#: templates/inventory/car_form.html:431 +#: templates/inventory/car_form.html:431 templates/inventory/car_form.html:432 msgid "Please enter a valid VIN." msgstr "الرجاء إدخال رقم هيكل صالح مكون من 17 حرفًا." -#: templates/inventory/car_form.html:447 +#: templates/inventory/car_form.html:450 msgid "Failed to decode VIN." msgstr "فشل في فك تشفير رقم الهيكل" -#: templates/inventory/car_form.html:452 +#: templates/inventory/car_form.html:455 templates/inventory/car_form.html:456 msgid "An error occurred while decoding the VIN." msgstr "حدث خطأ أثناء فك تشفير الهيكل" @@ -1312,6 +1485,13 @@ msgstr "لا توجد سيارات متاحة." msgid "Error loading options." msgstr "خطأ في تحميل الخيارات." +#: templates/inventory/car_location_form.html:4 +#: templates/inventory/car_location_form.html:12 +#, fuzzy +#| msgid "actions" +msgid "Manage Car Location" +msgstr "الإجراءات" + #: templates/inventory/color_palette.html:74 msgid "Update Color" msgstr "تحديث اللون" @@ -1386,47 +1566,108 @@ msgstr "الماسح الضوئي" msgid "Specifications" msgstr "المواصفات" +#: templates/sales/quotation_detail.html:7 +msgid "Quotation Details" +msgstr "تفاصيل عرض السعر" + +#: templates/sales/quotation_detail.html:17 +msgid "VAT No" +msgstr "الرقم الضريبي" + +#: templates/sales/quotation_detail.html:20 +msgid "Quotation Information" +msgstr "معلومات عرض السعر" + +#: templates/sales/quotation_detail.html:21 +msgid "Quotation No" +msgstr "رقم عرض السعر" + +#: templates/sales/quotation_detail.html:22 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:15 +msgid "Date" +msgstr "التاريخ" + +#: templates/sales/quotation_detail.html:59 +msgid "Summary" +msgstr "الملخص" + +#: templates/sales/quotation_detail.html:62 +msgid "Total Sales Before VAT" +msgstr "إجمالي المبيعات قبل ضريبة القيمة المضافة" + +#: templates/sales/quotation_detail.html:70 +msgid "Total Sales After VAT" +msgstr "إجمالي المبيعات بعد ضريبة القيمة المضافة" + +#: templates/sales/quotation_detail.html:76 +msgid "Back to Quotations" +msgstr "العودة إلى قائمة عروض الأسعار" + +#: templates/sales/quotation_form.html:5 templates/sales/quotation_form.html:9 +msgid "Create Quotation" +msgstr "إنشاء عرض سعر" + +#: templates/sales/quotation_list.html:4 templates/sales/quotation_list.html:8 +msgid "Quotations" +msgstr "عروض الأسعار" + +#: templates/sales/quotation_list.html:15 +msgid "Total Cars" +msgstr "إجمالي عدد السيارات" + +#: templates/sales/quotation_list.html:31 +#: templates/vendors/vendors_list.html:55 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:44 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/entity/entitiy_list.html:20 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:38 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:85 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/card_po.html:22 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/unit/unit_list.html:32 +msgid "View" +msgstr "عرض" + +#: templates/sales/quotation_list.html:38 +msgid "No Quotations Found" +msgstr "لم يتم العثور على عروض أسعار" + +#: templates/sales/sales_order_detail.html:2 +#: templates/sales/sales_order_detail.html:5 +msgid "Sales Order Details" +msgstr "تفاصيل أمر البيع" + +#: templates/sales/sales_order_detail.html:8 +msgid "Quotation ID" +msgstr "رقم عرض السعر" + +#: templates/sales/sales_order_detail.html:21 +msgid "Cars in Sales Order" +msgstr "السيارات في أمر البيع" + #: templates/vendors/vendor_form.html:14 msgid "Edit Vendor" -msgstr "تحديث المورد" +msgstr "تعديل المورد" -#: templates/vendors/vendors_list.html:42 -msgid "name" -msgstr "الاسم" +#: templates/vendors/vendors_list.html:20 +msgid "Enter vendor name" +msgstr "أدخل اسم المورد" -#: templates/vendors/vendors_list.html:45 -msgid "address" -msgstr "العنوان" - -#: templates/vendors/vendors_list.html:72 -msgid "no vendors found" +#: templates/vendors/vendors_list.html:62 +msgid "No vendors found" msgstr "لم يتم العثور على موردين" -#: templates/vendors/vendors_list.html:82 -msgid "first" -msgstr "الأول" - -#: templates/vendors/vendors_list.html:87 -msgid "previous" -msgstr "السابق" - -#: templates/vendors/vendors_list.html:112 -msgid "next" -msgstr "التالي" - -#: templates/vendors/vendors_list.html:117 -msgid "last" -msgstr "الأخير" - #: templates/vendors/view_vendor.html:3 msgid "View Vendor" msgstr "عرض المورد" #: templates/vendors/view_vendor.html:18 +msgid "Delete Vendor" +msgstr "حذف مورد" + +#: templates/vendors/view_vendor.html:24 msgid "Are you sure you want to delete this vendor?" msgstr "هل أنت متأكد أنك تريد حذف هذا المورد؟" -#: templates/vendors/view_vendor.html:37 +#: templates/vendors/view_vendor.html:43 msgid "Vendor Details" msgstr "تفاصيل المورد" @@ -2948,18 +3189,6 @@ msgstr "اختر تاريخ الإغلاق" msgid "Closing Entry Notes" msgstr "ملاحظات إدخال الإغلاق" -#: venv/lib/python3.11/site-packages/django_ledger/forms/coa.py:17 -#: venv/lib/python3.11/site-packages/django_ledger/forms/coa.py:38 -#: venv/lib/python3.11/site-packages/django_ledger/models/data_import.py:61 -#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1144 -#: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:314 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:9 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:11 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:14 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:46 -msgid "Description" -msgstr "الوصف" - #: venv/lib/python3.11/site-packages/django_ledger/forms/customer.py:40 #, python-format msgid "Example: 3.50% should be entered as 0.035" @@ -3594,6 +3823,11 @@ msgstr "مقفل" msgid "Active" msgstr "نشط" +#: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:436 +#: venv/lib/python3.11/site-packages/django_ledger/models/coa.py:152 +msgid "Chart of Accounts" +msgstr "قائمة الحسابات" + #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:443 #: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:485 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/bank_account_update.html:13 @@ -3658,13 +3892,6 @@ msgstr "يجب تمرير user_model عند استخدام entity_slug." msgid "Bank Account" msgstr "الحساب المصرفي" -#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:338 -#: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:223 -#: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:299 -#: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:192 -msgid "Draft" -msgstr "مسودة" - #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:339 #: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:224 #: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:300 @@ -3685,14 +3912,6 @@ msgstr "تمت الموافقة" msgid "Paid" msgstr "مدفوع" -#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:342 -#: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:228 -#: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:304 -#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1042 -#: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:196 -msgid "Canceled" -msgstr "ملغى" - #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:343 #: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:227 #: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:303 @@ -4567,18 +4786,6 @@ msgstr "نموذج الفاتورة" msgid "Invoice Model" msgstr "نموذج الفاتورة" -#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1068 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:97 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_item_formset.html:21 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_item_table.html:10 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/tags/ce_item_formset.html:19 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/invoice_detail.html:96 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/tags/invoice_item_formset.html:19 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/po_item_formset.html:20 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/po_update.html:51 -msgid "Quantity" -msgstr "الكمية" - #: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1072 msgid "Cost Per Unit" msgstr "التكلفة لكل وحدة" @@ -5018,12 +5225,6 @@ msgstr "إدخال دفتر اليومية المرتبط بهذه المعام msgid "Account from Chart of Accounts to be associated with this transaction." msgstr "الحساب من مخطط الحسابات المرتبط بهذه المعاملة." -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:491 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/po_item_formset.html:22 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/tags/po_item_table.html:11 -msgid "Amount" -msgstr "المبلغ" - #: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:492 msgid "Account of the transaction." msgstr "حساب المعاملة." @@ -5403,15 +5604,6 @@ msgstr "تكوين الفاتورة" msgid "Due in" msgstr "مستحق في" -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:44 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/entity/entitiy_list.html:20 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:38 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:85 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/card_po.html:22 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/unit/unit_list.html:32 -msgid "View" -msgstr "عرض" - #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:49 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:187 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:43 @@ -6234,10 +6426,6 @@ msgstr "تكوين الفاتورة" msgid "Journal Entry Detail" msgstr "تفاصيل إدخال اليومية" -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:15 -msgid "Date" -msgstr "التاريخ" - #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:47 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:108 msgid "UnLock" @@ -6800,3 +6988,11 @@ msgid "" "SILKY_AUTHENTICATION can not be enabled without Session, Authentication or " "Message Django's middlewares" msgstr "" + +#~ msgid "Location" +#~ msgstr "الموقع" + +#, fuzzy +#~| msgid "Net Income" +#~ msgid "Sales Income" +#~ msgstr "صافي الدخل" diff --git a/static/images/logos/.DS_Store b/static/images/logos/.DS_Store index 4ba9080d4950c7bdc3d6e8696bb8400888604c94..08b72d29754d2c04a64e3fac9529204acb356f7e 100644 GIT binary patch delta 46 jcmZn(XbISmF2-(Vs-s|JVYE3<>?b>dBZtfpo5lzLK<5o8 delta 46 jcmZn(XbISmF2-(brlVkNXt+5~>?b>dBZtfpo5lzLKClf9 diff --git a/templates/inventory/car_detail.html b/templates/inventory/car_detail.html index cf8ae4a2..a03ac8cf 100644 --- a/templates/inventory/car_detail.html +++ b/templates/inventory/car_detail.html @@ -149,6 +149,27 @@ {% endif %} + + {% trans 'Showroom Location' %} + + {% if car.location %} +{% if car.location.is_owner_showroom %} + {% trans 'Our Showroom' %} + {% else %} + {{ car.location.showroom.get_local_name }} + {% endif %} + {% trans "transfer" %} +{% else %} + + {% trans "No location available." %} + + {% trans "Add" %} + + + + {% endif %} +
@@ -304,7 +325,7 @@
- {% trans "transfer" %} + {% trans "Edit" %} diff --git a/templates/inventory/car_inventory.html b/templates/inventory/car_inventory.html index ead58f1d..3aba0a17 100644 --- a/templates/inventory/car_inventory.html +++ b/templates/inventory/car_inventory.html @@ -1,12 +1,13 @@ {% extends 'base.html' %} {% load i18n %} -{% load static %} {% block title %} {% trans 'inventory'|capfirst %} {% endblock %} -{% block inventory %}{% trans "inventory" %}(current){% endblock %} +{% block inventory %} +{% trans "inventory" %}(current) +{% endblock %} {% block content %} - +
-
-
-
- - -
-
-
- - - - {% if request.GET.q %} - - - - {% endif %} -
-
-
+
+
+
+
+
+
+ + + + {% if request.GET.q %} + + + + {% endif %} +
+
+
- - - - - - - - - - - - - {% for car in cars %} - - {% if car.colors.all %} - {% for color in car.colors.all %} - - {% endfor %} - {% else %} - - {% endif %} - - - - - - - {% empty %} - - - - {% endfor %} - -
{% trans "VIN" %}{% trans "Year" %}{% trans "Make" %}{% trans "Model" %}{% trans "Actions" %}
{{ car.vin }}{{ car.year }}{{ car.id_car_make.get_local_name }}{{ car.id_car_model.get_local_name }} - {% trans "view" %} -
{% trans "No cars available." %}
- - {% if is_paginated %} - - {% endif %} -
-
-
+ + + + + + + + + + + + + {% for car in cars %} + + + + {% if car.colors.exists %} + + + {% else %} + + + {% endif %} + {% if car.location.is_owner_showroom %} + + {% else %} + + {% endif %} + + + {% empty %} + + + + {% endfor %} + +
{% trans "VIN" %}{% trans "Year" %}{% trans 'Exterior Color' %}{% trans 'Interior Color' %}{% trans "Showroom Location" %}{% trans "Actions" %}
{{ car.vin }}{{ car.year }}{{ car.colors.first.exterior.get_local_name }}
{{ car.colors.first.interior.get_local_name }}
{% trans 'Our Showroom' %}{{ car.location.showroom.get_local_name }} + + {% trans "view" %} + +
{% trans "No cars available." %}
+ + + {% if is_paginated %} + + {% endif %} +
+
+
{% endblock %} \ No newline at end of file diff --git a/templates/inventory/car_location_form.html b/templates/inventory/car_location_form.html index 4bdcfcb8..6b6f6011 100644 --- a/templates/inventory/car_location_form.html +++ b/templates/inventory/car_location_form.html @@ -1,10 +1,22 @@ - - - - - $Title$ - - -$END$ - - \ No newline at end of file +{% extends 'base.html' %} +{% load i18n %} +{% load crispy_forms_filters %} +{% block title %}{% trans "Manage Car Location" %}{% endblock %} +{% block content %} + {% if carlocation.exists %} +

Transfer

+ {% else %} +

Add

+ {% endif %} +
+

{% trans "Manage Car Location" %}

+
+ {% csrf_token %} + {{ form|crispy }} +
+ + +
+
+
+{% endblock %} \ No newline at end of file