From c73485f7ab8611e7d2029354a3f3a8e47b563b2a Mon Sep 17 00:00:00 2001 From: Vincent Le Gallic Date: Tue, 28 Aug 2018 12:02:16 +0200 Subject: [PATCH 001/252] Typos in README --- README.md | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d3de9163..f4e38aa9 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Re2o -Gnu public license v2.0 +GNU public license v2.0 ## Avant propos -Re2o est un logiciel d'administration développé initiallement au rezometz. Il +Re2o est un logiciel d'administration développé initialement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en quelques clics. @@ -31,15 +31,15 @@ Pour cela : ## Fonctionnement général -Re2o est séparé entre les models, qui sont visible sur le schéma des -dépendances. Il s'agit en réalité des tables sql, et les fields etant les +Re2o est séparé entre les models, qui sont visibles sur le schéma des +dépendances. Il s'agit en réalité des tables sql, et les fields étant les colonnes. Ceci dit il n'est jamais nécessaire de toucher directement au sql, django procédant automatiquement à tout cela. On crée donc différents models (user, right pour les droits des users, interfaces, IpList pour l'ensemble des adresses ip, etc) -Du coté des forms, il s'agit des formulaire d'édition des models. Il +Du coté des forms, il s'agit des formulaires d'édition des models. Il s'agit de ModelForms django, qui héritent des models très simplement, voir la documentation django models forms. @@ -56,12 +56,20 @@ d'accéder à ces vues, utilisé par re2o-tools. # Requète en base de donnée -Pour avoir un shell, il suffit de lancer '''python3 manage.py shell''' -Pour charger des objets, example avec User, faire : -''' from users.models import User''' -Pour charger les objets django, il suffit de faire User.objects.all() -pour tous les users par exemple. -Il est ensuite aisé de faire des requètes, par exemple -User.objects.filter(pseudo='test') -Des exemples et la documentation complète sur les requètes django sont +Pour avoir un shell, lancer : +```.bash +python3 manage.py shell +``` + +Pour charger des objets (exemple avec User), faire : +```.python +from users.models import User +``` + +Pour charger les objets django, il suffit de faire `User.objects.all()` +pour tous les users par exemple. +Il est ensuite aisé de faire des requêtes, par exemple +`User.objects.filter(pseudo='test')` + +Des exemples et la documentation complète sur les requêtes django sont disponible sur le site officiel. From 5d30e95aa4e71f93ce9a3a5d858163678c5ba60c Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Tue, 28 Aug 2018 20:18:09 +0200 Subject: [PATCH 002/252] Ebauche, interface de capture de mac et d'enregistrement de chambre --- static/images/rj45.gif | Bin 0 -> 15546 bytes users/forms.py | 52 ++++++++++++++++++++++++++ users/templates/users/plugin_out.html | 41 ++++++++++++++++++++ users/urls.py | 1 + users/views.py | 25 ++++++++++++- 5 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 static/images/rj45.gif create mode 100644 users/templates/users/plugin_out.html diff --git a/static/images/rj45.gif b/static/images/rj45.gif new file mode 100644 index 0000000000000000000000000000000000000000..69630b10c95605502bcc1cc1efb4f16ccae18a7d GIT binary patch literal 15546 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 machine et votre chambre ont bien été enregistrées. Merci de débrancher et rebrancher votre cable RJ45 pour bénéficier d'une connexion filaire +
rj45_in_out
+ +
+
+
+{% endblock %} + diff --git a/users/urls.py b/users/urls.py index 5515dd29..1e6ffa8c 100644 --- a/users/urls.py +++ b/users/urls.py @@ -109,6 +109,7 @@ urlpatterns = [ url(r'^mass_archive/$', views.mass_archive, name='mass-archive'), url(r'^$', views.index, name='index'), url(r'^index_clubs/$', views.index_clubs, name='index-clubs'), + url(r'^initial_register/$', views.initial_register, name='initial-register'), url(r'^rest/ml/std/$', views.ml_std_list, name='ml-std-list'), diff --git a/users/views.py b/users/views.py index af311ceb..86cfa767 100644 --- a/users/views.py +++ b/users/views.py @@ -105,7 +105,8 @@ from .forms import ( PassForm, ResetPasswordForm, ClubAdminandMembersForm, - GroupForm + GroupForm, + InitialRegisterForm ) @@ -1081,6 +1082,28 @@ def process_passwd(request, req): request ) +@login_required +def initial_register(request): + u_form = InitialRegisterForm(request.POST or None, user=request.user, switch_ip=request.GET.get('switch_ip', None), switch_port=request.GET.get('switch_port', None), client_mac=request.GET.get('client_mac', None)) + if not u_form.fields: + messages.error(request, _("Incorrect url, or already registered device")) + return redirect(reverse( + 'users:profil', + kwargs={'userid': str(request.user.id)} + )) + if u_form.is_valid(): + messages.success(request, _("Successfull register ! Please plug off and plug again your cable to get internet access")) + return form( + {}, + 'users/plugin_out.html', + request + ) + return form( + {'userform': u_form, 'action_name': _("Register device or room")}, + 'users/user.html', + request + ) + class JSONResponse(HttpResponse): """ Framework Rest """ From 1de72714d0ba6cc546222f0a18403d41319652d2 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Tue, 28 Aug 2018 23:17:45 +0200 Subject: [PATCH 003/252] translation for commit f355175b + typos --- re2o/locale/fr/LC_MESSAGES/django.mo | Bin 5657 -> 5658 bytes re2o/locale/fr/LC_MESSAGES/django.po | 2 +- users/forms.py | 4 +- users/locale/fr/LC_MESSAGES/django.mo | Bin 25505 -> 26688 bytes users/locale/fr/LC_MESSAGES/django.po | 260 +++++++++++++++----------- users/templates/users/plugin_out.html | 3 +- users/views.py | 6 +- 7 files changed, 160 insertions(+), 115 deletions(-) diff --git a/re2o/locale/fr/LC_MESSAGES/django.mo b/re2o/locale/fr/LC_MESSAGES/django.mo index 72cde11123bdec09725205a6db29b466a77770f5..e51e7ad2c405c39dd7c69a5d303d5cdd7f5053c7 100644 GIT binary patch delta 121 zcmbQKGfQVf2~(;h0|UcpVFrdMApI0bD+6f<5e5b&Ae{oFC4h80kd_0|3xKpfklqia t-venQAYWdTfx!?+2LWjizXeF^0_p8Q+5|{H-F%bjs{mu!=5xZ{OaL=;67T>3 delta 119 zcmbQGGgD_n2~(;B0|UcpVFrdMApHbLD+6hJ5e5b&Ae{`PLGo=tS`J9h2h#dLdLNX2 r2c(UFd^u4D216hn2&6&$W+1H#q_+WS6CnL$^G&9&0-MhZdouw540{r7 diff --git a/re2o/locale/fr/LC_MESSAGES/django.po b/re2o/locale/fr/LC_MESSAGES/django.po index f54fdcc1..58886a6b 100644 --- a/re2o/locale/fr/LC_MESSAGES/django.po +++ b/re2o/locale/fr/LC_MESSAGES/django.po @@ -232,7 +232,7 @@ msgstr "Accéder à mon profil" #: templates/re2o/index.html:79 msgid "Services of the organisation" -msgstr "Serices de l'association" +msgstr "Services de l'association" #: templates/re2o/index.html:93 msgid "Go there" diff --git a/users/forms.py b/users/forms.py index 982ad58f..a6ea70b9 100644 --- a/users/forms.py +++ b/users/forms.py @@ -688,11 +688,11 @@ class InitialRegisterForm(forms.Form): self.nas_type = Nas.objects.filter(nas_type__interface__ipv4__ipv4=switch_ip).first() super(InitialRegisterForm, self).__init__(*args, **kwargs) if hasattr(self, 'new_room'): - self.fields['register_room'].label = _("New connection from Room %s. Is that yours ? If it is the case, type Ok" % self.new_room) + self.fields['register_room'].label = _("New connection from room %s. Is it yours? If that is the case, type OK." % self.new_room) else: self.fields.pop('register_room') if hasattr(self, 'mac_address'): - self.fields['register_machine'].label = _("New connection from new device. Register It ? Say Yes to get internet connection from it (mac_address : %s)" % self.mac_address) + self.fields['register_machine'].label = _("New connection from new device. Register it? Say Yes to get Internet access from it (MAC Address : %s)." % self.mac_address) else: self.fields.pop('register_machine') diff --git a/users/locale/fr/LC_MESSAGES/django.mo b/users/locale/fr/LC_MESSAGES/django.mo index 059a73fcf5ef3e75001f0cd01be085abfedcdafa..fada8ed8190f9564253ed4774f80b1f6a9ace32b 100644 GIT binary patch delta 7977 zcmbu?dwi7DoyYN$kPxmR7w#ZDfm{fX;U;%TfDmbvJBXr-Fqu3dgUKYFnS_hVD23Xh zvaXj_w^%`zLQtwS3e{4j1W>CjUbQbwy2w1zH@AI6bzV@}-Kf2G$-@MN` z^E~JBJLj3;_UDrhy^@r8CoAQC!!_i)VGrDo1^6-!z)x*^c0XgfQ!m7BSd0vnFmown&~Pmd#xU}XxeI&YZd6Bya2&pi z6R{_=&BOVahK<-B*W+cl2^qlbKuv5f_Q4j^0^Y_hjBh@q(3yrWP%}&6X|1d~4#6SV z0T-Y;ybfn#C2HU%Y=`?W1)suVd zu-iamdgEB6$;?G%rWUm|n~!TQ}HZng6Gg%FedaxisN_K3ALg@ zsJ$9$>m`^^eHLnh5mX8{B8xNkpxU26wI4%G_&2BtoJCFSE7bSttWI0iKZpElrh{qF zjK-r+-Kd1dL8%M`cW*UegfxX-#lZ6;f<)3ejhdA zU8qbyftpC-AO+3jc^rzbqEh=MY7cv{@#)hx{YdnMp427M3s$g#Znsu{{Pc4XaTztVex+6Q|dI!|RdZ6~)!45bc z_53tchL)f*|b=Dm?f%?ms&-f;lysLxZsDa0#QaKfss%7Y90JVZWsDbv``tzvN z{u*_<-$R|53#bfr<{;>~Ow>YpTQ9?e_IQxJVKQn0Gi?1z)ZQ;Z4H!hFZZ)doP1p(V zKn?IcTYt!YzZ-S`kFgRDA_w2(4EN7m*>Li&0q4=6LvjtifYqoKjVkg}I1}}LFU1n9 zwe5THkJJyN4(DT}Ntrv2Gw>r^fTKtFukl87sP91CcVtAuPucHj$fe;+YtBf2rdJ@_ zWLBXDxDWN<0o3opNz@_x9QD>@j56jMI1H7sIBH8aqt41Bs4ackdNM&lKMi)wx9#5jSvfCJcB12FUE5${)47FwZP?rXTt)n7hpp%YR4F2RM2 zZ&p%Z`^+=QT+A8Njs3^@hh!q^kdCi8!i&x-wtYNbmnf3NvZ=3F&Pye&8P(& z#Jlmg*bY}QD`hfbjbSR|n>7@=;d)eRwqQ0sjNP#r^?JR4dRva$`bk@V2fNUI8oS~- z)D|R7@t;e>9@NvZH|8RLAk9=v=u|JKa6=M*WUxQ=_on&-e}#RiXBYc>89?p*71#%> zkT=!bic0Zb)ctSZ06d2}Gg&46R_3A>8bJLH6qk^Hbyz`zUcU{f*JBq>!=uO?OnWLC zXeKHH-$bo&Ee^y4_QHp;A09w0i*r@%-`lbjG`9!0BYj<6BGthIDyK* zMa;p0GyQ*ZO-DUgjY{bj9E5wZC%%GO`5#cJ{VVFMbSv`@TTfJbKTO48sIxE%J7Z!N z1$DFtwc=H%_c)H~cq^vklcrsdKJE(yl z@=cf~3QFNqsMM#-@=s}3)E?%e1}sJGSrC=Fo2^?>dwvj=nKw{}?h@*`uKXTr;9;n@ zYZ_|73())be>DZ}H4Uf%e{Ovf)!}*6jQf`Rsmw=pI1ZJOt1u61Q4_lt$73_5;fL09 zs0Ca?)@pikP`Yyd%rXkOcq1y6ccWIY2bI!;s8qjVzdw!FQ8!od7Za{W9lmDNUcZMO z@nh7AFQNMBGTYZdy-k;6LWeI%K`GpXn!t9{3Vw#l$T?I88FP#ofw`!aF2)WRN1c&d zP%FF>bq02!gU_KBbP7k|C#VVL&gK2@L?OTdP{Tyz*VmL{JG>dy(XH4XAHcitVO)Ym z^Zc#Yh|1uDsFXj8n(#4H2HwPU{Lp&Qws)LQ{`E!Q`F@HEF_n4=cEvK(#1^4`I+tM= zY(!<|Tc|Uz4K?6l9E&G#2zFWE|9fC8YUS&(Gd_V@(7^-+y(TTF!}dEIiK+Z)(+%TL zDV>U%$hDY-6_}3=w!Rg$kjGKaJ&Rh%QB+1=LXGn}>b_5~8zzz#`F~zBQG41SwX!Lw zQ@#|lFoHTGw_!Fugz9J?YM?`?l^w%+d<{oo>0*Bi8cxNL*i;b z1KUt3Z9%>=@1qXoByD&SZK&7nYL0#(-h>=*vlFk!k5Ok~&b5AqqNw{HLE%_Q&1m;885b)2PFhx7`1i(Qwq;a6LL$js5Vu zsIA$Fz41759LyPCgs9k-)i&;7RjMI1=|Z5)JuK|SYG`;NpU>bkxl5>vb)>7uofvQG5B zs*U<}aDw=R7(whMqJ&;cUAf%Tp7^U@H9tU2w%pb^pXMkrn9yXBxYr?ceT&Fve6xna zlZ0NqG(y*5AMY^PqWAxW%~ZPD4%D7Z93);Q>IkL&L1HPigbtQc{hx%c2Z(Xpvl-tZv~3>~#|WJrGHt#`bl@Ic z-}Ui6GiaMd>5q)>UB~%su;qL33Su8o#Enbv72;RKPY7L`e9V8~&u#fG{Lq%aWBn3! z;(tu&AnF=qCzOJT8X7uLNF$0VFV`Jh{EB+N1zEJeNO=aKliQ!ToVMYFuDgA_&k20$ zJ>TZl__5-i(UjNOx_*TIMEo0}*S3F>^3OGj7*5Ppg{zm3_oI|fC)249#rN<4v4faI zUDrwCr^IZc2W@X7hu%C##E5qGzTUWs`o9x;WrKvb{}Dz4k#>e@(2m?c!Ej-j2!kz5&)Aw0)Dfg*Zd#dYYI?jN+c(;Io87JVki> z7qAbvQ2#)UT;qJa&niCug=kM?6aPiDUZt%CJWo7E-2b(Mo9CwDynO^EludIx!agvi4D-4*q^!Y!>iPkY#UTk>4DUZ>=v$n1w z8Y^+itDJasFz$pIsM>Wx!I(STiLb49oq1OUnx_=3OwM$pc7j@+y1932;js#D7F7*3 zcAe3nmXzbnuW{+ZsSL;L1e{=`l6zWf8rCUeC~qyHU`37lf2=UjynN`>>4~L!pf(t) z4o6(CFRur0HLFRk6KiOlNzK=D9{5LRQsGA2D)QrPPSD9*9o7#1Et`SnUK1;m(k3{g z$4nYIzInr>chig5dM6yQ2Z2M--~{XIgHbnJ<5adZt!mlkxDo$2L|dAgSCk(~PSmh& zuhTU;36*Yr13SC^hUKDa2S{qxQ zjMK;&4LhL%Hx_sFcreDv3D&#oyrVN<_M6F5qbuF0S?JP>O1djnS5xVlvetCa$fDaO zNah;YW`ES?uJa}&CH{76ts99uB(NbC3p+W^61O2t7S}1o713ZM#F=tfZPab6HP&gG zp_WH<%GwUy-_2XVENp3tHPp5=u_-a9w0Y6|FESHLypCE=A%obSZFcIISVh>4I4w?)>K^8?8QLi8HWUHzpM0P`6}YOYDbjaVVzXWbBBw zw*571LwzTP2wlLM+30T!`7|!vZ{pJZchHRV?G1A_|c>1~t?BQ4iLjR=5VEa3Atxj`K^I35avH zrUQ}$(;c;dVWLKK~3yDYQSJlvhGhp?ezfch83uVEJmHB7rhiTleL(K+id+3 zY6}9AoB`USR+MfnK)sGbZG9~Er+yy}!_BCE{W(CIXlqo4V^I@GMNPn)Lm`bq0V<_; zqV{e!s)J?7qRe{KfcsGsJB<983;fbbqd6cNs5j~i-GG|#5Y*uwjXEp$p)yvBnR@@1 zQwXGCAL_w+)C>g37*?Jx7!2_thJ%n1}1yl!DQ5lI$buto<{Fq$pcIOR*;#Q<)C#7e2D;bQXQNX26e@);pfa(^e!dm8fVZtXQCqp&etrZs z@Nru|hhFXRB?=lSfPRC$igx>SeS{!u?qEi?m`d#fV$70 zgQNF65tA^_IsrA&8f498Z6^8G>HeGsJ@_lCLwA;QsCr<-7Y*J-dnGDUKGXnvQD@^Q zY6~x0-Pz82-yQX~3`gBJ74`fK>mo0OA{y4BIy{AXz}1x#j&9T*4nhA%FM5*fqL_8Lsw=PhT=?A>gQtwu0)*`ua8123U8t^@DY-Ia~gxuo#XsHk3$V~ zBWj{07>QF*-*D4W9WTK$T#f98xq|$dlR>4gE2Se}yQ8vDSE0hB{$5rlT^FkFBu;+h7IiZF&TQ7~jmW z4K-?@UW@udT8!Ge6{wCkp&s0dZSif4!q1SuU*-(zFo*WxPq2&qM@@J>Y16>#QDy5gcA)m~Gt^2Cp;2kzRm;X))lC;au$=()6ZGqAdI6v z8I_4@R0dwfc-)7b@F&!BZr)W*Jl{(}do~(1^CwU%UxG^Q2GpLvgF0+=wtX*Z1qV@Q z;RuG{B~(AI{?3Y{Fok*os^1|Ph7(Z}^Hx#lKw%N8qt{WX-GfT?QPhK%P%{o4;B=gh zI#ju+fs3spQ5l?sO8sWkA>EGJ!g|zr=aDV*n(%>6>e8%3Peh+>RRf zAnNrxhg$J9)LY{o#FrE%q6WO%Iv3U7E2s&7h~aww>nW(iW2lr|!DNh~7wu_3?1>c^ zgiEa}P={_U@`$NJouLr^P$XeADwBn%1&l&vv=Wu+C-gbvo5d7v$Bj4=n-6yOz5;b> zt57R_9MwUs^(EA6v;`CKC@OOS9B~aCkD7QMDiaT(o?n1jxC$HI|9T3+G+aa-j^9x$ zYgz2P|xt z-iDfC1!~0)qb4-Ry2Q4xvh}T~RMueteuLVA?@<#whdO+hu_d-DaWc^nwbgkgZef)_YAUPj{kW8tQ@P(StitXX6JrU|7i*uIFxr!9p<109D|xzwQYaRw%4OpdKLBBy6Ii1 zu0n0e)7Tp~pw7k#)IwU^=G3!LNh-q-#y77}xB*{BeZyVE{uoK`p;(UUcrr#~HEQpc zqxOCsdT3f*%ose^RRG?)8S*N!?+E@ z@oVcz^rLs0GbJUU{<~b^jG?kJ-#lnJ7kOcGN_#^JjG` z4SFr^#t5v!RyfPL7+X_cjrwAF3-ub-ppSSOu%to z3VLv+bs@T_>l#4(r=jG0C(x()Cy{R3?!-?C9j2~4w9K|^f}4na#8RS!_zR({8A0|N zu0)>k=Ge-U)*ko=Vh(Yfc$D~+XuKYwaDa&5VQqn~=Ln9B$*?mor~EAOM`AXiEo{7W zz;#`6@S0i*2|PH^X)rA)&!_x8@d}Y+J58d@ZkdHdOWGEou6W8nA#a%pq^xawhzOzV z!D^!M+D@UyR&KzyE_(co!goY(;zL4LvO~k+(LriPXW!!m;@?E$wT;66h;NC*wy`z$ z>U!P5ykKoa`>$&T(Mc=Pi5yEbUXyL%JU&I-K|Dr;(eY`FCE8I=wgXW$^~6_%-uEcl zJ2&}kDs9gb9}r&>I=HKe4TQ#Txb!~i+b@s^CO#q75xPDnG8#(!s|90-?hMeJ*h0CA z;M_J`(N?~NuV1%Oay6MyJL;#1osHwad;L~k7klF~P1;nvw@JMlFeiY^sdR@B`{@nXwQ1 zuI|Jt;yzWlZgFUMm%p)PeXlIC<&!vt_^4BCFSMBWkT0YgpU|Q z6cCNqT@>yn-mne7ThHLz#KXip#7o3k;vAtXnlZLEl*oSym1|Ts6XC>FBAe($yRIJ{ zOh@V?ZFwWs5xZ@DIz|$IBHkndxc6ghg}pG5m`Qw1G+rYpyvq1y8u0)zoM^m$rr^iJ zCv3w%@E)SSt+(N`6w3D#$B3cCA)+nO^x8#bSd)eaDQEL+9HFc8cz*RHQfYV%+YtMS z1mbT*G2zk8zOn5iLVQb;^Zk4^sT2JcT}yk h(c)cxz9&oT{T7WYYv)^5mh1BM9}yVoJ3Y1B^?!zp%SZqK diff --git a/users/locale/fr/LC_MESSAGES/django.po b/users/locale/fr/LC_MESSAGES/django.po index d3ff0f4f..2dd96142 100644 --- a/users/locale/fr/LC_MESSAGES/django.po +++ b/users/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-08-23 15:36+0200\n" +"POT-Creation-Date: 2018-08-28 23:07+0200\n" "PO-Revision-Date: 2018-06-27 23:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -35,181 +35,197 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." -#: forms.py:70 +#: forms.py:72 msgid "Current password" msgstr "Mot de passe actuel" -#: forms.py:75 forms.py:447 +#: forms.py:77 forms.py:449 msgid "New password" msgstr "Nouveau mot de passe" -#: forms.py:81 +#: forms.py:83 msgid "New password confirmation" msgstr "Confirmation du nouveau mot de passe" -#: forms.py:98 +#: forms.py:100 msgid "The new passwords don't match." msgstr "Les nouveaux mots de passe ne correspondent pas." -#: forms.py:107 +#: forms.py:109 msgid "The current password is incorrect." msgstr "Le mot de passe actuel est incorrect." -#: forms.py:125 forms.py:178 models.py:1550 +#: forms.py:127 forms.py:180 models.py:1550 msgid "Password" msgstr "Mot de passe" -#: forms.py:131 forms.py:184 +#: forms.py:133 forms.py:186 msgid "Password confirmation" msgstr "Confirmation du mot de passe" -#: forms.py:136 forms.py:227 +#: forms.py:138 forms.py:229 msgid "Is admin" msgstr "Est admin" -#: forms.py:146 +#: forms.py:148 msgid "You can't use an internal address as your external address." msgstr "" "Vous ne pouvez pas utiliser une adresse interne pour votre adresse externe." -#: forms.py:159 forms.py:208 +#: forms.py:161 forms.py:210 msgid "The passwords don't match." msgstr "Les mots de passe ne correspondent pas." -#: forms.py:236 +#: forms.py:238 #, python-format msgid "User is admin: %s" msgstr "L'utilisateur est admin : %s" -#: forms.py:284 templates/users/aff_clubs.html:38 +#: forms.py:286 templates/users/aff_clubs.html:38 #: templates/users/aff_listright.html:63 templates/users/aff_listright.html:168 #: templates/users/aff_users.html:39 templates/users/profil.html:169 #: templates/users/profil.html:283 templates/users/profil.html:302 msgid "Username" msgstr "Pseudo" -#: forms.py:299 +#: forms.py:301 msgid "Impossible to archive users whose end access date is in the future." msgstr "" "Impossible d'archiver des utilisateurs dont la date de fin de connexion est " "dans le futur." -#: forms.py:311 templates/users/profil.html:282 templates/users/profil.html:301 +#: forms.py:313 templates/users/profil.html:282 templates/users/profil.html:301 msgid "First name" msgstr "Prénom" -#: forms.py:312 templates/users/aff_users.html:37 +#: forms.py:314 templates/users/aff_users.html:37 #: templates/users/profil.html:165 templates/users/profil.html:281 #: templates/users/profil.html:300 msgid "Surname" msgstr "Nom" -#: forms.py:313 models.py:1551 templates/users/aff_emailaddress.html:36 +#: forms.py:315 models.py:1551 templates/users/aff_emailaddress.html:36 #: templates/users/profil.html:171 msgid "Email address" msgstr "Adresse mail" -#: forms.py:314 forms.py:385 forms.py:516 templates/users/aff_schools.html:37 +#: forms.py:316 forms.py:387 forms.py:518 templates/users/aff_schools.html:37 #: templates/users/profil.html:181 msgid "School" msgstr "Établissement" -#: forms.py:315 forms.py:386 models.py:1204 +#: forms.py:317 forms.py:388 models.py:1204 #: templates/users/aff_serviceusers.html:34 templates/users/profil.html:183 msgid "Comment" msgstr "Commentaire" -#: forms.py:316 forms.py:387 templates/users/aff_clubs.html:40 +#: forms.py:318 forms.py:389 templates/users/aff_clubs.html:40 #: templates/users/aff_users.html:41 templates/users/profil.html:175 msgid "Room" msgstr "Chambre" -#: forms.py:317 forms.py:388 +#: forms.py:319 forms.py:390 msgid "No room" msgstr "Pas de chambre" -#: forms.py:318 forms.py:389 +#: forms.py:320 forms.py:391 msgid "Select a school" msgstr "Sélectionnez un établissement" -#: forms.py:319 +#: forms.py:321 msgid "Leave empty if you don't have any GPG key." msgstr "Laissez vide si vous n'avez pas de clé GPG." -#: forms.py:321 +#: forms.py:323 msgid "Default shell" msgstr "Interface système par défaut" -#: forms.py:328 forms.py:656 +#: forms.py:330 forms.py:658 msgid "You can't use a {} address." msgstr "Vous ne pouvez pas utiliser une adresse {}." -#: forms.py:353 forms.py:411 +#: forms.py:355 forms.py:413 msgid "A valid telephone number is required." msgstr "Un numéro de téléphone valide est requis." -#: forms.py:364 +#: forms.py:366 msgid "Force the move?" msgstr "Forcer le déménagement ?" -#: forms.py:384 templates/users/aff_clubs.html:36 +#: forms.py:386 templates/users/aff_clubs.html:36 #: templates/users/aff_serviceusers.html:32 msgid "Name" msgstr "Nom" -#: forms.py:390 +#: forms.py:392 msgid "Use a mailing list" msgstr "Utiliser une liste de diffusion" -#: forms.py:504 templates/users/aff_listright.html:38 +#: forms.py:506 templates/users/aff_listright.html:38 msgid "Superuser" msgstr "Superutilisateur" -#: forms.py:528 +#: forms.py:530 msgid "Shell name" msgstr "Nom de l'interface système" -#: forms.py:547 +#: forms.py:549 msgid "Name of the group of rights" msgstr "Nom du groupe de droits" -#: forms.py:558 +#: forms.py:560 msgid "GID. Warning: this field must not be edited after creation." msgstr "GID. Attention : ce champ ne doit pas être modifié après création." -#: forms.py:566 +#: forms.py:568 msgid "Current groups of rights" msgstr "Groupes de droits actuels" -#: forms.py:583 +#: forms.py:585 msgid "Current schools" msgstr "Établissements actuels" -#: forms.py:601 forms.py:615 templates/users/aff_bans.html:41 +#: forms.py:603 forms.py:617 templates/users/aff_bans.html:41 #: templates/users/aff_whitelists.html:41 msgid "End date" msgstr "Date de fin" -#: forms.py:629 models.py:1748 +#: forms.py:631 models.py:1748 msgid "Local part of the email address" msgstr "Partie locale de l'adresse mail" -#: forms.py:630 +#: forms.py:632 msgid "Can't contain @" msgstr "Ne peut pas contenir @" -#: forms.py:645 +#: forms.py:647 msgid "Main email address" msgstr "Adresse mail principale" -#: forms.py:647 +#: forms.py:649 msgid "Redirect local emails" msgstr "Rediriger les mails locaux" -#: forms.py:649 +#: forms.py:651 msgid "Use local emails" msgstr "Utiliser les mails locaux" +#: forms.py:691 +#, python-format +msgid "New connection from room %s. Is it yours? If that is the case, type OK." +msgstr "" +"Nouvelle connexion depuis la chambre %s. Est-ce la vôtre ? Si c'est le cas, " +"tapez OK." + +#: forms.py:695 +#, python-format +msgid "" +"New connection from new device. Register it? Say Yes to get Internet access " +"from it (MAC Address : %s)." +msgstr "" +"Nouvelle connexion depuis un nouvel appareil. L'enregistrer ? Dites Oui pour " +"avoir accès à Internet depuis cet appareil (adresse MAC : %s)." + #: models.py:105 #, python-format msgid "The username '%(label)s' contains forbidden characters." @@ -722,7 +738,8 @@ msgstr "Confirmer" #: templates/users/index_schools.html:30 #: templates/users/index_serviceusers.html:30 #: templates/users/index_shell.html:30 templates/users/index_whitelist.html:29 -#: templates/users/sidebar.html:52 templates/users/user.html:30 +#: templates/users/plugin_out.html:31 templates/users/sidebar.html:52 +#: templates/users/user.html:30 msgid "Users" msgstr "Utilisateurs" @@ -816,6 +833,15 @@ msgid "The following users will be archived (%(to_archive_list|length)s):" msgstr "" "Les utilisateus suivants vont être archivés (%(to_archive_list|length)s :" +#: templates/users/plugin_out.html:35 +msgid "" +"Your machine and your room were successfully registered. Please disconnect " +"and reconnect your Ethernet cable to benefit from a wired connection." +msgstr "" +"Votre machine et votre chambre ont bien été enregistrées. Veuillez" +" débrancher et rebrancher votre câble Ethernet pour bénéficier d'une" +" connexion filaire." + #: templates/users/profil.html:37 #, python-format msgid "Welcome %(name)s %(surname)s" @@ -881,7 +907,7 @@ msgstr " Informations détaillées" msgid "Edit" msgstr "Modifier" -#: templates/users/profil.html:133 views.py:282 views.py:1079 +#: templates/users/profil.html:133 views.py:283 views.py:1080 msgid "Change the password" msgstr "Changer le mot de passe" @@ -889,7 +915,7 @@ msgstr "Changer le mot de passe" msgid "Change the state" msgstr "Changer l'état" -#: templates/users/profil.html:144 views.py:260 +#: templates/users/profil.html:144 views.py:261 msgid "Edit the groups" msgstr "Modifier les groupes" @@ -956,7 +982,7 @@ msgstr "Solde" #: templates/users/profil.html:241 msgid "Refill" -msgstr "Rechager" +msgstr "Recharger" #: templates/users/profil.html:246 msgid "GPG fingerprint" @@ -1002,7 +1028,7 @@ msgstr "Modifier le solde" msgid "No invoice" msgstr "Pas de facture" -#: templates/users/profil.html:385 views.py:384 +#: templates/users/profil.html:385 views.py:385 msgid "Add a ban" msgstr "Ajouter un bannissement" @@ -1058,7 +1084,7 @@ msgstr " Ajouter une adresse mail" msgid "Create a club or organisation" msgstr "Créer un club ou une association" -#: templates/users/sidebar.html:39 views.py:134 +#: templates/users/sidebar.html:39 views.py:135 msgid "Create a user" msgstr "Créer un utilisateur" @@ -1095,178 +1121,178 @@ msgstr "Conditions Générales d'Utilisation" msgid "Summary of the General Terms of Use" msgstr "Résumé des Conditions Générales d'Utilisation" -#: views.py:122 +#: views.py:123 #, python-format msgid "The user %s was created, an email to set the password was sent." msgstr "" "L'utilisateur %s a été créé, un mail pour initialiser le mot de passe a été " "envoyé." -#: views.py:151 +#: views.py:152 #, python-format msgid "The club %s was created, an email to set the password was sent." msgstr "" "Le club %s a été créé, un mail pour initialiser le mot de passe a été envoyé." -#: views.py:158 +#: views.py:159 msgid "Create a club" msgstr "Créer un club" -#: views.py:176 +#: views.py:177 msgid "The club was edited." msgstr "Le club a été modifié." -#: views.py:185 +#: views.py:186 msgid "Edit the admins and members" msgstr "Modifier les admins et les membres" -#: views.py:213 +#: views.py:214 msgid "The user was edited." msgstr "L'utilisateur a été modifié." -#: views.py:219 +#: views.py:220 msgid "Edit the user" msgstr "Modifier l'utilisateur" -#: views.py:233 +#: views.py:234 msgid "The state was edited." msgstr "L'état a été modifié." -#: views.py:239 +#: views.py:240 msgid "Edit the state" msgstr "Modifier l'état" -#: views.py:254 +#: views.py:255 msgid "The groups were edited." msgstr "Les groupes ont été modifiés." -#: views.py:276 views.py:1076 +#: views.py:277 views.py:1077 msgid "The password was changed." msgstr "Le mot de passe a été changé." -#: views.py:294 +#: views.py:295 #, python-format msgid "%s was removed from the group." msgstr "%s a été retiré du groupe." -#: views.py:304 +#: views.py:305 #, python-format msgid "%s is no longer superuser." msgstr "%s n'est plus superutilisateur." -#: views.py:317 +#: views.py:318 msgid "The service user was created." msgstr "L'utilisateur service a été créé." -#: views.py:321 +#: views.py:322 msgid "Create a service user" msgstr "Créer un utilisateur service" -#: views.py:338 +#: views.py:339 msgid "The service user was edited." msgstr "L'utilisateur service a été modifié." -#: views.py:341 +#: views.py:342 msgid "Edit a service user" msgstr "Modifier un utilisateur service" -#: views.py:353 +#: views.py:354 msgid "The service user was deleted." msgstr "L'utilisateur service a été supprimé." -#: views.py:373 +#: views.py:374 msgid "The ban was added." msgstr "Le bannissement a été ajouté." -#: views.py:381 +#: views.py:382 msgid "Warning: this user already has an active ban." msgstr "Attention : cet utilisateur a déjà un bannissement actif." -#: views.py:400 +#: views.py:401 msgid "The ban was edited." msgstr "Le bannissement a été modifié." -#: views.py:403 +#: views.py:404 msgid "Edit a ban" msgstr "Modifier un bannissement" -#: views.py:415 +#: views.py:416 msgid "The ban was deleted." msgstr "Le bannissement a été supprimé." -#: views.py:442 +#: views.py:443 msgid "The whitelist was added." msgstr "L'accès gracieux a été ajouté." -#: views.py:450 +#: views.py:451 msgid "Warning: this user already has an active whitelist." msgstr "Attention : cet utilisateur a déjà un accès gracieux actif." -#: views.py:453 +#: views.py:454 msgid "Add a whitelist" msgstr "Ajouter un accès gracieux" -#: views.py:473 +#: views.py:474 msgid "The whitelist was edited." msgstr "L'accès gracieux a été ajouté." -#: views.py:476 +#: views.py:477 msgid "Edit a whitelist" msgstr "Modifier un accès gracieux" -#: views.py:488 +#: views.py:489 msgid "The whitelist was deleted." msgstr "L'accès gracieux a été supprimé." -#: views.py:512 +#: views.py:513 msgid "The local email account was created." msgstr "Le compte mail local a été créé." -#: views.py:520 +#: views.py:521 msgid "Add a local email account" msgstr "Ajouter un compte mail local" -#: views.py:537 +#: views.py:538 msgid "The local email account was edited." msgstr "Le compte mail local a été modifié." -#: views.py:545 +#: views.py:546 msgid "Edit a local email account" msgstr "Modifier un compte mail local" -#: views.py:557 +#: views.py:558 msgid "The local email account was deleted." msgstr "Le compte mail local a été supprimé." -#: views.py:581 +#: views.py:582 msgid "The email settings were edited." msgstr "Les paramètres mail ont été modifiés." -#: views.py:590 +#: views.py:591 msgid "Edit the email settings" msgstr "Modifier les paramètres mail" -#: views.py:604 +#: views.py:605 msgid "The school was added." msgstr "L'établissement a été ajouté." -#: views.py:607 +#: views.py:608 msgid "Add a school" msgstr "Ajouter un établissement" -#: views.py:622 +#: views.py:623 msgid "The school was edited." msgstr "L'établissement a été modifié." -#: views.py:625 +#: views.py:626 msgid "Edit a school" msgstr "Modifier un établissement" -#: views.py:644 +#: views.py:645 msgid "The school was deleted." msgstr "L'établissement a été supprimé." -#: views.py:648 +#: views.py:649 #, python-format msgid "" "The school %s is assigned to at least one user, impossible to delete it." @@ -1274,51 +1300,51 @@ msgstr "" "L'établissement %s est affecté à au moins un utilisateur, impossible de le " "supprimer." -#: views.py:652 views.py:764 +#: views.py:653 views.py:765 msgid "Delete" msgstr "Supprimer" -#: views.py:665 +#: views.py:666 msgid "The shell was added." msgstr "L'interface système a été ajoutée." -#: views.py:668 +#: views.py:669 msgid "Add a shell" msgstr "Ajouter une interface système" -#: views.py:682 +#: views.py:683 msgid "The shell was edited." msgstr "L'interface système a été modifiée." -#: views.py:685 +#: views.py:686 msgid "Edit a shell" msgstr "Modifier une interface système" -#: views.py:697 +#: views.py:698 msgid "The shell was deleted." msgstr "L'interface système a été supprimée." -#: views.py:714 +#: views.py:715 msgid "The group of rights was added." msgstr "Le groupe de droits a été ajouté." -#: views.py:717 +#: views.py:718 msgid "Add a group of rights" msgstr "Ajouter un groupe de droits" -#: views.py:735 +#: views.py:736 msgid "The group of rights was edited." msgstr "Le groupe de droits a été modifié." -#: views.py:738 +#: views.py:739 msgid "Edit a group of rights" msgstr "Modifier un groupe de droits" -#: views.py:755 +#: views.py:756 msgid "The group of rights was deleted." msgstr "Le groupe de droits a été supprimé." -#: views.py:760 +#: views.py:761 #, python-format msgid "" "The group of rights %s is assigned to at least one user, impossible to " @@ -1327,36 +1353,52 @@ msgstr "" "Le groupe de droits %s est affecté à au moins un utilisateur, impossible de " "le supprimer." -#: views.py:788 +#: views.py:789 msgid "Archiving" msgstr "Archivage" -#: views.py:789 +#: views.py:790 #, python-format msgid "%s users were archived." msgstr "%s utilisateurs ont été archivés." -#: views.py:1038 +#: views.py:1039 msgid "The user doesn't exist." msgstr "L'utilisateur n'existe pas." -#: views.py:1040 views.py:1048 +#: views.py:1041 views.py:1049 msgid "Reset" msgstr "Réinitialiser" -#: views.py:1045 +#: views.py:1046 msgid "An email to reset the password was sent." msgstr "Un mail pour réinitialiser le mot de passe a été envoyé." -#: views.py:1062 +#: views.py:1063 msgid "Error: please contact an admin." msgstr "Erreur : veuillez contacter un admin." -#: views.py:1074 +#: views.py:1075 msgid "Password reset" msgstr "Réinitialisation du mot de passe" -#: views.py:1114 views.py:1138 views.py:1153 +#: views.py:1089 +msgid "Incorrect URL, or already registered device" +msgstr "URL incorrect, ou appareil déjà enregistré" + +#: views.py:1095 +msgid "" +"Successful registration! Please disconnect and reconnect your Ethernet cable " +"to get Internet access." +msgstr "" +"Enregistrement réussi ! Veuillez débrancher et rebrancher votre câble Ethernet" +" pour avoir accès à Internet." + +#: views.py:1104 +msgid "Register device or room" +msgstr "Enregistrer un appareil ou une chambre" + +#: views.py:1139 views.py:1163 views.py:1178 msgid "The mailing list doesn't exist." msgstr "La liste de diffusion n'existe pas." diff --git a/users/templates/users/plugin_out.html b/users/templates/users/plugin_out.html index a6ebf83f..21666310 100644 --- a/users/templates/users/plugin_out.html +++ b/users/templates/users/plugin_out.html @@ -27,11 +27,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load massive_bootstrap_form %} {% load static %} {% load i18n %} + {% block title %}{% trans "Users" %}{% endblock %} {% block content %} -

Votre machine et votre chambre ont bien été enregistrées. Merci de débrancher et rebrancher votre cable RJ45 pour bénéficier d'une connexion filaire

+

{% trans "Your machine and your room were successfully registered. Please disconnect and reconnect your Ethernet cable to benefit from a wired connection." %}

rj45_in_out

diff --git a/users/views.py b/users/views.py index 86cfa767..360e256b 100644 --- a/users/views.py +++ b/users/views.py @@ -1086,13 +1086,15 @@ def process_passwd(request, req): def initial_register(request): u_form = InitialRegisterForm(request.POST or None, user=request.user, switch_ip=request.GET.get('switch_ip', None), switch_port=request.GET.get('switch_port', None), client_mac=request.GET.get('client_mac', None)) if not u_form.fields: - messages.error(request, _("Incorrect url, or already registered device")) + messages.error(request, _("Incorrect URL, or already registered device")) return redirect(reverse( 'users:profil', kwargs={'userid': str(request.user.id)} )) if u_form.is_valid(): - messages.success(request, _("Successfull register ! Please plug off and plug again your cable to get internet access")) + messages.success(request, _("Successful registration! Please" + " disconnect and reconnect your Ethernet" + " cable to get Internet access.")) return form( {}, 'users/plugin_out.html', From fa3aca906f0cc10d4bb6f8e2f2a26edbd5899f8e Mon Sep 17 00:00:00 2001 From: grisel-davy Date: Thu, 30 Aug 2018 17:25:15 +0200 Subject: [PATCH 004/252] =?UTF-8?q?Les=20nouveau=20users=20ne=20sont=20pas?= =?UTF-8?q?=20adh=C3=A9rents=20et=20n'ont=20pas=20de=20home?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/views.py | 2 +- cotisations/models.py | 8 ++++++++ users/migrations/0077_auto_20180824_1750.py | 20 ++++++++++++++++++++ users/models.py | 6 ++++-- users/templates/users/profil.html | 11 +++++++---- 5 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 users/migrations/0077_auto_20180824_1750.py diff --git a/api/views.py b/api/views.py index 0f6301bc..e9528622 100644 --- a/api/views.py +++ b/api/views.py @@ -421,7 +421,7 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet): class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet): """Exposes infos of `users.models.Users` objects to create homes. """ - queryset = users.User.objects.all() + queryset = users.User.objects.filter(state = 0) serializer_class = serializers.HomeCreationSerializer class ClubViewSet(viewsets.ReadOnlyModelViewSet): diff --git a/cotisations/models.py b/cotisations/models.py index fe89aa5d..06791f89 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -243,6 +243,9 @@ def facture_post_save(**kwargs): """ facture = kwargs['instance'] user = facture.user + if facture.valid and facture.vente_set.filter(Q(type_cotisation='All') | Q(type_cotisation='Adhesion')).exists(): + user.state = 0 + user.save() user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) @@ -473,6 +476,11 @@ def vente_post_save(**kwargs): purchase.cotisation.save() user = purchase.facture.user user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) + if purchase.facture.valid and (purchase.type_cotisation == 'All' or purchase.type_cotisation == 'Adhesion'): + user = purchase.facture.user + if user.state == 3: + user.state = 0 + user.save() # TODO : change vente to purchase diff --git a/users/migrations/0077_auto_20180824_1750.py b/users/migrations/0077_auto_20180824_1750.py new file mode 100644 index 00000000..b9510257 --- /dev/null +++ b/users/migrations/0077_auto_20180824_1750.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-08-24 15:50 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0076_auto_20180818_1321'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='state', + field=models.IntegerField(choices=[(0, 'STATE_ACTIVE'), (1, 'STATE_DISABLED'), (2, 'STATE_ARCHIVE'), (3, 'STATE_NOT_YET_ACTIVE')], default=3), + ), + ] diff --git a/users/models.py b/users/models.py index de342031..3e6128a3 100755 --- a/users/models.py +++ b/users/models.py @@ -186,10 +186,12 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, STATE_ACTIVE = 0 STATE_DISABLED = 1 STATE_ARCHIVE = 2 + STATE_NOT_YET_ACTIVE = 3 STATES = ( (0, 'STATE_ACTIVE'), (1, 'STATE_DISABLED'), (2, 'STATE_ARCHIVE'), + (3, 'STATE_NOT_YET_ACTIVE'), ) surname = models.CharField(max_length=255) @@ -231,7 +233,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, blank=True ) pwd_ntlm = models.CharField(max_length=255) - state = models.IntegerField(choices=STATES, default=STATE_ACTIVE) + state = models.IntegerField(choices=STATES, default=STATE_NOT_YET_ACTIVE) registered = models.DateTimeField(auto_now_add=True) telephone = models.CharField(max_length=15, blank=True, null=True) uid_number = models.PositiveIntegerField( @@ -329,7 +331,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, @property def is_active(self): """ Renvoie si l'user est à l'état actif""" - return self.state == self.STATE_ACTIVE + return self.state == self.STATE_ACTIVE or self.state == self.STATE_NOT_YET_ACTIVE @property def is_staff(self): diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index 0f4f8b2c..76b3daeb 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -211,11 +211,14 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% trans "State" %} {% if users.state == 0 %} - {% trans "Active" %} + {% trans "Active" %} {% elif users.state == 1 %} - {% trans "Disabled" %} - {% else %} - {% trans "Archived" %} + {% trans "Disabled" %} + {% elif users.state == 2 %} + {% trans "Archived" %} + {% elif users.state == 3 %} + {% trans "Not yet Member" %} + {% endif %} From 5ab8bb4f0ec2685a421f35e656809d0930f28ea2 Mon Sep 17 00:00:00 2001 From: grisel-davy Date: Thu, 30 Aug 2018 23:08:23 +0200 Subject: [PATCH 005/252] Empeche la syncronisation ldap pour les users_not_yet_member --- users/models.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/users/models.py b/users/models.py index 3e6128a3..d73d5b98 100755 --- a/users/models.py +++ b/users/models.py @@ -563,10 +563,11 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, try: user_ldap = LdapUser.objects.get(uidNumber=self.uid_number) except LdapUser.DoesNotExist: - user_ldap = LdapUser(uidNumber=self.uid_number) - base = True - access_refresh = True - mac_refresh = True + if self.state != 3: + user_ldap = LdapUser(uidNumber=self.uid_number) + base = True + access_refresh = True + mac_refresh = True if base: user_ldap.name = self.pseudo user_ldap.sn = self.pseudo From 0ffdde5a6a5af991c5e67aa93fce68c0e0663628 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Fri, 31 Aug 2018 13:26:54 +0200 Subject: [PATCH 006/252] Cree une fonction pour set active les utilisateurs cotisant --- api/views.py | 3 ++- cotisations/models.py | 14 ++++---------- users/models.py | 8 ++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/api/views.py b/api/views.py index e9528622..d117057a 100644 --- a/api/views.py +++ b/api/views.py @@ -29,6 +29,7 @@ the response (JSON or other), the CSRF exempting, ... import datetime from django.conf import settings +from django.db.models import Q from rest_framework.authtoken.views import ObtainAuthToken from rest_framework.authtoken.models import Token from rest_framework.response import Response @@ -421,7 +422,7 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet): class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet): """Exposes infos of `users.models.Users` objects to create homes. """ - queryset = users.User.objects.filter(state = 0) + queryset = users.User.objects.exclude(Q(state=User.STATE_DISABLED) | Q(state=User.STATE_NOT_YET_ACTIVE)) serializer_class = serializers.HomeCreationSerializer class ClubViewSet(viewsets.ReadOnlyModelViewSet): diff --git a/cotisations/models.py b/cotisations/models.py index 06791f89..8734c17c 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -243,10 +243,8 @@ def facture_post_save(**kwargs): """ facture = kwargs['instance'] user = facture.user - if facture.valid and facture.vente_set.filter(Q(type_cotisation='All') | Q(type_cotisation='Adhesion')).exists(): - user.state = 0 - user.save() - user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) + user.set_active() + user.ldap_sync(base=True, access_refresh=True, mac_refresh=False) @receiver(post_delete, sender=Facture) @@ -475,12 +473,8 @@ def vente_post_save(**kwargs): purchase.create_cotis() purchase.cotisation.save() user = purchase.facture.user - user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) - if purchase.facture.valid and (purchase.type_cotisation == 'All' or purchase.type_cotisation == 'Adhesion'): - user = purchase.facture.user - if user.state == 3: - user.state = 0 - user.save() + user.set_active() + user.ldap_sync(base=True, access_refresh=True, mac_refresh=False) # TODO : change vente to purchase diff --git a/users/models.py b/users/models.py index d73d5b98..212754e2 100755 --- a/users/models.py +++ b/users/models.py @@ -333,6 +333,14 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, """ Renvoie si l'user est à l'état actif""" return self.state == self.STATE_ACTIVE or self.state == self.STATE_NOT_YET_ACTIVE + def set_active(self): + """Enable this user if he subscribed successfully one time before + Active l'utilisateur définitivement si il a adhéré au moins une fois""" + if self.state == self.STATE_NOT_YET_ACTIVE: + if self.facture_set.filter(valid=True).filter(Q(vente__type_cotisation='All') | Q(vente__type_cotisation='Adhesion')).exists(): + self.state = self.STATE_ACTIVE + self.save() + @property def is_staff(self): """ Fonction de base django, renvoie si l'user est admin""" From 48773668d1e3d35b8b220e7704993adb95ee0524 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Fri, 31 Aug 2018 13:35:33 +0200 Subject: [PATCH 007/252] No harcoded var --- users/models.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/users/models.py b/users/models.py index 212754e2..9c4f5f4e 100755 --- a/users/models.py +++ b/users/models.py @@ -571,11 +571,13 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, try: user_ldap = LdapUser.objects.get(uidNumber=self.uid_number) except LdapUser.DoesNotExist: - if self.state != 3: - user_ldap = LdapUser(uidNumber=self.uid_number) - base = True - access_refresh = True - mac_refresh = True + # Freshly created users are NOT synced in ldap base + if self.state == self.STATE_NOT_YET_ACTIVE: + return + user_ldap = LdapUser(uidNumber=self.uid_number) + base = True + access_refresh = True + mac_refresh = True if base: user_ldap.name = self.pseudo user_ldap.sn = self.pseudo From ea78da87e0cb6021a75e2f2908a0f5309ce0b0be Mon Sep 17 00:00:00 2001 From: chirac Date: Fri, 31 Aug 2018 13:37:08 +0200 Subject: [PATCH 008/252] Que en anglais docstring models.py --- users/models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/users/models.py b/users/models.py index 9c4f5f4e..41090ab1 100755 --- a/users/models.py +++ b/users/models.py @@ -334,8 +334,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, return self.state == self.STATE_ACTIVE or self.state == self.STATE_NOT_YET_ACTIVE def set_active(self): - """Enable this user if he subscribed successfully one time before - Active l'utilisateur définitivement si il a adhéré au moins une fois""" + """Enable this user if he subscribed successfully one time before""" if self.state == self.STATE_NOT_YET_ACTIVE: if self.facture_set.filter(valid=True).filter(Q(vente__type_cotisation='All') | Q(vente__type_cotisation='Adhesion')).exists(): self.state = self.STATE_ACTIVE From ded8f89ba824bb9fc0faf07ef21f4038c3f1322e Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 31 Aug 2018 22:25:38 +0200 Subject: [PATCH 009/252] =?UTF-8?q?Fix=20couleurs=20du=20texte=20pour=20l'?= =?UTF-8?q?=C3=A9tat=20'actif'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- users/templates/users/profil.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index 76b3daeb..e0868247 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -52,7 +52,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% elif not users.has_access %}
{% trans "No connection" %}
-
+
{% can_create Facture %} {% trans "Pay for a connection" %} @@ -211,9 +211,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% trans "State" %} {% if users.state == 0 %} - {% trans "Active" %} + {% trans "Active" %} {% elif users.state == 1 %} - {% trans "Disabled" %} + {% trans "Disabled" %} {% elif users.state == 2 %} {% trans "Archived" %} {% elif users.state == 3 %} From cd8a23da31aefa033eb7f48009ee46167629d630 Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 1 Sep 2018 00:55:18 +0200 Subject: [PATCH 010/252] Fix import de users.User --- api/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/views.py b/api/views.py index d117057a..6e5265f6 100644 --- a/api/views.py +++ b/api/views.py @@ -422,7 +422,7 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet): class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet): """Exposes infos of `users.models.Users` objects to create homes. """ - queryset = users.User.objects.exclude(Q(state=User.STATE_DISABLED) | Q(state=User.STATE_NOT_YET_ACTIVE)) + queryset = users.User.objects.exclude(Q(state=users.User.STATE_DISABLED) | Q(state=users.User.STATE_NOT_YET_ACTIVE)) serializer_class = serializers.HomeCreationSerializer class ClubViewSet(viewsets.ReadOnlyModelViewSet): From 2dd410fedfb7b3d7bac1ad7e3c63825369ddf68c Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Fri, 31 Aug 2018 15:53:45 +0200 Subject: [PATCH 011/252] Fix l'envoie de mail, en postsave maintenant (plus propre) --- .../migrations/0034_auto_20180831_1532.py | 20 +++++++++++++++++++ cotisations/models.py | 18 ++++++++++++----- cotisations/payment_methods/balance/models.py | 2 -- cotisations/payment_methods/cheque/models.py | 2 -- cotisations/payment_methods/comnpay/models.py | 2 -- cotisations/views.py | 6 +----- 6 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 cotisations/migrations/0034_auto_20180831_1532.py diff --git a/cotisations/migrations/0034_auto_20180831_1532.py b/cotisations/migrations/0034_auto_20180831_1532.py new file mode 100644 index 00000000..ea698374 --- /dev/null +++ b/cotisations/migrations/0034_auto_20180831_1532.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-08-31 13:32 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cotisations', '0033_auto_20180818_1319'), + ] + + operations = [ + migrations.AlterField( + model_name='facture', + name='valid', + field=models.BooleanField(default=False, verbose_name='validated'), + ), + ] diff --git a/cotisations/models.py b/cotisations/models.py index 8734c17c..15d2e39d 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -50,7 +50,7 @@ from machines.models import regen from re2o.field_permissions import FieldPermissionModelMixin from re2o.mixins import AclMixin, RevMixin -from cotisations.utils import find_payment_method +from cotisations.utils import find_payment_method, send_mail_invoice from cotisations.validators import check_no_balance @@ -137,7 +137,7 @@ class Facture(BaseInvoice): ) # TODO : change name to validity for clarity valid = models.BooleanField( - default=True, + default=False, verbose_name=_("validated") ) # TODO : changed name to controlled for clarity @@ -231,6 +231,7 @@ class Facture(BaseInvoice): self.field_permissions = { 'control': self.can_change_control, } + self.__original_valid = self.valid def __str__(self): return str(self.user) + ' ' + str(self.date) @@ -242,9 +243,12 @@ def facture_post_save(**kwargs): Synchronise the LDAP user after an invoice has been saved. """ facture = kwargs['instance'] - user = facture.user - user.set_active() - user.ldap_sync(base=True, access_refresh=True, mac_refresh=False) + if facture.valid: + user = facture.user + if not facture.__original_valid: + user.set_active() + send_mail_invoice(facture) + user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) @receiver(post_delete, sender=Facture) @@ -702,6 +706,10 @@ class Paiement(RevMixin, AclMixin, models.Model): if payment_method is not None and use_payment_method: return payment_method.end_payment(invoice, request) + ## So make this invoice valid, trigger send mail + invoice.valid = True + invoice.save() + # In case a cotisation was bought, inform the user, the # cotisation time has been extended too if any(sell.type_cotisation for sell in invoice.vente_set.all()): diff --git a/cotisations/payment_methods/balance/models.py b/cotisations/payment_methods/balance/models.py index 250e6949..b4c82556 100644 --- a/cotisations/payment_methods/balance/models.py +++ b/cotisations/payment_methods/balance/models.py @@ -74,8 +74,6 @@ class BalancePayment(PaymentMethodMixin, models.Model): user = invoice.user total_price = invoice.prix_total() if float(user.solde) - float(total_price) < self.minimum_balance: - invoice.valid = False - invoice.save() messages.error( request, _("Your balance is too low for this operation.") diff --git a/cotisations/payment_methods/cheque/models.py b/cotisations/payment_methods/cheque/models.py index cd6d2920..8f00ff46 100644 --- a/cotisations/payment_methods/cheque/models.py +++ b/cotisations/payment_methods/cheque/models.py @@ -46,8 +46,6 @@ class ChequePayment(PaymentMethodMixin, models.Model): """Invalidates the invoice then redirect the user towards a view asking for informations to add to the invoice before validating it. """ - invoice.valid = False - invoice.save() return redirect(reverse( 'cotisations:cheque:validate', kwargs={'invoice_pk': invoice.pk} diff --git a/cotisations/payment_methods/comnpay/models.py b/cotisations/payment_methods/comnpay/models.py index af389cf8..7fac089a 100644 --- a/cotisations/payment_methods/comnpay/models.py +++ b/cotisations/payment_methods/comnpay/models.py @@ -81,8 +81,6 @@ class ComnpayPayment(PaymentMethodMixin, models.Model): a facture id, the price and the secret transaction data stored in the preferences. """ - invoice.valid = False - invoice.save() host = request.get_host() p = Transaction( str(self.payment_credential), diff --git a/cotisations/views.py b/cotisations/views.py index a4a35825..e28a7bf0 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -81,7 +81,7 @@ from .forms import ( ) from .tex import render_invoice from .payment_methods.forms import payment_method_factory -from .utils import find_payment_method, send_mail_invoice +from .utils import find_payment_method @login_required @@ -148,8 +148,6 @@ def new_facture(request, user, userid): p.facture = new_invoice_instance p.save() - send_mail_invoice(new_invoice_instance) - return new_invoice_instance.paiement.end_payment( new_invoice_instance, request @@ -848,8 +846,6 @@ def credit_solde(request, user, **_kwargs): number=1 ) - send_mail_invoice(invoice) - return invoice.paiement.end_payment(invoice, request) p = get_object_or_404(Paiement, is_balance=True) return form({ From d609bb6493fed362d1b267b14a799811357d2fbd Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 1 Sep 2018 02:12:19 +0200 Subject: [PATCH 012/252] Post save custom dans la fonction save, pour __original_valid --- cotisations/models.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cotisations/models.py b/cotisations/models.py index 15d2e39d..0c9ef171 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -233,10 +233,14 @@ class Facture(BaseInvoice): } self.__original_valid = self.valid + def save(self, *args, **kwargs): + super(Facture, self).save(*args, **kwargs) + if not self.__original_valid and self.valid: + send_mail_invoice(self) + def __str__(self): return str(self.user) + ' ' + str(self.date) - @receiver(post_save, sender=Facture) def facture_post_save(**kwargs): """ @@ -245,10 +249,8 @@ def facture_post_save(**kwargs): facture = kwargs['instance'] if facture.valid: user = facture.user - if not facture.__original_valid: - user.set_active() - send_mail_invoice(facture) - user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) + user.set_active() + user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) @receiver(post_delete, sender=Facture) From 5d65e8722925a2d8af42c5e1d5d79793e596d5c3 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 1 Sep 2018 12:10:47 +0200 Subject: [PATCH 013/252] =?UTF-8?q?Redirige=20vers=20l'utilisateur=20cible?= =?UTF-8?q?=20apr=C3=A8s=20un=20paiement=20par=20comnpay.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cotisations/payment_methods/comnpay/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cotisations/payment_methods/comnpay/views.py b/cotisations/payment_methods/comnpay/views.py index 2383f1e9..49dc496f 100644 --- a/cotisations/payment_methods/comnpay/views.py +++ b/cotisations/payment_methods/comnpay/views.py @@ -68,7 +68,7 @@ def accept_payment(request, factureid): ) return redirect(reverse( 'users:profil', - kwargs={'userid': request.user.id} + kwargs={'userid': invoice.user.id} )) From f68a1ae2a960b15b9408b88c67d75163f1f2e722 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 1 Sep 2018 12:00:59 +0200 Subject: [PATCH 014/252] Corrige les classes css du bouton historique des cotisations --- cotisations/templates/cotisations/aff_cotisations.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cotisations/templates/cotisations/aff_cotisations.html b/cotisations/templates/cotisations/aff_cotisations.html index b7fe993b..30de85dc 100644 --- a/cotisations/templates/cotisations/aff_cotisations.html +++ b/cotisations/templates/cotisations/aff_cotisations.html @@ -73,7 +73,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% can_delete facture %} {% include 'buttons/suppr.html' with href='cotisations:del-facture' id=facture.id %} {% acl_end %} - {% history_button facture text=True html_class=False %} + {% history_button facture %} {% if facture.valid %} From 9b080450ab3d474625bcaca94fabd6fade1681c9 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 1 Sep 2018 12:26:15 +0200 Subject: [PATCH 015/252] Fix le choix des articles pour les custom invoices --- cotisations/forms.py | 2 +- cotisations/models.py | 6 ++++-- cotisations/views.py | 5 ++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cotisations/forms.py b/cotisations/forms.py index 9194597a..5ada2fa0 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -102,7 +102,7 @@ class SelectArticleForm(FormRevMixin, Form): def __init__(self, *args, **kwargs): user = kwargs.pop('user') - target_user = kwargs.pop('target_user') + target_user = kwargs.pop('target_user', None) super(SelectArticleForm, self).__init__(*args, **kwargs) self.fields['article'].queryset = Article.find_allowed_articles(user, target_user) diff --git a/cotisations/models.py b/cotisations/models.py index 0c9ef171..e05330bc 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -50,7 +50,7 @@ from machines.models import regen from re2o.field_permissions import FieldPermissionModelMixin from re2o.mixins import AclMixin, RevMixin -from cotisations.utils import find_payment_method, send_mail_invoice +from cotisations.utils import find_payment_method, send_mail_invoice from cotisations.validators import check_no_balance @@ -610,7 +610,9 @@ class Article(RevMixin, AclMixin, models.Model): user: The user requesting articles. target_user: The user to sell articles """ - if target_user.is_class_club: + if target_user is None: + objects_pool = cls.objects.filter(Q(type_user='All')) + elif target_user.is_class_club: objects_pool = cls.objects.filter( Q(type_user='All') | Q(type_user='Club') ) diff --git a/cotisations/views.py b/cotisations/views.py index e28a7bf0..35a97545 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -191,9 +191,9 @@ def new_custom_invoice(request): # Building the invocie form and the article formset invoice_form = CustomInvoiceForm(request.POST or None) - article_formset = formset_factory(SelectArticleForm)( + articles_formset = formset_factory(SelectArticleForm)( request.POST or None, - form_kwargs={'user': request.user, 'target_user': user} + form_kwargs={'user': request.user} ) if invoice_form.is_valid() and articles_formset.is_valid(): @@ -216,7 +216,6 @@ def new_custom_invoice(request): ) return redirect(reverse('cotisations:index-custom-invoice')) - return form({ 'factureform': invoice_form, 'action_name': _("Create"), From 6b1597c0c681ca7e04619a374ca88630a3440e4c Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Comby Date: Sat, 1 Sep 2018 18:38:12 +0200 Subject: [PATCH 016/252] Module de paiement par note --- cotisations/migrations/0035_notepayment.py | 31 +++++++ cotisations/payment_methods/__init__.py | 3 +- cotisations/payment_methods/note/__init__.py | 26 ++++++ cotisations/payment_methods/note/forms.py | 38 ++++++++ cotisations/payment_methods/note/models.py | 65 +++++++++++++ cotisations/payment_methods/note/note.py | 74 +++++++++++++++ cotisations/payment_methods/note/urls.py | 30 ++++++ cotisations/payment_methods/note/views.py | 97 ++++++++++++++++++++ cotisations/payment_methods/urls.py | 3 +- 9 files changed, 365 insertions(+), 2 deletions(-) create mode 100644 cotisations/migrations/0035_notepayment.py create mode 100644 cotisations/payment_methods/note/__init__.py create mode 100644 cotisations/payment_methods/note/forms.py create mode 100644 cotisations/payment_methods/note/models.py create mode 100755 cotisations/payment_methods/note/note.py create mode 100644 cotisations/payment_methods/note/urls.py create mode 100644 cotisations/payment_methods/note/views.py diff --git a/cotisations/migrations/0035_notepayment.py b/cotisations/migrations/0035_notepayment.py new file mode 100644 index 00000000..1d8bcd48 --- /dev/null +++ b/cotisations/migrations/0035_notepayment.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-09-01 11:27 +from __future__ import unicode_literals + +import cotisations.payment_methods.mixins +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cotisations', '0034_auto_20180831_1532'), + ] + + operations = [ + migrations.CreateModel( + name='NotePayment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('server', models.CharField(max_length=255, verbose_name='server')), + ('port', models.PositiveIntegerField(blank=True, null=True)), + ('id_note', models.PositiveIntegerField(blank=True, null=True)), + ('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')), + ], + options={ + 'verbose_name': 'NoteKfet', + }, + bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model), + ), + ] diff --git a/cotisations/payment_methods/__init__.py b/cotisations/payment_methods/__init__.py index b78a86fd..85f2bd53 100644 --- a/cotisations/payment_methods/__init__.py +++ b/cotisations/payment_methods/__init__.py @@ -127,10 +127,11 @@ method to your model, where `form` is an instance of """ -from . import comnpay, cheque, balance, urls +from . import comnpay, cheque, balance, note, urls PAYMENT_METHODS = [ comnpay, cheque, balance, + note ] diff --git a/cotisations/payment_methods/note/__init__.py b/cotisations/payment_methods/note/__init__.py new file mode 100644 index 00000000..1f133d11 --- /dev/null +++ b/cotisations/payment_methods/note/__init__.py @@ -0,0 +1,26 @@ +# -*- mode: python; coding: utf-8 -*- +# Re2o est un logiciel d'administration développé initiallement au rezometz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2018 Gabriel Detraz, Pierre-Antoine Comby +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" +This module contains a method to pay online using comnpay. +""" +from . import models, urls +NAME = "NOTE" +PaymentMethod = models.NotePayment diff --git a/cotisations/payment_methods/note/forms.py b/cotisations/payment_methods/note/forms.py new file mode 100644 index 00000000..e52c275c --- /dev/null +++ b/cotisations/payment_methods/note/forms.py @@ -0,0 +1,38 @@ +# -*- mode: python; coding: utf-8 -*- +# Re2o est un logiciel d'administration développé initiallement au rezometz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2018 Pierre-Antoine Comby +# Copyright © 2018 Gabriel Detraz +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from cotisations.utils import find_payment_method + +class NoteCredentialForm(forms.Form): + """A special form to get credential to connect to a NoteKfet2015 server throught his API + object. + """ + login = forms.CharField( + label=_("pseudo note") + ) + password = forms.CharField( + label=_("Password"), + widget=forms.PasswordInput + ) + diff --git a/cotisations/payment_methods/note/models.py b/cotisations/payment_methods/note/models.py new file mode 100644 index 00000000..60ed8ad3 --- /dev/null +++ b/cotisations/payment_methods/note/models.py @@ -0,0 +1,65 @@ +# -*- mode: python; coding: utf-8 -*- +# Re2o est un logiciel d'administration développé initiallement au rezometz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2018 Pierre-Antoine Comby +# Copyright © 2018 Gabriel Detraz +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +from django.db import models +from django.shortcuts import render +from django.urls import reverse +from django.utils.translation import ugettext_lazy as _ +from django.contrib import messages + +from cotisations.models import Paiement +from cotisations.payment_methods.mixins import PaymentMethodMixin + +from django.shortcuts import render, redirect + + +class NotePayment(PaymentMethodMixin, models.Model): + """ + The model allowing you to pay with NoteKfet2015. + """ + + class Meta: + verbose_name = _("NoteKfet") + + payment = models.OneToOneField( + Paiement, + on_delete = models.CASCADE, + related_name = 'payment_method', + editable = False + ) + server = models.CharField( + max_length=255, + verbose_name=_("server") + ) + port = models.PositiveIntegerField( + blank = True, + null = True + ) + id_note = models.PositiveIntegerField( + blank = True, + null = True + ) + + def end_payment(self, invoice, request): + return redirect(reverse( + 'cotisations:note:note_payment', + kwargs={'factureid': invoice.id} + )) diff --git a/cotisations/payment_methods/note/note.py b/cotisations/payment_methods/note/note.py new file mode 100755 index 00000000..8b7614b0 --- /dev/null +++ b/cotisations/payment_methods/note/note.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 +# -*- coding:utf-8 -*- + +# Codé par PAC , forké de 20-100 + +""" Module pour dialoguer avec la NoteKfet2015 """ + +import socket +import json +import ssl +import traceback + + +def get_response(socket): + length_str = b'' + char = socket.recv(1) + while char != b'\n': + length_str += char + char = socket.recv(1) + total = int(length_str) + return json.loads(socket.recv(total).decode('utf-8')) + +def connect(server, port): + sock = socket.socket() + try: + # On établit la connexion sur port 4242 + sock.connect((server, port)) + # On passe en SSL + sock = ssl.wrap_socket(sock) + # On fait un hello + sock.send(b'["hello", "manual"]') + retcode = get_response(sock) + except: + # Si on a foiré quelque part, c'est que le serveur est down + return (False, sock, "Serveur indisponible") + return (True, sock, "") + +def login(server, port, username, password, masque = [[], [], True]): + result, sock, err = connect(server, port) + if not result: + return (False, None, err) + try: + commande = ["login", [username, password, "bdd", masque]] + sock.send(json.dumps(commande).encode("utf-8")) + response = get_response(sock) + retcode = response['retcode'] + if retcode == 0: + return (True, sock, "") + elif retcode == 5: + return (False, sock, "Login incorrect") + else: + return (False, sock, "Erreur inconnue " + str(retcode)) + except: + # Si on a foiré quelque part, c'est que le serveur est down + return (False, sock, "Erreur de communication avec le serveur") + + +def don(sock, montant, id_note, facture): + """ + Faire faire un don à l'id_note + """ + try: + sock.send(json.dumps(["dons", [[id_note], round(montant*100), "Facture : id=%s, designation=%s" % (facture.id, facture.name())]]).encode("utf-8")) + response = get_response(sock) + retcode = response['retcode'] + transaction_retcode = response["msg"][0][0] + if 0 < retcode < 100 or 200 <= retcode or 0 < transaction_retcode < 100 or 200 <= transaction_retcode: + return (False, "Transaction échouée. (Solde trop négatif ?)") + elif retcode == 0: + return (True, "") + else: + return (False, "Erreur inconnue " + str(retcode)) + except: + return (False, "Erreur de communication avec le serveur") diff --git a/cotisations/payment_methods/note/urls.py b/cotisations/payment_methods/note/urls.py new file mode 100644 index 00000000..7b939136 --- /dev/null +++ b/cotisations/payment_methods/note/urls.py @@ -0,0 +1,30 @@ +# -*- mode: python; coding: utf-8 -*- +# Re2o est un logiciel d'administration développé initiallement au rezometz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2018 Gabriel Detraz +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +from django.conf.urls import url +from . import views + +urlpatterns = [ + url( + r'^note_payment/(?P[0-9]+)$', + views.note_payment, + name='note_payment' + ), +] diff --git a/cotisations/payment_methods/note/views.py b/cotisations/payment_methods/note/views.py new file mode 100644 index 00000000..d4d0ac21 --- /dev/null +++ b/cotisations/payment_methods/note/views.py @@ -0,0 +1,97 @@ +# -*- mode: python; coding: utf-8 -*- +# Re2o est un logiciel d'administration développé initiallement au rezometz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2018 Gabriel Detraz +# Copyright © 2018 Pierre-Antoine Comby +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +"""Payment + +Here are the views needed by comnpay +""" + +from collections import OrderedDict + +from django.urls import reverse +from django.shortcuts import redirect, get_object_or_404 +from django.contrib.auth.decorators import login_required +from django.contrib import messages +from django.views.decorators.csrf import csrf_exempt +from django.utils.datastructures import MultiValueDictKeyError +from django.utils.translation import ugettext as _ +from django.http import HttpResponse, HttpResponseBadRequest + +from cotisations.models import Facture +from cotisations.utils import find_payment_method +from .models import NotePayment +from re2o.views import form +from re2o.acl import ( + can_create, + can_edit +) +from .note import login, don +from .forms import NoteCredentialForm + +@login_required +@can_edit(Facture) +def note_payment(request, facture, factureid): + """ + Build a request to start the negociation with NoteKfet by using + a facture id, the price and the login/password data stored in + the preferences. + """ + user = facture.user + payment_method = find_payment_method(facture.paiement) + if not payment_method or not isinstance(payment_method, NotePayment): + messages.error(request, "Erreur inconnue") + return redirect(reverse( + 'users:profil', + kwargs={'userid': user.id} + )) + noteform = NoteCredentialForm(request.POST or None) + if noteform.is_valid(): + pseudo = noteform.cleaned_data['login'] + password = noteform.cleaned_data['password'] + result, sock, err = login(payment_method.server, payment_method.port, pseudo, password) + if not result: + messages.error(request, err) + return form( + {'form': noteform, 'amount': facture.prix_total()}, + "cotisations/payment.html", + request + ) + else: + result, err = don(sock, facture.prix_total(), payment_method.id_note, facture) + if not result: + messages.error(request, err) + return form( + {'form': noteform, 'amount': facture.prix_total()}, + "cotisations/payment.html", + request + ) + facture.valid = True + facture.save() + messages.success(request, "Le paiement par note a bien été effectué") + return redirect(reverse( + 'users:profil', + kwargs={'userid': user.id} + )) + return form( + {'form': noteform, 'amount': facture.prix_total()}, + "cotisations/payment.html", + request + ) diff --git a/cotisations/payment_methods/urls.py b/cotisations/payment_methods/urls.py index 20e50255..dd6d7726 100644 --- a/cotisations/payment_methods/urls.py +++ b/cotisations/payment_methods/urls.py @@ -19,9 +19,10 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. from django.conf.urls import include, url -from . import comnpay, cheque +from . import comnpay, cheque, note urlpatterns = [ url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')), url(r'^cheque/', include(cheque.urls, namespace='cheque')), + url(r'^note/', include(note.urls, namespace='note')), ] From f5eb4616f5e6839b42fe9211ef1111c5bec68950 Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 1 Sep 2018 19:08:11 +0200 Subject: [PATCH 017/252] Rename note en note_kfet --- cotisations/payment_methods/__init__.py | 4 ++-- cotisations/payment_methods/{note => note_kfet}/__init__.py | 0 cotisations/payment_methods/{note => note_kfet}/forms.py | 0 cotisations/payment_methods/{note => note_kfet}/models.py | 2 +- cotisations/payment_methods/{note => note_kfet}/note.py | 0 cotisations/payment_methods/{note => note_kfet}/urls.py | 0 cotisations/payment_methods/{note => note_kfet}/views.py | 0 cotisations/payment_methods/urls.py | 4 ++-- 8 files changed, 5 insertions(+), 5 deletions(-) rename cotisations/payment_methods/{note => note_kfet}/__init__.py (100%) rename cotisations/payment_methods/{note => note_kfet}/forms.py (100%) rename cotisations/payment_methods/{note => note_kfet}/models.py (97%) rename cotisations/payment_methods/{note => note_kfet}/note.py (100%) rename cotisations/payment_methods/{note => note_kfet}/urls.py (100%) rename cotisations/payment_methods/{note => note_kfet}/views.py (100%) diff --git a/cotisations/payment_methods/__init__.py b/cotisations/payment_methods/__init__.py index 85f2bd53..1efde30b 100644 --- a/cotisations/payment_methods/__init__.py +++ b/cotisations/payment_methods/__init__.py @@ -127,11 +127,11 @@ method to your model, where `form` is an instance of """ -from . import comnpay, cheque, balance, note, urls +from . import comnpay, cheque, balance, note_kfet, urls PAYMENT_METHODS = [ comnpay, cheque, balance, - note + note_kfet ] diff --git a/cotisations/payment_methods/note/__init__.py b/cotisations/payment_methods/note_kfet/__init__.py similarity index 100% rename from cotisations/payment_methods/note/__init__.py rename to cotisations/payment_methods/note_kfet/__init__.py diff --git a/cotisations/payment_methods/note/forms.py b/cotisations/payment_methods/note_kfet/forms.py similarity index 100% rename from cotisations/payment_methods/note/forms.py rename to cotisations/payment_methods/note_kfet/forms.py diff --git a/cotisations/payment_methods/note/models.py b/cotisations/payment_methods/note_kfet/models.py similarity index 97% rename from cotisations/payment_methods/note/models.py rename to cotisations/payment_methods/note_kfet/models.py index 60ed8ad3..be54bd54 100644 --- a/cotisations/payment_methods/note/models.py +++ b/cotisations/payment_methods/note_kfet/models.py @@ -60,6 +60,6 @@ class NotePayment(PaymentMethodMixin, models.Model): def end_payment(self, invoice, request): return redirect(reverse( - 'cotisations:note:note_payment', + 'cotisations:note_kfet:note_payment', kwargs={'factureid': invoice.id} )) diff --git a/cotisations/payment_methods/note/note.py b/cotisations/payment_methods/note_kfet/note.py similarity index 100% rename from cotisations/payment_methods/note/note.py rename to cotisations/payment_methods/note_kfet/note.py diff --git a/cotisations/payment_methods/note/urls.py b/cotisations/payment_methods/note_kfet/urls.py similarity index 100% rename from cotisations/payment_methods/note/urls.py rename to cotisations/payment_methods/note_kfet/urls.py diff --git a/cotisations/payment_methods/note/views.py b/cotisations/payment_methods/note_kfet/views.py similarity index 100% rename from cotisations/payment_methods/note/views.py rename to cotisations/payment_methods/note_kfet/views.py diff --git a/cotisations/payment_methods/urls.py b/cotisations/payment_methods/urls.py index dd6d7726..f6bb31dd 100644 --- a/cotisations/payment_methods/urls.py +++ b/cotisations/payment_methods/urls.py @@ -19,10 +19,10 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. from django.conf.urls import include, url -from . import comnpay, cheque, note +from . import comnpay, cheque, note_kfet urlpatterns = [ url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')), url(r'^cheque/', include(cheque.urls, namespace='cheque')), - url(r'^note/', include(note.urls, namespace='note')), + url(r'^note_kfet/', include(note_kfet.urls, namespace='note_kfet')), ] From 32be355fd8bf7ab23b83f2e4c1f6b3e5ccd8f643 Mon Sep 17 00:00:00 2001 From: detraz Date: Sun, 2 Sep 2018 18:07:43 +0200 Subject: [PATCH 018/252] Corrections de front buttons et labels cotisations --- cotisations/locale/fr/LC_MESSAGES/django.mo | Bin 16996 -> 16926 bytes cotisations/locale/fr/LC_MESSAGES/django.po | 22 +++++++----------- .../templates/cotisations/control.html | 2 +- cotisations/templates/cotisations/delete.html | 2 +- .../templates/cotisations/edit_facture.html | 4 ++-- .../templates/cotisations/facture.html | 8 +++---- .../templates/cotisations/payment.html | 2 +- cotisations/views.py | 4 ++-- 8 files changed, 20 insertions(+), 24 deletions(-) diff --git a/cotisations/locale/fr/LC_MESSAGES/django.mo b/cotisations/locale/fr/LC_MESSAGES/django.mo index b5a65357c7cdca3510ade884242d8b729da0eb65..3a1671bbfcbedf829e2923ff601b75f00d441560 100644 GIT binary patch delta 4591 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 UWi4?7KMSp-Q>X21A9z*tzulzVyZ`_I diff --git a/cotisations/locale/fr/LC_MESSAGES/django.po b/cotisations/locale/fr/LC_MESSAGES/django.po index 129d4d72..15f6a057 100644 --- a/cotisations/locale/fr/LC_MESSAGES/django.po +++ b/cotisations/locale/fr/LC_MESSAGES/django.po @@ -681,8 +681,9 @@ msgstr "" #: templates/cotisations/delete.html:38 #: templates/cotisations/edit_facture.html:60 +#: views.py:181 views.py:235 msgid "Confirm" -msgstr "Confirmer" +msgstr "Valider" #: templates/cotisations/edit_facture.html:31 #: templates/cotisations/facture.html:30 @@ -695,12 +696,13 @@ msgstr "Modifier la facture" #: templates/cotisations/edit_facture.html:41 #: templates/cotisations/facture.html:56 -msgid "Invoice's articles" -msgstr "Articles de la facture" +#: templates/cotisations/index_article.html:30 +msgid "Articles" +msgstr "Articles" #: templates/cotisations/facture.html:37 -msgid "New invoice" -msgstr "Nouvelle facture" +msgid "Buy" +msgstr "Acheter une cotisation" #: templates/cotisations/facture.html:40 #, python-format @@ -713,8 +715,8 @@ msgid "Current balance: %(balance)s €" msgstr "Solde actuel : %(balance)s €" #: templates/cotisations/facture.html:70 -msgid "Add an article" -msgstr "Ajouter un article" +msgid "Add an extra article" +msgstr "Ajouter un article supplémentaire" #: templates/cotisations/facture.html:72 msgid "Total price: 0,00 €" @@ -728,9 +730,6 @@ msgstr "Factures" msgid "Subscriptions" msgstr "Cotisations" -#: templates/cotisations/index_article.html:30 -msgid "Articles" -msgstr "Articles" #: templates/cotisations/index_article.html:33 msgid "Article types list" @@ -812,9 +811,6 @@ msgstr "Contrôler les factures" msgid "You need to choose at least one article." msgstr "Vous devez choisir au moins un article." -#: views.py:181 views.py:235 -msgid "Create" -msgstr "Créer" #: views.py:228 msgid "The custom invoice was created." diff --git a/cotisations/templates/cotisations/control.html b/cotisations/templates/cotisations/control.html index 6a4a5cca..483c150c 100644 --- a/cotisations/templates/cotisations/control.html +++ b/cotisations/templates/cotisations/control.html @@ -105,7 +105,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endfor %} {% trans "Edit" as tr_edit %} - {% bootstrap_button tr_edit button_type='submit' icon='star' %} + {% bootstrap_button tr_edit button_type='submit' icon='ok' button_class='btn-success' %} {% endblock %} diff --git a/cotisations/templates/cotisations/delete.html b/cotisations/templates/cotisations/delete.html index dc06e5a5..58ce8ad2 100644 --- a/cotisations/templates/cotisations/delete.html +++ b/cotisations/templates/cotisations/delete.html @@ -36,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% blocktrans %}Warning: are you sure you really want to delete this {{ object_name }} object ( {{ objet }} )?{% endblocktrans %} {% trans "Confirm" as tr_confirm %} - {% bootstrap_button tr_confirm button_type='submit' icon='trash' %} + {% bootstrap_button tr_confirm button_type='submit' icon='trash' button_class='btn-danger' %} {% endblock %} diff --git a/cotisations/templates/cotisations/edit_facture.html b/cotisations/templates/cotisations/edit_facture.html index 9ddcac8c..a00084f6 100644 --- a/cotisations/templates/cotisations/edit_facture.html +++ b/cotisations/templates/cotisations/edit_facture.html @@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

{% trans "Edit the invoice" %}

{% massive_bootstrap_form factureform 'user' %} {{ venteform.management_form }} -

{% trans "Invoice's articles" %}

+

{% trans "Articles" %}

@@ -58,7 +58,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endfor %}
{% trans "Confirm" as tr_confirm %} - {% bootstrap_button tr_confirm button_type='submit' icon='star' %} + {% bootstrap_button tr_confirm button_type='submit' icon='ok' button_class='btn-success' %} {% endblock %} diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index 4f905160..1f87f579 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if title %}

{{ title }}

{% else %} -

{% trans "New invoice" %}

+

{% trans "Buy" %}

{% endif %} {% if max_balance %}

{% blocktrans %}Maximum allowed balance: {{ max_balance }} €{% endblocktrans %}

@@ -53,7 +53,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endif %} {% if articlesformset %} -

{% trans "Invoice's articles" %}

+

{% trans "Articles" %}

{{ articlesformset.management_form }} {% for articlesform in articlesformset.forms %} @@ -67,12 +67,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endfor %}
- +

{% blocktrans %}Total price: 0,00 €{% endblocktrans %}

{% endif %} - {% bootstrap_button action_name button_type='submit' icon='star' %} + {% bootstrap_button action_name button_type='submit' icon='ok' button_class='btn-success' %} {% if articlesformset or payment_method%} diff --git a/cotisations/templates/cotisations/payment.html b/cotisations/templates/cotisations/payment.html index 997168fd..ecd90ed8 100644 --- a/cotisations/templates/cotisations/payment.html +++ b/cotisations/templates/cotisations/payment.html @@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% bootstrap_form form %} {% endif %} {% trans "Pay" as tr_pay %} - {% bootstrap_button tr_pay button_type='submit' icon='piggy-bank' %} + {% bootstrap_button tr_pay button_type='submit' icon='piggy-bank' button_class='btn-success' %} {% endblock %} diff --git a/cotisations/views.py b/cotisations/views.py index 35a97545..9241f209 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -169,7 +169,7 @@ def new_facture(request, user, userid): 'articlesformset': article_formset, 'articlelist': article_list, 'balance': balance, - 'action_name': _('Create'), + 'action_name': _('Confirm'), }, 'cotisations/facture.html', request ) @@ -218,7 +218,7 @@ def new_custom_invoice(request): return form({ 'factureform': invoice_form, - 'action_name': _("Create"), + 'action_name': _("Confirm"), 'articlesformset': articles_formset, 'articlelist': articles }, 'cotisations/facture.html', request) From dacf1e461599a4d2b3ef6304c91233db3a55913a Mon Sep 17 00:00:00 2001 From: detraz Date: Sun, 2 Sep 2018 18:28:54 +0200 Subject: [PATCH 019/252] Correction des boutons sur les autres apps --- machines/templates/machines/delete.html | 2 +- machines/templates/machines/edit_portlist.html | 2 +- machines/templates/machines/machine.html | 2 +- preferences/templates/preferences/edit_preferences.html | 2 +- preferences/templates/preferences/preferences.html | 2 +- topologie/templates/topologie/delete.html | 2 +- topologie/templates/topologie/switch.html | 2 +- topologie/templates/topologie/topo.html | 2 +- topologie/templates/topologie/topo_more.html | 2 +- users/templates/users/delete.html | 2 +- users/templates/users/user.html | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/machines/templates/machines/delete.html b/machines/templates/machines/delete.html index 1c9811f2..ae365c69 100644 --- a/machines/templates/machines/delete.html +++ b/machines/templates/machines/delete.html @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% csrf_token %}

{% blocktrans %}Warning: are you sure you want to delete this object {{ objet_name }} ( {{ objet }} )?{% endblocktrans %}

{% trans "Confirm" as tr_confirm %} - {% bootstrap_button tr_confirm button_type="submit" icon="trash" %} + {% bootstrap_button tr_confirm button_type="submit" icon='trash' button_class='btn-danger' %}

diff --git a/machines/templates/machines/edit_portlist.html b/machines/templates/machines/edit_portlist.html index d6a5e9df..5bb8723f 100644 --- a/machines/templates/machines/edit_portlist.html +++ b/machines/templates/machines/edit_portlist.html @@ -51,7 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

{% trans "Create or edit" as tr_create_or_edit %} - {% bootstrap_button tr_create_or_edit button_type="submit" icon="star" %} + {% bootstrap_button tr_create_or_edit icon='ok' button_class='btn-success' %} From eae05e4b7ce82ca9b40967bc8ff5711b47bc59f9 Mon Sep 17 00:00:00 2001 From: detraz Date: Sun, 2 Sep 2018 20:22:25 +0200 Subject: [PATCH 020/252] Permet la recherche avec telephone et email des users --- search/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/search/views.py b/search/views.py index 93aa1d0e..495a7df7 100644 --- a/search/views.py +++ b/search/views.py @@ -140,7 +140,9 @@ def search_single_word(word, filters, user, ) | Q( room__name__icontains=word ) | Q( - room__name__icontains=word + email__icontains=word + ) | Q( + telephone__icontains=word ) ) & Q(state__in=user_state) if not User.can_view_all(user)[0]: From 66614873067f02955dff95ca951f08ba6e813c55 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Mon, 3 Sep 2018 12:12:12 +0200 Subject: [PATCH 021/252] =?UTF-8?q?Lien=20pour=20envoyer=20un=20mail=20dir?= =?UTF-8?q?ectement=20=C3=A0=20un=20utilisateur=20sur=20la=20page=20profil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- users/templates/users/profil.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index e0868247..87825606 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -166,10 +166,10 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ users.surname }} - {% trans "Username" %} + {% trans "Username" %} {{ users.pseudo }} - {% trans "Email address" %} - {{ users.email }} + {% trans "Email address" %} +
{{users.email}} {% trans "Room" %} From 52f3d4d5503b5ed9719fff3c96d4740af5025698 Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 8 Sep 2018 21:09:17 +0200 Subject: [PATCH 022/252] =?UTF-8?q?Not=20yet=20member,=20possibilit=C3=A9?= =?UTF-8?q?=20de=20trouver=20les=20users=20pas=20encore=20adh=C3=A9rents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logs/views.py | 8 ++++++++ search/forms.py | 1 + 2 files changed, 9 insertions(+) diff --git a/logs/views.py b/logs/views.py index a9fe5418..21e3c470 100644 --- a/logs/views.py +++ b/logs/views.py @@ -254,6 +254,14 @@ def stats_general(request): .count()), Club.objects.filter(state=Club.STATE_ARCHIVE).count() ], + 'not_active_users': [ + _("Not yet active users"), + User.objects.filter(state=User.STATE_NOT_YET_ACTIVE).count(), + (Adherent.objects + .filter(state=Adherent.STATE_NOT_YET_ACTIVE) + .count()), + Club.objects.filter(state=Club.STATE_NOT_YET_ACTIVE).count() + ], 'adherent_users': [ _("Contributing members"), _all_adherent.count(), diff --git a/search/forms.py b/search/forms.py index 6065e799..5c98415f 100644 --- a/search/forms.py +++ b/search/forms.py @@ -33,6 +33,7 @@ CHOICES_USER = ( ('0', _("Active")), ('1', _("Disabled")), ('2', _("Archived")), + ('3', _("Not Yet Active")), ) CHOICES_AFF = ( From 5b347f3db4f63715e731dec8c251c2c9c3dfe7f6 Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 8 Sep 2018 21:09:48 +0200 Subject: [PATCH 023/252] Fix, utilise la bonne fonction d'envoie de mails --- cotisations/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cotisations/utils.py b/cotisations/utils.py index 0211dd40..a8c2768e 100644 --- a/cotisations/utils.py +++ b/cotisations/utils.py @@ -89,7 +89,7 @@ def send_mail_invoice(invoice): 'Votre facture / Your invoice', template.render(ctx), GeneralOption.get_cached_value('email_from'), - [invoice.user.email], + [invoice.user.get_mail], attachments=[('invoice.pdf', pdf, 'application/pdf')] ) mail.send() From 9fdadaf478310dce7aa1ca2c9dbb107b7493b536 Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 8 Sep 2018 21:11:04 +0200 Subject: [PATCH 024/252] =?UTF-8?q?Le=20home=20est=20une=20methode=20+=20r?= =?UTF-8?q?=C3=A8gle=20les=20probl=C3=A8mes=20de=20la=20casse=20sur=20le?= =?UTF-8?q?=20pseudo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- users/models.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/users/models.py b/users/models.py index 41090ab1..f579148c 100755 --- a/users/models.py +++ b/users/models.py @@ -93,7 +93,7 @@ from preferences.models import OptionalMachine, MailMessageOption def linux_user_check(login): """ Validation du pseudo pour respecter les contraintes unix""" - UNIX_LOGIN_PATTERN = re.compile("^[a-zA-Z0-9-]*[$]?$") + UNIX_LOGIN_PATTERN = re.compile("^[a-zA-Z][a-zA-Z0-9-]*[$]?$") return UNIX_LOGIN_PATTERN.match(login) @@ -374,6 +374,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, si il n'est pas défini""" return self.shell or OptionalUser.get_cached_value('shell_default') + @cached_property + def home_directory(self): + return '/home/' + self.pseudo + @cached_property def get_shadow_expire(self): """Return the shadow_expire value for the user""" @@ -581,7 +585,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, user_ldap.name = self.pseudo user_ldap.sn = self.pseudo user_ldap.dialupAccess = str(self.has_access()) - user_ldap.home_directory = '/home/' + self.pseudo + user_ldap.home_directory = self.home_directory user_ldap.mail = self.get_mail user_ldap.given_name = self.surname.lower() + '_'\ + self.name.lower()[:3] From f2c132016f23ff9f3a640e50a4f8a128b7103513 Mon Sep 17 00:00:00 2001 From: detraz Date: Sat, 8 Sep 2018 21:11:42 +0200 Subject: [PATCH 025/252] =?UTF-8?q?Les=20factures=20sont=20valid=C3=A9es?= =?UTF-8?q?=20en=20post=5Fpaiement=20+=20bug=20fix=20paiement=20relation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cotisations/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cotisations/views.py b/cotisations/views.py index 9241f209..4cd76f93 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -836,7 +836,6 @@ def credit_solde(request, user, **_kwargs): else: price_ok = True if price_ok: - invoice.valid = True invoice.save() Vente.objects.create( facture=invoice, @@ -852,6 +851,6 @@ def credit_solde(request, user, **_kwargs): 'balance': user.solde, 'title': _("Refill your balance"), 'action_name': _("Pay"), - 'max_balance': p.payment_method.maximum_balance, + 'max_balance': find_payment_method(p).maximum_balance, }, 'cotisations/facture.html', request) From 992dc9702463e60c2ab2c480577f89fef1bddcc4 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Wed, 19 Sep 2018 10:06:09 +0200 Subject: [PATCH 026/252] Fix initial migration Initial migration was failing due to change_facture_pdf not being initialised at the right time. --- cotisations/migrations/0032_custom_invoice.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cotisations/migrations/0032_custom_invoice.py b/cotisations/migrations/0032_custom_invoice.py index 68963bf5..39c23e8b 100644 --- a/cotisations/migrations/0032_custom_invoice.py +++ b/cotisations/migrations/0032_custom_invoice.py @@ -30,7 +30,9 @@ def update_rights(apps, schema_editor): create_permissions(app) app.models_module = False - former = Permission.objects.get(codename='change_facture_pdf') + ContentType = apps.get_model("contenttypes", "ContentType") + content_type = ContentType.objects.get_for_model(Permission) + former, created = Permission.objects.get_or_create(codename='change_facture_pdf', content_type=content_type) new_1 = Permission.objects.get(codename='add_custominvoice') new_2 = Permission.objects.get(codename='change_custominvoice') new_3 = Permission.objects.get(codename='view_custominvoice') From b7359f5b3880c2fe0c8ae2031e054b52f666e6d8 Mon Sep 17 00:00:00 2001 From: edpibu Date: Wed, 19 Sep 2018 15:40:53 +0200 Subject: [PATCH 027/252] =?UTF-8?q?Fix=20170:=20Ajout=20d'une=20case=20?= =?UTF-8?q?=C3=A0=20cocher=20pour=20=C3=A9viter=20les=20doublons=20de=20co?= =?UTF-8?q?mptes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- users/forms.py | 16 ++++++++++++++++ users/views.py | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/users/forms.py b/users/forms.py index a6ea70b9..e2339a0d 100644 --- a/users/forms.py +++ b/users/forms.py @@ -375,6 +375,22 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): remove_user_room(self.cleaned_data.get('room')) return +class AdherentCreationForm(AdherentForm): + """Formulaire de création d'un user. + AdherentForm auquel on ajoute une checkbox afin d'éviter les + doublons d'utilisateurs""" + def __init__(self, *args, **kwargs): + super(AdherentCreationForm, self).__init__(*args, **kwargs) + + # Champ permettant d'éviter au maxium les doublons d'utilisateurs + former_user_check_info = _("If you already have an account, please use it. "\ + + "If your lost access to it, please consider "\ + + "using the forgotten password button on the "\ + + "login page or contacting support.") + self.fields['former_user_check'] = forms.BooleanField(required=True, + help_text=former_user_check_info) + self.fields['former_user_check'].label = _("I have not had an account before") + class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): """Formulaire de base d'edition d'un user. Formulaire de base, utilisé diff --git a/users/views.py b/users/views.py index 360e256b..41138ce3 100644 --- a/users/views.py +++ b/users/views.py @@ -100,6 +100,7 @@ from .forms import ( ServiceUserForm, ListRightForm, AdherentForm, + AdherentCreationForm, ClubForm, MassArchiveForm, PassForm, @@ -114,7 +115,7 @@ from .forms import ( def new_user(request): """ Vue de création d'un nouvel utilisateur, envoie un mail pour le mot de passe""" - user = AdherentForm(request.POST or None, user=request.user) + user = AdherentCreationForm(request.POST or None, user=request.user) GTU_sum_up = GeneralOption.get_cached_value('GTU_sum_up') GTU = GeneralOption.get_cached_value('GTU') if user.is_valid(): From 1d107d33f2dfac9bf64ef92f70f66b63a2033acf Mon Sep 17 00:00:00 2001 From: edpibu Date: Wed, 19 Sep 2018 23:24:15 +0200 Subject: [PATCH 028/252] Fixed field creation --- users/forms.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/users/forms.py b/users/forms.py index e2339a0d..65e06715 100644 --- a/users/forms.py +++ b/users/forms.py @@ -379,19 +379,18 @@ class AdherentCreationForm(AdherentForm): """Formulaire de création d'un user. AdherentForm auquel on ajoute une checkbox afin d'éviter les doublons d'utilisateurs""" + + # Champ permettant d'éviter au maxium les doublons d'utilisateurs + former_user_check_info = _("If you already have an account, please use it. "\ + + "If your lost access to it, please consider "\ + + "using the forgotten password button on the "\ + + "login page or contacting support.") + former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info) + former_user_check = _("I have not had an account before") + def __init__(self, *args, **kwargs): super(AdherentCreationForm, self).__init__(*args, **kwargs) - - # Champ permettant d'éviter au maxium les doublons d'utilisateurs - former_user_check_info = _("If you already have an account, please use it. "\ - + "If your lost access to it, please consider "\ - + "using the forgotten password button on the "\ - + "login page or contacting support.") - self.fields['former_user_check'] = forms.BooleanField(required=True, - help_text=former_user_check_info) - self.fields['former_user_check'].label = _("I have not had an account before") - - + class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): """Formulaire de base d'edition d'un user. Formulaire de base, utilisé pour l'edition de self par self ou un cableur. On formate les champs From d0fdf841cf3df4076c57200173b822c9b97bc61a Mon Sep 17 00:00:00 2001 From: edpibu Date: Thu, 20 Sep 2018 08:39:48 +0200 Subject: [PATCH 029/252] Fixed label creation on AdherentCreationForm. Added AdherentEditForm. shell and gpg_fingerprint fields have been moved from AdherentForm to AdherentEditForm. --- users/forms.py | 45 ++++++++++++++++++++++++++++++++------------- users/views.py | 4 ++-- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/users/forms.py b/users/forms.py index 65e06715..7954895a 100644 --- a/users/forms.py +++ b/users/forms.py @@ -318,9 +318,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): self.fields['room'].label = _("Room") self.fields['room'].empty_label = _("No room") self.fields['school'].empty_label = _("Select a school") - self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.") - if 'shell' in self.fields: - self.fields['shell'].empty_label = _("Default shell") def clean_email(self): if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get('email'): @@ -340,9 +337,7 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): 'school', 'comment', 'telephone', - 'room', - 'shell', - 'gpg_fingerprint' + 'room' ] @@ -356,12 +351,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): ) return telephone - def clean_gpg_fingerprint(self): - """Format the GPG fingerprint""" - gpg_fingerprint = self.cleaned_data.get('gpg_fingerprint', None) - if gpg_fingerprint: - return gpg_fingerprint.replace(' ', '').upper() - force = forms.BooleanField( label=_("Force the move?"), initial=False, @@ -386,10 +375,40 @@ class AdherentCreationForm(AdherentForm): + "using the forgotten password button on the "\ + "login page or contacting support.") former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info) - former_user_check = _("I have not had an account before") + former_user_check.label = _("I have not had an account before") def __init__(self, *args, **kwargs): super(AdherentCreationForm, self).__init__(*args, **kwargs) + +class AdherentEditForm(AdherentForm): + """Formulaire d'édition d'un user. + AdherentForm incluant la modification des champs gpg et shell""" + def __init__(self, *args, **kargs): + super(AdherentEditForm, self).__init__(*args, **kwargs) + self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.") + if 'shell' in self.fields: + self.fields['shell'].empty_label = _("Default shell") + + def clean_gpg_fingerprint(self): + """Format the GPG fingerprint""" + gpg_fingerprint = self.cleaned_data.get('gpg_fingerprint', None) + if gpg_fingerprint: + return gpg_fingerprint.replace(' ', '').upper() + + class Meta: + model = Adherent + fields = [ + 'name', + 'surname', + 'pseudo', + 'email', + 'school', + 'comment', + 'telephone', + 'room', + 'shell', + 'gpg_fingerprint' + ] class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): """Formulaire de base d'edition d'un user. Formulaire de base, utilisé diff --git a/users/views.py b/users/views.py index 41138ce3..77a23878 100644 --- a/users/views.py +++ b/users/views.py @@ -99,8 +99,8 @@ from .forms import ( EditServiceUserForm, ServiceUserForm, ListRightForm, - AdherentForm, AdherentCreationForm, + AdherentEditForm, ClubForm, MassArchiveForm, PassForm, @@ -198,7 +198,7 @@ def edit_info(request, user, userid): si l'id est différent de request.user, vérifie la possession du droit cableur """ if user.is_class_adherent: - user_form = AdherentForm( + user_form = AdherentEditForm( request.POST or None, instance=user.adherent, user=request.user From 2db88d628a3a36267e5373ab496b1c4645421df6 Mon Sep 17 00:00:00 2001 From: edpibu Date: Thu, 20 Sep 2018 10:57:31 +0200 Subject: [PATCH 030/252] Added checkbox for GTU. --- users/forms.py | 9 ++++++++- users/templates/users/user.html | 1 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/users/forms.py b/users/forms.py index 7954895a..525ebb74 100644 --- a/users/forms.py +++ b/users/forms.py @@ -48,6 +48,8 @@ from re2o.utils import remove_user_room, get_input_formats_help_text from re2o.mixins import FormRevMixin from re2o.field_permissions import FieldPermissionFormMixin +from preferences.models import GeneralOption + from .widgets import DateTimePicker from .models import ( @@ -377,13 +379,18 @@ class AdherentCreationForm(AdherentForm): former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info) former_user_check.label = _("I have not had an account before") + # Checkbox for GTU + gtu_check = forms.BooleanField(required=True) + gtu_check.label = mark_safe("{}{}{}".format( + _("I commit to accept the "), GeneralOption.get_cached_value('GTU'), _("General Terms of Use"), _("."))) + def __init__(self, *args, **kwargs): super(AdherentCreationForm, self).__init__(*args, **kwargs) class AdherentEditForm(AdherentForm): """Formulaire d'édition d'un user. AdherentForm incluant la modification des champs gpg et shell""" - def __init__(self, *args, **kargs): + def __init__(self, *args, **kargs): super(AdherentEditForm, self).__init__(*args, **kwargs) self.fields['gpg_fingerprint'].widget.attrs['placeholder'] = _("Leave empty if you don't have any GPG key.") if 'shell' in self.fields: diff --git a/users/templates/users/user.html b/users/templates/users/user.html index 3f19d3d8..6282c2fa 100644 --- a/users/templates/users/user.html +++ b/users/templates/users/user.html @@ -42,7 +42,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %}
{% if showCGU %} -

{% trans "By clicking 'Create or edit', the user commits to respect the " %}{% trans "General Terms of Use" %}.

{% trans "Summary of the General Terms of Use" %}

{{ GTU_sum_up }}

{% endif %} From 9e578bf93d2ed80dd76d6879cf1582362d2c264d Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Thu, 20 Sep 2018 15:38:36 +0200 Subject: [PATCH 031/252] Fix merge request 294 --- users/forms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/users/forms.py b/users/forms.py index 525ebb74..d2dfabb5 100644 --- a/users/forms.py +++ b/users/forms.py @@ -40,6 +40,7 @@ from django.core.validators import MinLengthValidator from django.utils import timezone from django.contrib.auth.models import Group, Permission from django.utils.translation import ugettext_lazy as _ +from django.utils.safestring import mark_safe from machines.models import Interface, Machine, Nas from topologie.models import Port From a0bb34f74093f649bc07c9c1be935687b94099c1 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Fri, 21 Sep 2018 12:47:59 +0200 Subject: [PATCH 032/252] Update .gitignore to ignore more files Based on the Python template : https://github.com/github/gitignore/ I'm using PyCharm which creates .idea folders. So I need this to make my life easier. --- .gitignore | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c65c2cc3..49df31ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,48 @@ -settings_local.py +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class *.swp -*.pyc + +# Translations +#*.mo TODO +*.pot + +# Django stuff +*.log +local_settings.py +db.sqlite3 + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# PyCharm project settings +.idea/ + +# Django statics +static_files/ +static/logo/ + +# re2o specific +settings_local.py re2o.png -__pycache__/* -static_files/* -static/logo/* -media/* +media/ From e571751c706a5541aeb421bf366d328e35e01585 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Sep 2018 22:11:25 +0200 Subject: [PATCH 033/252] Fix footer and about * Rather than using href="\\host/about/" in page footer, use href="protocol://host/about/" * The old footer uses hacks to be staticly on the bottom. To make it much simpler one solution is to turn it white and use official Bootstrap code. This leads to less CSS to maintain and better cross-browser compatibility. * On re2o about page (/about/) there is some typos such as : * assocations > associations * legitlab > le gitlab * Use Bootstrap navbar-static-top rather than custom CSS. The result is the same, so we should be better using directly Bootstrap CSS. --- re2o/locale/fr/LC_MESSAGES/django.mo | Bin 5658 -> 5619 bytes re2o/locale/fr/LC_MESSAGES/django.po | 4 +- static/css/base.css | 34 +- templates/base.html | 373 +++++++++++----------- templates/locale/fr/LC_MESSAGES/django.mo | Bin 5348 -> 5886 bytes templates/locale/fr/LC_MESSAGES/django.po | 28 +- 6 files changed, 228 insertions(+), 211 deletions(-) diff --git a/re2o/locale/fr/LC_MESSAGES/django.mo b/re2o/locale/fr/LC_MESSAGES/django.mo index e51e7ad2c405c39dd7c69a5d303d5cdd7f5053c7..e3d6b8ed33926ba613cc385cae1ce79cb5766660 100644 GIT binary patch delta 425 zcmXZXJxIe)5Ww+^23k$6mipC29%|7Nr8X3CadPNVq)Qi36k~=$QBYb?#NejjAm|Xp zv2G5Q?8Q;g$w6>;62!s9LDB!Cg$KWP_wF8dS2JJs-J#)IhRBU2GASa>n8+Ny-~>kc zL^5b&3d@+l9UR7Eq*VfpU<1>5izE1qCcYzI$|vf&A5>_@#g`r~>9|M~v)GFZIEqWC z8&>fIx9|)H#)z4EHgMLB|Jlh`%w1_E0-s!&%~U%wsEj?fQ*|f0l0=mGEdFW=y%BDlC^(skT|I ixT;ujy=_u;M@<(>#k!MGd$nCv^)7PJeE61_H~#?(;5v~2 delta 432 zcmXZXF-SsT5Ww-%q+V&3yfRzzQ5l3i`g|IQQ&4k5NJL9K=naAtsBMuDMG-Z%L{ktg zP0<^gLK+$(nxY|hho**Tim3lbPQSbR?mq55(`QrHTY-8mAaWTN85faeL`2~)j-l!m znZzOv<2J_d6ytb>jLJQB;WMW26^HN}Luf`t_)-$6`%-A39hJIt6D&|La2b2h#RQg7 z5A5Lq9^(b^T1z=!sG6ZL}c_}C%x)y^B{|3OdYs>lirEeiVLS*AyE z4fO*1ID+Rmjg7V+=#VD|MKZXEI^RVbZ!w20|1J1qOcd?8is#l!8|(JGTk{H*qcVA0 qP?xVi?KJ>So0%d;Vdp6#4`ChCBEG diff --git a/re2o/locale/fr/LC_MESSAGES/django.po b/re2o/locale/fr/LC_MESSAGES/django.po index 58886a6b..67b33e5d 100644 --- a/re2o/locale/fr/LC_MESSAGES/django.po +++ b/re2o/locale/fr/LC_MESSAGES/django.po @@ -98,11 +98,11 @@ msgid "" "to contact us and come help us build the future of Re2o." msgstr "" "Re2o est un outil d'administration initié par Rézo Supélec Metz et quelques membres d'autres assocations de Rézo Supélec Metz et quelques membres d'autres associations de FedeRez autour de l'été 2016.
Il se veut " "être un outil indépendant de toute infrastructure réseau pour pouvoir être " "installé en \"quelques étapes\". Cet outil est entièrement gratuit et est " -"disponible sous license GNU Public License v2 (GPLv2) sur legitlab de FedeRez.
\n" "Les mainteneurs de Re2o sont de fiers bénévoles venant principalement " "d'écoles d'ingénieurs françaises (mais pas seulement) qui ont donné beaucoup " diff --git a/static/css/base.css b/static/css/base.css index 5748f538..168f6c81 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -1,38 +1,16 @@ -/* Sticky footer hacks */ -html, body { - height: 100%; -} - -#wrap { - min-height: 100%; -} - -#main { - overflow: auto; - padding-bottom:60px; /* this needs to be bigger than footer height*/ -} - +/* Footer */ footer { - position: relative; - margin-top: -50px; /* negative value of footer height */ - height: 50px; - clear:both; - padding-top:20px; - background-color: #222222; - /*background: -webkit-linear-gradient(left, red, red 16.6%, orange 16.6%, orange, orange 33.3%, yellow 33.3%, yellow, yellow 50%, green 50%, green, green 66.6%, blue 66.6%, blue, blue 83.3%, violet 83.3%,violet); */ - color: white; - padding: 15px; + padding-top: 3rem; + padding-bottom: 3rem; } -footer a { - color: white; - text-decoration: underline; +footer p { + margin-bottom: .25rem; } -/* Remove the navbar's default margin-bottom and rounded borders */ +/* Remove the navbar's default margin-bottom */ .navbar { margin-bottom: 0; - border-radius: 0; } /* Reduce the padding for the logo in the navbar-brand so the 32px-high logo diff --git a/templates/base.html b/templates/base.html index aeb840da..81304ad8 100644 --- a/templates/base.html +++ b/templates/base.html @@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., + {# Load CSS and JavaScript #} {% bootstrap_css %} @@ -60,203 +61,217 @@ with this program; if not, write to the Free Software Foundation, Inc., -
- + +
+
+
+
+
+ {% block sidebar %} + {% endblock %} +
- - -
-
-
-
-
- {% block sidebar %} - {% endblock %} -
-
-
-
- {# Display django.contrib.messages as Bootstrap alerts #} - {% bootstrap_messages %} -
- {% block content %}{% endblock %} -
-
-
- {% if request_user.is_authenticated %} -
-

{{ request_user.name }} {{ request_user.surname }}

-
- - - - - - - - - - - - - - - - - -
{% trans "Username" %}{{ request_user.pseudo }}
{% trans "Room" %}{{ request_user.room }}
{% trans "Internet access" %} - {% if request_user.has_access %} - {% blocktrans with request.user.end_access|date:"d b Y" as date %}Until {{ date }}{% endblocktrans %} - {% else %} - {% trans "Disabled" %} - {% endif %} -
{% trans "Membership" %} - {% if request_user.is_adherent %} - {% blocktrans with request_user.end_adhesion|date:"d b Y" as date %}Until {{ date }}{% endblocktrans %} - {% else %} - {% trans "Not a member" %} - {% endif %} -
- - {% else %} -

{% trans "You are not logged in." %}

- {% endif %} -
+
+ {# Display django.contrib.messages as Bootstrap alerts #} + {% bootstrap_messages %} +
+ {% block content %}{% endblock %} +
+
+
{% if request_user.is_authenticated %} -
-
-

{% blocktrans count interfaces|length as nb %}{{ nb }} active machine{% plural %}{{ nb }} active machines{% endblocktrans %}

-
- +
+

{{ request_user.name }} {{ request_user.surname }}

+ + + + + + + + + + + + + + + + + +
{% trans "Username" %}{{ request_user.pseudo }}
{% trans "Room" %}{{ request_user.room }}
{% trans "Internet access" %} + {% if request_user.has_access %} + {% blocktrans with request.user.end_access|date:"d b Y" as date %}Until {{ date }}{% endblocktrans %} + {% else %} + {% trans "Disabled" %} + {% endif %} +
{% trans "Membership" %} + {% if request_user.is_adherent %} + {% blocktrans with request_user.end_adhesion|date:"d b Y" as date %}Until {{ date }}{% endblocktrans %} + {% else %} + {% trans "Not a member" %} + {% endif %} +
+ + {% else %} +

{% trans "You are not logged in." %}

{% endif %}
+ {% if request_user.is_authenticated %} +
+
+

{% blocktrans count interfaces|length as nb %}{{ nb }} active machine{% plural %}{{ nb }} active machines{% endblocktrans %}

+
+ +
+ {% endif %}
-
{% if request_user.is_authenticated %} @@ -272,6 +265,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
+ {# Load JavaScript #} + {% bootstrap_javascript %} + + + + + + + {# Read the documentation for more information #} diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index 87825606..7df4a01a 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -55,7 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% can_create Facture %} - {% trans "Pay for a connection" %} + {% trans "Pay for a connection" %} {% acl_else %} {% trans "Ask for someone with the appropriate rights to pay for a connection." %} @@ -68,7 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -79,7 +79,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
- {{ users.solde }} + {{ users.solde }}
From dabf484422544548189d0f2db1d59baed7b717a1 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Wed, 19 Sep 2018 14:42:34 +0200 Subject: [PATCH 035/252] Change base layout Make CSS a bit cleaner and remove useless separator. --- static/css/base.css | 12 ++++++------ templates/base.html | 9 ++++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/static/css/base.css b/static/css/base.css index 393a7c20..3678e65c 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -8,10 +8,9 @@ footer p { margin-bottom: .25rem; } -/* Remove the navbar's default margin-bottom */ -.navbar { - margin-bottom: 0; -} +/* Move the space between navbar and content in the content */ +.navbar { margin-bottom: 0; } +.pt4 { padding-top: 1.5rem!important; } /* Reserv space for icons and align */ a > i.fa { @@ -58,10 +57,11 @@ a > i.fa { overflow: auto; } -/* Set gray background color and 100% height */ +/* Set gray background color */ .sidenav { - padding-top: 20px; background-color: #f1f1f1; + border: 1px solid #e0e0e0; + border-radius: 0 0 5px 5px; } .table > tbody > tr > td, .table > tbody > tr > th, .table > tfoot > tr > td, .table > tfoot > tr > th, .table > thead > tr > td, .table > thead > tr > th { vertical-align: middle; diff --git a/templates/base.html b/templates/base.html index d1306832..9ede191f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -53,7 +53,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ name_website }} : {% block title %}{% trans "Home" %}{% endblock %} - +