From 436fddf5543dc04a35e0abdc12d5e8460cd274a2 Mon Sep 17 00:00:00 2001 From: Abdelkouddous LHACHIMI Date: Sat, 28 Mar 2026 08:17:20 +0100 Subject: [PATCH] Last version of 28/03/2026 --- config/do_dashboard_extended_template.xlsx | Bin 27417 -> 27971 bytes config/do_dashboard_monitoring_template.xlsx | Bin 21232 -> 21228 bytes do_dashboard.py | 6 +- do_dashboard_constants.py | 2 +- do_dashboard_excel_export.py | 90 +++++++++++++++++-- 5 files changed, 89 insertions(+), 9 deletions(-) diff --git a/config/do_dashboard_extended_template.xlsx b/config/do_dashboard_extended_template.xlsx index 794fad8e7d469a15cb5006a8a4a5b2f9f7635272..42c09eaafb75abde3bd2a3987938112872e9e416 100644 GIT binary patch delta 13847 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 F|1V4_C4K+^ diff --git a/config/do_dashboard_monitoring_template.xlsx b/config/do_dashboard_monitoring_template.xlsx index e529a1c5714377b4804cfa8c1aeec12730027c4a..3faab2faafaef4c9250e6106b0aa8c84388bb9cc 100644 GIT binary patch delta 10662 zcmchd2{hGTxc5<+hsZoegv|3yD)UUH#8D#iRA$F7LzFR&kTD?{BJ(`YPR0lsj#=g@ zM27o2=ji|Tzqfa-cfIT0Yb^_V|33S9_Orj=Xa8!Qtt`y7EX+@b*no8=S>gT#3=C>~ z3=9$s3=B_uJ`X2XyN6CrcD$Yr_WAl}k-3WGrwu9ye=^uFDuTdgss>JX_(jGhX-787 zBVN)xc-4hYpqg&GD+ee%!3qy;C1r zK&a2`)ya}r_-mzax9BUN|5|rix|tKM0)aAT9l30sc#N2|rx}FHaALfQhl-HCb9SpE zyb?3B6H37v@;YIgkbrup%#1R5`hz+ysc~*n@XU9b_f_|JgU|u^i56 z=d*Tu&48?u3_)5~gJPrmn5AYg*%Bri$y@Baqba|p1zFXW=HGNvGa9)prQ|1Hh}*>v z4tG+#ef6U%7q9qciuJyKQVwx}MPf|Iy=r{kP^siD<*eM8S>21I6s#+G4AjLu5^tuH zn#cRe4SLK*g!Q4$uXcgh7L12->X&9DC?B=DV(O0Tof#PGk7fk`KBgNEk#9(3}Wz$L?J=q%!<_QtkQ z5N^=rbsf~rw>oKTQV|>0aST^`RwZtKoVyBNI}{DDhGJV(&IJ=X z-6@W$58BA13_7x3rrb=VcvMM8TQ~Ug(HfJ+K18_Z+hdzg`AY5h>T{YKy`wITeq>BDlqp25b+MN%fHi2Z(35%>T zT^AFSGGumK;}^$)qt?ypqF3bvd2!e&O|M-#pulpuFt+^>9u-;dGSgn$wn%8?c(p`^r#f}*#rGk4 z&O%RLd-!zn`wZqiVs}*4*?ZMb&JxaTF)H94XLZrRq@-F#Z}pyo9-VPL&1gy^iL{C8 zeY4z+GncZvZfy>Zc0iY4)BVp9#A(x!Y0;yBKfCz5TCwXp9?8_K(m1@ejuEgg`8E!*QvCYNHNs5#F(#l@wBuDp%`!=1e6@cPdHZXA{|vcxuhy zJZ2y`O!tQH6dM*TP7brxA}--0(7+-lOH4GZrNh8Do&y^N2CP?$7M4kL88GKAQV#X@ zpKmlUB;tBAc2Ov)$Iqmn%<{^$m-q@%>v%heCpEd8Q@J7QWr0;UuNOycaDIK@0VClI zTbd8@3iZSU_CI%VP29t@tG-AW3Fr35Qbz7($q7yRW z6qU+25_YH|IEi402yR&(IPpE?@8n7@Y0WfkEH9NMjw})fDP6IC9yXUCg1z; zGsPW*r;m_I2hSv5;YeQg@cN>*fo!*r)p1EiNyg#cuIlGA1$brGfcN%lvCOlYEXA{_ zxQXrEdl{1t=YS_g%exQPC(C4khT1Cn;}(tV7Je_cz1bVJiM0vIsj0P|BD8hh0yJhC zEkE?BiISG(aQOHffjHNo@w+&yZR-ouucgi&2-6Zpnwez^eFx&gNVHb^aFPy_(x^Pb zR(ozawhCdJ+#Pm*>_QR?$ZIo;iNBwW6C z0zaDWIks^rtNt~tmdZ@U^AX8gZ5B zuJaXlbo%b?2C(OKpD|7FjdxH~B`-4VKIjT#j3Und(&a1}!(-L}#Q1pl*rmwOEpV$V z9v-ES_snn2&p(o;Nh_TZP5Tz6r&-vS&y3Kp>l|69{nFCa>Q-^8V5dA(8tgk+ARzm+ zrGyXhd`9)`HfoB z0vRc#ju0}JzA-QED6El>tNL~@`Kld09Ibb!M}wyHCpSjg+{Bm-ZKP)AYsVt!Me3Jm*%w;FuVgRWng5vl`U)@~l($hVw@#B2c}n7=={Nvq}S8~1!sx?o1JR-;q?bP)4hL5Do^4E7<%iz1s8@3-ARZXhx zA1fXj|gv+Mw zm>8Q*K(XY(k*H^Yb3Av9`_XOJklpmYjp-qvkYXA0hM42XAg`-^%{* zIpK}`%WwMa1*G-Rr^hFZFi1sI`@(}@^z`@9y>6k(ckZu?7TQ9VK@ajp0q!4#*9qP~ zY`=|{^3GzUfabnVP50oLE^rGDMgLJEwK!X5h0=cD`k1%rVT8|by_>e z0SYo&RrhS(dUB-eJzeuoL8HIS7*0}0+!t>%)ELkjaxtoYCugW}@0kt-vnp@PTLm1phfO@Nb07L3Xv=<&FQt#d98+~QKic9 z@U@De^%TWQl}A?i`%vTguqQbDR1_=aeE9A8@KbQuInM8E788Q@d>78>T@d$zyXa9g z7djudM-BsmWjsj{jaJ&fA4ZM-zYntPjmGs1?p#VjZ8lx+uI=Z~Z||(%&>JrvqqfJ+ z@<-RE$qHGUzYGF@9sS=M1pby3c#2x~W86HDPc*UEs58%M|4gU~N&zgE#@~wd|2+u& zPb~U>S(9b2h$ks)fj~6y+^s_iZvdoS-dAi;{=XsIzoIFu=$QbbYVi0p7?x;DII_3?;j@&0zbWc( z=jo3Br=orfiu`ZghjU8oT>MD!fsX3?@Y_|re?1}pzt!Nv-&}?Lw;B-stp+rI?h8O(j7V1r{cU6a zN)?%D^fw}h8SX*|6q{!&TyKZ7bT8JIkVkd_{9V4ZOh@*m0Zrb|^4P`TMq$+*n%ceC z)4xaCD^v@GFlDWZ`AV?R55!-#IzP>v-X#3fTXULcBuG_Cjx2Demn3dNL^AdT=yq-N>24 zJnI8M>$0$Up<4|z14_e<`t@D2yM3H0zV#y=wih&2e03pCHU4Tu7;#{(+~S=z{Rb~v zmwcdW;?uEU!S=q=SKhs34kq03KCm|IhAd*$Vhl3^tk%f5$Fwf{GfQ7xCN7d4-rS$Q zg;5`Iz>@?Q+?MB^EDzUOu{e;QQUEB@Hus87pDDi7T3L0t>72vX2$npG4cCiGADIQ? zMOrr5oWctHrmSiV_|Ht)a^`u{yW59mOa!FXu|G5Gr!+6ddtcxND{2(>%0s6O%+6l% ztn4Oj_6H{ zPNI>oVwHDYPzZJi8et-}M|>L?e`vm3O_72+*N<&Xk=qC4oW(?wzag zLmjR-nqI08xR#fol+yjw1Qv(2X||UMqh!?>=}j0pP$qeYquB#?vMI!(G87jT$j5oj z=Pj#JT0;+J2GS~ZStPs^*HC3R0E<++KXwcjN%Pd(3#E7faL!?FLQ4M9Wu)YFnWV0w zbxn&KpG$_+_2|WDP}g9Q2?J2#T@Q555keua&k+-5H1ZHPzWWLaAv#AG(TKwf=NttT z!bXaY;=_VQfLz@86>=0qdCu^khY5FX&m#3Yi8(T&YvR=6v}ZeM?O4I3wRpgt!$-kQ z%?SOfB)+et9fNd(va_wC%ItwI#P%M_aM3{)u#0RGN13wJDEn$QXLVmf`bJb0^v#H@ z6kEAoTNmg|;NzVK`I@J3(I^M=%#8BLt3=ixWreQ>?k!CFXm%mxLaAPPw;6T7kuT9| zF%ptTJ4>T-s2w#^49=jObp?I&3qfjSgvb-IPdS&oG#YW&svPP=Ax9trAQ>WZG=ukC zO@Ro>tfikb3TUQWM|@5)6zP%=5!T`hoXx>m;(qUJ|Nbp2 z2y8rX+6k0Sgku<1?Yo_wo7p4xVeG%sJ<<2|!A(jS?-28Xh#`O%Q+MDvEJF zXXei}QRUpOK!wzVw(@{;w;sNUirjY5MnJm}HJrWvF8%}0AI4rYqh9hV$nNLUltaUY zyz+7wnvr1^s3O;?V&_4#o1;26K4H8qz=Dbs0LC%JdZ5LZbPRjP#mrk*^Tx*ejW(}c`-Q?De%`M%SpZHTdat^bx$iFDtZ}`EL|OmHkl2Z?J7*UmQ-dLYMA#dv-*RtRaroFD?|uG^CV~eB5o+ zR*_XtS|b5A-NYgAc_%K4?Nv^Rqqp_VMr}?sT|3_cj})yZU;X@v#|QQwuiO_9I=1s= z75`Y)^@lvvBHT8WOv;8jO59{=M)^k`=CS{bOW%I$sxjt;X4N z$YSx6VFP#YyeJeQs2jQ2E5z5eySVo&yJtl<|LehS&%(_hkM;PH+g15H6;@#j~kar+b=3t&mUtw0s%u{_w_79)gXr^f~;Y)u0DEY@e{J|x<8pWCFk=(DGgje z@nvE7@Bl(5O#`$?jfCRbBC1!d0gK>4ALyom)Jura=fi`$-DRK_#gvepn_+JZDf1+YR!3s6VJ($~B7OISy#2;$cs`Z(Ou<63fG=JVzbS9#CQ%zD!o#BT8WB{}u+c#8@^uCBp^-dd662@w&Bc^y3#Rv|eqx+UCP3yL79lU1>k+*6#`oemCbp&=C z&OJQY-4Uy*m~T?tpz^Yja@w4SH_h4B8TZB0Rn_h8UoD)|kmX=9ScME$ZSO!ZV3`&sE^5TxVf5}_Go`FNq05hg<1$+fOA_LOdQB3)7Zu(A!t`__WBQIu%uw&9|87ZS7cLf`0xLl9 zHa)hFq)%$Ai*O%z#=!S}-*+OsG!1y2@2yCfXPdUYl{DElpqzY3p@d z4eovAXX$L_d(Wii^}lI{MND`oFkaA47a*u;k01&lxS1_;Iod}ij#b|+k z*@Xh%N8ismb5*ej;{Kp0hUF8#+9LwwUWVtfyR-^~?4gJnwHC|f-|f>5}O!sB_9A)m(>0ft!p z@I*c=NFdV-U5**nXBO9FY`z@z)dV?l_}A)mS$R5IdMWq&e16NyE%B(3vUgh=cso}a zyyR7XNxp-OSxJ1(2Ev^}c3=9Iifdo;_NLqV5^?3cA5T`iGs}Y-Qn>KgHGA%bj4hi1 zj0SQRGLC@7a84-bdh91|=~FsU6@1Mf|!D`vsqCxTCJ5*#z)<%y$Z3 z%dxy*it+LGvv_W9cmdt7O6q;CQME!N#6vzg1MaTG+V;eojo^1eT1#Rz2G%#x#xz7? zre#QrMhByx`&c2>epU*$`!mJOe)0ZaNo^5f%x>049g6rmr&nsO-l$@M)i=4S_4ulPv~G{VJ7eIn6nM&yF2BoV{Hgt6i*VdEWWRA2(D<^-{pEY| zjED2W;oh=pix{i`Uu(ey|JVRGlSb@)i!EPoqX2fKofkWoNZs5SAHUanDuq%M*M4m& zE=_Lf{s^Nfh0oheZH9-2mCvNotG|7be7xIz+mv$!=Q?3-t++UZM24G1Rsa131cuT_ zjpfD|URR>};FP>clT+{YW+0G5S6L+WG*nUlmUXkwS+Z6B-CtK|EfJS{Icn(UMR1mN z)r`~Kj97o9`$-riEy?xY;MLXEmRQj{e!eI zMnpM$I<$B~YGSOJ8oM`Tk>tHlPZ5Js($rX_=o1Ho$>+5k8?A zP1u#zLoEB~uRlLW(r%B>RXFp7b*4GH84xig(`gDMD=iF2`+1N;I#{!{i}-Xa)3^t= zc=GLTkugRrxgD1fV)TM^N z-J8@)I+RVEHCxNn3aa30{8h z15DcwRKA_*gG3Fg@(-1bDZey1*W+^ch`pChU~nxhIxXll+dgH#b37fvk!u08h9NH{CF?Kj}!Z9ZaarcBOMCYiUcyv&h#gy}A&fk{YHFU{+iur5GuC*ZH0@CZ1$~ zBJ9V}4J-ZD%m8*aF74|$>qasCq9Z6gBuy>L{}80xC&?1n3FPuuQq*D zQ!HSz^1D14v|lSG?>8hiQxmd7z68v6vZd373%OE7UuAi8Q~JUnHN-dJ2SG`+O7bPV ze?G+s6V=kZNKAl%0TUpgg&k;Lru+A2m%vw;f4*#BJz5HwCa^2o*RTKQ_ndzo!q65# zeJB$3)&on|rhsLMUk2Cz{S^y~(w4_$h7D+IV_t)?=-kC*f_do3U}C|_bZ%Z~P{4p8 w6lh@cnwRNNGQh;ZfMQ`_kp9L|KQF?hb!9POFdtnR%r~$qT>Q5gzc&S+4IG2Mde# z5*8LI78aJLJ+BAU#qKc_YRBX0V4wGB-7!O+;?y)}Q~Gt*shrtiv5d1$tJ#odti0;G z(nlcx9gw_k_cu(xPS3qu9kmZ-bMD zub!4Tu$1oe;Y_W^dl50m58lr3{^W^@{zp!ajOS(LIdl^khHol;yxy+9-u&uwd(%bJ zM@g|90)w zl{YxtF@Cilp@rY#DSJX~7o^VQhuw05lO^NUkJr32Cju6%93?_1f|TrJEEZYeSI*uP zdOcsYZ@R6?=5yU5GcwHfQaO3WBm5dY5H$3r1CgOB-Dk45sDEf4(4jZsUh%QMuYi zRB*pMx;~iklVC8?=I147HKpYt=eyeeLrZ%mm3`B@lVeYw7UsDg#OJN*rhH2;_DZw* z^8Mb>4%dT3m}3~%a3HW{w?H_l^74rRQKtFAAC3+--_)Giv=NN>E6=p_UtM% zeU`4$iqrFh@!B)rca=sno7R=tiyO}J!ZpqFzowa~ro|%W#t#`jI+-%IXA{~!A4_Lp z$$}_a3Suu!*+hy@FIYJXrmDZaaf8Y;&@P}`KWb;3glUHV9m{=SihZRev|_~fFkNV6 z)E_$L+Ot<@F(t|$ct5#-V-#{uM7`VFaPumGo~jmKC_N!;_vQZ5A)VatrZJ<&1S^rr zg@Ji`Cw{kR4++aR@Li74FoeNf3Cp`L2$;ud_K17FM}2d->ofCqtg-x|gMFy=!fwXx zOAI;AUb)Egw#j}9fU2P;AA%rqb#8M$xd=On%EbPv7NTe^xHZX2FC5fZ81P;~hP+E2 zo{k%6XQwJ$lq`9v?KQs_gtJR+T7MMZdq<$@F)l$Y_i^OZQ{7usD&rxF&Cj9hWkKxM$ww6qC{_z=+C$@8T(^&3k{;ko z@qX_?49zb#UL(QBk8DdCTK}~@xj0jBe$6C>gaj_M(>8u|y5j6Ca#-rgcyhKPbv{1_ z8$xC;A4Ik+Ndr2bzV!^X)AsQ0moaeY6ffgaPiSs-ONQ^VW10UO=t9A&heD6qYRie> zTgHu-^3AimKg{cW85StJhfRxHS2i5IN^Eq5m>8*ECe?oPc9xp{c9uHLn+mVUm6-5t zcOl)`Q)7agOy)7dEyF7i$BRo^25wGUPOgm868YbEDu9F7uoO!GAW|H`;fyWCd9|e{VIhU{iPKHOkmHshI&ll{XHpKKD5m zZ8ubn>{=D=Zy2NkdQ&DOXR{v$%-_`3`#-y8qGqC^s-|XA#~5wW@Q$b;+Z-tx71Fhv z8k8G34rDRR3Jx`SJ9~(Du6H*uMau_e_3=uimFY5!NhUTC=w@++s1N22_u_XRjk+IQpOHyX@TTI^ghgcyX=s zvHg+!n2J4AoZb{+Et+vs)MYvWA5E!JY%i;8pa1T)>oWXP3cA_)Du1XUk94X#m3lb$ zxPcogw7KXX+ZH_DGI`Q`x)eIZTO#Mf8zw4}{7u7wH*#lOt!wT`K3|~r?{E_srX{Gy%B6!_`RFCs1? zLaWxw>QLF0y+0Qp?Q2aea@0@v>sd|ft`nd0@6zcoNek0z@OQD8}7;5 zKJu$v4|F&$giKs~;}#YHlmB!2VdfG)L%uGHC{+Vt0R+mmzu63<%W zN#0GWbJi^Z!07DVjh`M3^nSo`noM)YKXsE)jn4)ONU2l0v(j&14kSQW1H%)4!tD zrqcs)dA8&-@TA@lUYJ@Yzhj)N=dQL`^|-;1(SK(W&dj0qobu(5B=;jKLBo27t8>*9 z?=-ivt`xsA6aTzzEOLkQ#Ycc^>BPbG?XVayU5ZF5&FYPR&impOZbEtTn*>>HsyH1u zmfZ&jn9x(@baq_ROE)faIH2RWZaEyk%e9^;t#7}a6*!k3tg7+$4u23?8KRX(zuwR7 zWSuc?y41{?ls_IXB9u&2u8l_*-b4vbC$ffrQm8SWW?a{NI>ric@Xv$6eMQQ{MEM_$ z1D{_%Tt zH#nS}#pM07tpY=NHeNC&-6mAJC09rOLXm_X&PP}?7Xq}u>ywT5Z=?T{!A!u06ql3>z*J%F4%AFA+ zC7hOfgemW}g1TlR#;mkJu~_`;{J+HpShtz|r65&e!5~gsn2Is1E2ha>o$hxl+M`>s zn&&?=y|q{R-xiDFPig(Q6E3e^nRwyS#~#HXV}h5*`kjwf>`UD>zY>Fp;#f6i4XZ((8thzxE^Y2lO!gQFR*kt+(i~l7E{#Q_c)r~j*B?wFGcTjN( z{e_LcgMip@(l38SEmYlLd-?B2NlW~W>W9aN%xbmY`1cH#P+=L-1@G`b`M%kNF9k{r z;rLYJ@5hs_J!Klvk}AvwX83V0Cgea(ab&`+G-ae$#&u<-SDNDoue?GcBMJJS>@5SD zuSFG72SdMLg{!TMYsnX8M`LM`H5e(|(s<|a`dI^AhnbQT_z!$FnOJhtuJ4(H#M&vI zn5-zLPMY#d=0Md1n&6JlB^EFGj1k_3Y$FWg59@qVo2kZ|l z{$7z}4KQSX_VI8ODo>Nb>^d_wzb5z@D)JW<#GiLB>*Y}aZR%h}c8i%>bQ7F0NJ0+p zP3++!w-T6cu95Z3h_$pLM_9+fa%NE2=3Y@>fR^Sx;Oha>TbbAhIddMN!1M@b_~=&G za;jGBp>M&q>9Wen<*~LK+qXnVtl-yO+N%(>CU~N`E%R1%oq@h?Hzw(PG0+rwkg1bt- znx;_J=gM{10`qZ5y~tM{8ef-v{Osk^H0I)v-iWJ499KSqthD(D*GAryoL;q%yAX{^ zd^~oBW0++D*jrcg)Q@juS5p+FIU+Yng!HlrMAb>nsw7;Xd?|UEoPnO4O%Xg)nOqnG zi3ed#U4&KRqG5^N*!%)N;Zhq>{V7y^2ZBl;_YzM65jy=)bozsBbhva7$((`;#ip$C zKon*!EfnN9j*sO7-3A}KKpI^x2R_~@fdZh#Deq%>oa zH!PmfyeflYeV+@(x}sm60S53mm60tA8t|7FD8M-{Q!ZmjT7RxQbP+|;NG*yau$sOg zu>i>Ix~WsbWtv~eM5JC*Bm2{|C6GV!nfQ41ox1v|n|QE}OB{@TI(HV51`on^p*yU# z_7)?mPuH5_QMDB0s~j{yXP-snMZLf9guB_jq z0T_O}qYn&pzgszIp$?#M3lMuzw}4|sIhay&+d1X*qDy^DhbncZq>dm)9-oPM1nANH zI^RRdW3X)l55sSLQ&vO}ieGyt48MAF7_sdOR}MZyC-{g2L+>~PhF)2Gm=ZvW&Tim0 zzn^h1;#iyE&=p(Q+Lq? z&_cqekH;BuNYhaQU1elAW@KycTZXzevVkpO3jG7M=#6+a&j<(I+jmYRbbfs(Eo0qnandxkhxa zhbso##t2lsl*~DQvP$YG^wLE4X_|8Aee~SbXPO;hl2HT&t#_jd&4aRE&QmlEkt_^J zEFcZ6drj!xen!UghzAWb8Z!-ltKH3{#b(szFdrVkFay(7f1^z=)XUI>c95sTTS7xjF5hL? zB_^~edVZtL!k`7lZD%!i&~T{?f2*P#19z3%=u-e%6d{oqQ9!6MqUd>%YvhI!MW}2< z2&O&4Up}KowTGH-4#j)0Jr-YBEaO5@$*tpNTgS7Y?kD#!bd4IE>>JWp!203;_CK>q zZE_8i4{+0f4l?$HwAH;M`2=iwa~cchU%DS8%gu$qo2$phfhCtGQbh@BFY$4uHiO0v zc)N~7zV^^y@Y7_NM zsQqx>Ar)v2fHmJ2%cUD zG)hn)7C$jq$7^Oah2&6Jb)Xom_R|=smxYZua?nsoVrnA+)D4`Wm4c9{bW)~%QlK2|1ZN=Y8!p-+Ey4;2A`A%^X!H}M~4 z$(RN!5+0%+#X-oZqOfT`%`Wh$s|G?W{vr@C)BhT{c(@_H6Dtm#^7Wj`WBg)!dVAW4 z@1Ht~-x~@F8mK_K<6-lMG;|f&4^iZ~rJsvbdO&&a%C2GOfe6 zjmV*mCTrNNtAD++^wD(}w3elBHMe=a&?a1z1QxR(s-#p;N4h}2 z+{}_3>e68KZ#Nrec6Y_Jn!&ti}(sIEz}K;x4tutL3ky3E1qU)vi(y+163+QKFo zK#MRzpcgiSMM}saRiXXWtNZw^_$F$3QOfTP<>^hIxoV3b*Oq8xY}wEk(xIN6yv1Gc zpFdWptq5XK@4vMruzS!LX)LY+2PUSX$W$Nf9q+*eqspefAvu%fA4jK;i=Hk4Nk>C1 zC(YKBi3dq7NVB@i8irbUvVxc8S*7H8VQn45iN$VfT|M0BSht(_G`HPp%``2I#8(*}p z@=l&!*0oPsoUaL5ZdfK(>1hB`%X!;2{12TPghzb64U9;rm{Pw-E}x$Az!>o0^>mrG@%wxglI^Yr;seajWHu+Akb``c|rTCBLsh>Be~_ai)Z4B2i>?hZGR3gf;Uudl1L&+>ut~Bk`$8xhEPglCI=M7H z0J+09TK`n!+L6cZ+j#M~_hOxoMrPhOKk2_jXK>GtuLHr=p_dNH?4%u07|3cDVoL0# zJ*>VpB+jg?=ee4)w^7lc{AG&vmx2&0bIDBs+RqQBG%xOuja8n+#vO~#6|m4t+VXMK z+j=-(k`M&4U%!f1j}G+1rtXVtqm5($@pQ}{Tk+RWj|R3j!?ST0t8c?DM!S;CHn&gc@H*As7rR)*ensgHW#g4_mOMtM<5~{-l|qeU zlUHrh!!%2?->aQu3IjJo>m}U84_V`llt&ApA*5!WHu&Z=Bof2>;^q+Euui+z*R0Ay z^PqCcNKYdgFC%~Evv-mR+floYBWK9K70mqo+`hD7n4*a z?xheO5oPjNq&QsP`zVx9X_+~u^-#6`UY!Ttbx#OZU0%!0Fo8pA4J8Nzu9Hosg2UK} z7i^0dqAtWSM8ssMf0eA0k^dtBC&_5;i#E@VzHPvlli+!8VA}k*SIjBfmApEtggo%H zyLC(5hr^$?T}h2xDm43*gCdgz=)Se>MLLJRmTvESs-J?k-u|$&e#FzqISeTtLBhiivx|Ga`1#F`$uh;tHc3;zICe?f_Xk-59F=x6n#Z(3}DS|)dJ#iaAE*nN>>1p*EkQ0o6-#e~)1MC3- z`wiAA9mUP;Yfs0Ul{eLt(n3Ce8WOv^zk4RG>?c1VOy3_~x&567(og%qEMB`L&PH%F z258N-w>TxAPSCRQgDNL~(XUlBjZy1;SJ}=iUdMHZC3o7gtGAfQbL$A^8EcxzJ?&2| zkReK(ukL#bvMBPfR$hRjKDt!>e!C@81Yd4Tb70B~{D|!n=B-l2>s%8q!%IuGH;LA# z_|%QXMmg~Vt~@hl4wjWOtBR3w!G7rNy}7cdJM}9 z7EAvyHX!mOvg4i>`wIRo;!oAWp0$kCruVf!J@l!^jv0H?4~L{I(mf_t%Xfz!t(IK| zNQ)n&4|*aw>7Eg$caa}2ms%u@r4F*4hd8w!PNsbnVS^crk$s-yvl8k;6irE<$0SyE zO3Ms=>^Y3NE%P|9qKC=r4%ytBj`tDE$C>twsTIi)Y-HLVcCVm~lvZUPhb1orqG~yr z86G|fS@wqCsdJIASgJ8Ed{d=0p5ni`1sG&HaVGLdhs&OvhGah2!X4o=B&fPpHs{d> zoiU;6lbTt{W0dr?7iM-^(pHE(^ouyWH1J%erM`2GPIHZl0vH7q9w~$oou97_;fhQaT*i-ZAXFf1=*_?gCX>h{a*s1&+zB+yshy z9mQ`*LU!a9Xwn6Uo7P@IiB5k`Y}JjrNxlq8wCJkmtoR}26w1SMmM(1J1CzTXv|j4c z(b1kiUSE`dH#3RwHCB0q-;aym6QG9jk_!gqv$)PS!GWvvuc2Z)jY&Kw-*gL)duo{~ z9*!qg>@(B??M@+@$-{TDVpwc>FOu6x-VD~a`(l5t+p@qE*MLJ=@?O}91h?hOjF^52 zwZbiIz|`)`ZHks@{9_WxrUUXx#ASyTk^3^{g)z}}R_%`>9W-Nw_r`f0%2u7|7a$_b zXB$f(bZgx9Xd-H5>HQQXPJCgw3H;utlwv2Vt?YDi$?#uaHu<9w0Bikpz5jU(2)LXR#wHWrrO1uU$q gfA0tWgdZoYDTxh>^U##QPKhhiyn~maidyi00KeEM{Qv*} diff --git a/do_dashboard.py b/do_dashboard.py index c44df78..cf25ad4 100644 --- a/do_dashboard.py +++ b/do_dashboard.py @@ -1525,9 +1525,9 @@ def main(): console.print("[green]✓ Data saved to JSON files[/green]") print() - # === EXCEL EXPORT === (temporarily disabled for JSON generation testing) - # run_normal_mode_export(excel_export_enabled, excel_export_config, - # requests_mapping_config, organizations_mapping_config) + # === EXCEL EXPORT === + run_normal_mode_export(excel_export_enabled, excel_export_config, + requests_mapping_config, organizations_mapping_config) except IOError as io_err: logging.critical(f"Error while writing JSON file : {io_err}") diff --git a/do_dashboard_constants.py b/do_dashboard_constants.py index dac705c..48f37d9 100644 --- a/do_dashboard_constants.py +++ b/do_dashboard_constants.py @@ -75,7 +75,7 @@ API_AUTH_CONFIG_TOKEN_ENDPOINT = "/api/auth/config-token" API_AUTH_REFRESH_TOKEN_ENDPOINT = "/api/auth/refreshToken" # GDD (Diagnostic Order) endpoints -API_DO_WORKLIST_ENDPOINT = "/api/requests/worklist-filter" +API_DO_WORKLIST_ENDPOINT = "/api/requests/worklist-filter?role=admin" API_DO_REQUEST_DETAIL_ENDPOINT = "/api/requests" # + /{id}/validation API_DO_PROFESSIONALS_ENDPOINT = "/api/entity-manager/meta/modele_fr/data/nodes/pro/nodes" diff --git a/do_dashboard_excel_export.py b/do_dashboard_excel_export.py index 3e76578..a87c62d 100644 --- a/do_dashboard_excel_export.py +++ b/do_dashboard_excel_export.py @@ -1172,6 +1172,60 @@ def _get_column_mapping(mapping_config, mapping_column_name, source_type): return column_mapping if column_mapping else None +def _strftime_to_excel_format(strftime_fmt): + """Convert a Python strftime format string to an Excel number format string.""" + mapping = [ + ("%Y", "YYYY"), ("%y", "YY"), + ("%m", "MM"), ("%d", "DD"), + ("%H", "HH"), ("%M", "MM"), + ("%S", "SS"), + ] + result = strftime_fmt + for strftime_token, excel_token in mapping: + result = result.replace(strftime_token, excel_token) + return result + + +def _get_date_format_mapping(mapping_config, mapping_column_name, source_type): + """ + Build a date format mapping for columns whose field has a strftime-style field_template. + + Args: + mapping_config: List of mapping config rows + mapping_column_name: Name of the mapping column (e.g., "MainReport_PatientsList") + source_type: "Requests" or "Organizations" + + Returns: + Dict: {excel_col_index: {"strftime": "%d/%m/%Y", "excel": "DD/MM/YYYY"}} + Only includes columns with a date field_template (contains '%'). + """ + if not mapping_config: + return {} + + result = {} + for row in mapping_config: + field_template = row.get("field_template") + if not field_template or "%" not in str(field_template): + continue + + mapping_value = row.get(mapping_column_name) + if mapping_value is None or mapping_value == "": + continue + + try: + excel_col_index = int(mapping_value) - 1 + except (ValueError, TypeError): + continue + + if excel_col_index >= 0: + result[excel_col_index] = { + "strftime": str(field_template), + "excel": _strftime_to_excel_format(str(field_template)), + } + + return result + + def _parse_range_dimensions(start_row, start_col, end_row, end_col, header_row_count=0): """ Shared utility: Calculate dimensions from cell coordinates. @@ -1485,9 +1539,11 @@ def _prepare_table_data(source_type, source, sheet_config, requests_data, organi column_mapping = _get_column_mapping(mapping_config, source, source_type) if not column_mapping: logging.warning(f"Column mapping '{source}' not found or empty for {target_name}") - return None, None + return None, None, {} - return sorted_data, column_mapping + date_format_mapping = _get_date_format_mapping(mapping_config, source, source_type) + + return sorted_data, column_mapping, date_format_mapping def _resize_table_range(workbook_xw, sheet_xw, target_name, start_cell, max_col, start_row, num_data_rows, header_row_count=0, target_type=TARGET_TYPE_TABLE): @@ -1627,7 +1683,7 @@ def _duplicate_template_row(sheet_xw, start_cell, max_col, start_row, num_data_r def _fill_table_with_data(sheet_xw, start_cell, start_row, start_col, sorted_data, column_mapping, - value_replacement, target_name, sheet_name): + value_replacement, target_name, sheet_name, date_format_mapping=None): """ Fill table with data: group contiguous columns and transfer via bulk 2D arrays. @@ -1641,6 +1697,8 @@ def _fill_table_with_data(sheet_xw, start_cell, start_row, start_col, sorted_dat value_replacement: Value replacement configuration (or None) target_name: Target range name (for logging) sheet_name: Sheet name (for logging) + date_format_mapping: Optional dict {col_idx: {"strftime": ..., "excel": ...}} + Columns listed here will be written as native datetime objects. Returns: None (logging handles errors and success) @@ -1676,6 +1734,15 @@ def _fill_table_with_data(sheet_xw, start_cell, start_row, start_col, sorted_dat if value_replacement: value = _apply_value_replacement(value, value_replacement) + # Convert date strings to native datetime objects + if (date_format_mapping and excel_col_index in date_format_mapping + and isinstance(value, str)): + strftime_fmt = date_format_mapping[excel_col_index]["strftime"] + try: + value = datetime.strptime(value, strftime_fmt) + except (ValueError, TypeError): + pass # keep as string if parsing fails + row_values.append(value) data_2d.append(row_values) @@ -1687,6 +1754,18 @@ def _fill_table_with_data(sheet_xw, start_cell, start_row, start_col, sorted_dat # Write 2D array at once (xlwings automatically maps rows × columns) sheet_xw.range(target_range_start).value = data_2d + # Apply Excel number format to date columns in this group + if date_format_mapping and len(sorted_data) > 0: + last_data_row = start_row + len(sorted_data) - 1 + for col_idx in col_group: + if col_idx in date_format_mapping: + col_abs = start_col + col_idx + col_letter = get_column_letter(col_abs) + excel_fmt = date_format_mapping[col_idx]["excel"] + sheet_xw.range( + f"{col_letter}{start_row}:{col_letter}{last_data_row}" + ).number_format = excel_fmt + # Logging num_data_rows = len(sorted_data) logging.info(f"Filled table {target_name} with {num_data_rows} rows " @@ -1732,7 +1811,7 @@ def _process_sheet_xlwings(workbook_xw, sheet_config, requests_data, organizatio return False # Prepare data: filter, sort, get column mapping - sorted_data, column_mapping = _prepare_table_data( + sorted_data, column_mapping, date_format_mapping = _prepare_table_data( source_type, source, sheet_config, requests_data, organizations_data, requests_mapping_config, organizations_mapping_config, target_name ) @@ -1763,7 +1842,8 @@ def _process_sheet_xlwings(workbook_xw, sheet_config, requests_data, organizatio # STEP 2-3: Fill with data (grouped contiguous columns) _fill_table_with_data(sheet_xw, start_cell, start_row, start_col, sorted_data, - column_mapping, value_replacement, target_name, sheet_name) + column_mapping, value_replacement, target_name, sheet_name, + date_format_mapping) else: # No data - template row stays empty logging.info(f"No data for target '{target_name}' ({target_type}), leaving template row empty")