From 9a4d7b6ae1c85c026b1d23d8977765d03073595c Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Thu, 29 Jan 2026 10:06:39 +0100 Subject: [PATCH] =?UTF-8?q?```=20=E2=9C=A8=20feat(DevisController):=20Am?= =?UTF-8?q?=C3=A9liore=20la=20gestion=20et=20l'=C3=A9dition=20des=20devis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrige des bugs et améliore la création/édition des devis, incluant options et lignes, et la gestion des signatures. ``` --- .env | 6 +- assets/admin.scss | 6 ++ migrations/Version20260129083756.php | 32 ++++++++++ migrations/Version20260129084026.php | 38 +++++++++++ sign_ludikevent.jpeg | Bin 0 -> 57549 bytes src/Controller/Dashboard/DevisController.php | 63 +++++++++++-------- src/Controller/ReserverController.php | 3 + src/Entity/DevisOptions.php | 44 +++++++++---- src/Entity/Options.php | 35 ----------- src/Service/Pdf/DevisPdfService.php | 24 +++++-- src/Service/Signature/Client.php | 3 +- src/Twig/StripeExtension.php | 8 +-- templates/dashboard/devis/add.twig | 10 ++- templates/dashboard/devis/list.twig | 2 +- 14 files changed, 182 insertions(+), 92 deletions(-) create mode 100644 migrations/Version20260129083756.php create mode 100644 migrations/Version20260129084026.php create mode 100644 sign_ludikevent.jpeg diff --git a/.env b/.env index ea73d91..31a7bd6 100644 --- a/.env +++ b/.env @@ -83,9 +83,9 @@ STRIPE_PK=pk_test_51SUA22173W4aeFB1nO6oFfDZ12HOTffDKtCshhZ8rkUg6kUO2ZaQC0tK72rhE STRIPE_SK=sk_test_51SUA22173W4aeFB16EB2LxGI0hNvNJzFshDI98zRImWBIhSfzqOGAz5TlPxSpUWbj3x4COm6kmSsaal9FpQR1A7M0022DvjbbR STRIPE_WEBHOOKS_SECRET= -SIGN_URL=https://a292239e6756.ngrok-free.app -STRIPE_BASEURL=https://a292239e6756.ngrok-free.app -CONTRAT_BASEURL=https://a292239e6756.ngrok-free.app +SIGN_URL=https://790f740ccd60.ngrok-free.app +STRIPE_BASEURL=https://790f740ccd60.ngrok-free.app +CONTRAT_BASEURL=https://790f740ccd60.ngrok-free.app MINIO_S3_URL= MINIO_S3_CLIENT_ID= diff --git a/assets/admin.scss b/assets/admin.scss index 579716b..141db68 100644 --- a/assets/admin.scss +++ b/assets/admin.scss @@ -47,6 +47,12 @@ details { } } +.ts-control { + .item { + color: white !important; + } +} + /* --- TOMSELECT CUSTOM DARK THEME --- */ /* On augmente la spécificité par le nesting pour éviter les !important */ .ts-wrapper { diff --git a/migrations/Version20260129083756.php b/migrations/Version20260129083756.php new file mode 100644 index 0000000..3cc27d6 --- /dev/null +++ b/migrations/Version20260129083756.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE devis_options ADD details TEXT DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE devis_options DROP details'); + } +} diff --git a/migrations/Version20260129084026.php b/migrations/Version20260129084026.php new file mode 100644 index 0000000..e4b54f4 --- /dev/null +++ b/migrations/Version20260129084026.php @@ -0,0 +1,38 @@ +addSql('ALTER TABLE devis_options DROP CONSTRAINT fk_42db61dba7c41d6f'); + $this->addSql('DROP INDEX idx_42db61dba7c41d6f'); + $this->addSql('ALTER TABLE devis_options ADD option TEXT NOT NULL'); + $this->addSql('ALTER TABLE devis_options DROP option_id'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE devis_options ADD option_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE devis_options DROP option'); + $this->addSql('ALTER TABLE devis_options ADD CONSTRAINT fk_42db61dba7c41d6f FOREIGN KEY (option_id) REFERENCES options (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX idx_42db61dba7c41d6f ON devis_options (option_id)'); + } +} diff --git a/sign_ludikevent.jpeg b/sign_ludikevent.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8f9c062ec1b7bef27faec5121e18cf93b606f577 GIT binary patch literal 57549 zcmeFZ2UJsEw=cQ@Ap&BgD=i{jL_`IYl7NbUh+qQ*B??Ft5K(C%0TGcdBA}oIMT)dY zSHOghib(GzBvE=Kp@cvRZ~wo0&Ufy+@4b8OyLX&(zB9&IVUs;}S$og5=9+8H-*2vL zk8Do^d(NG;JPYvf0DuMf0k%nigITbbI{;W)0|x;B*a`6Rhyi@y9uN2dV!VJIf7=HD zRqz`C_;Psu&Z2YdlOKHeRC{QNt>NArY(=Ybuf{9=karUK#@Z$S8o{)E8;#882UDzRP`|mtRo$p{Sy= zs=B83)91S8me#iRj<4Uo_w^494h@ftj*-ZeU%zK&=jIpaE30ekj1A`I)?adgt@7W* z0{{QN$|VZQ#k*q%-ww!Ma`Es6{Ux~Q4t_-)0Ws5ykXr%b2aZPWlsJ|0w!BGD>DVQj zq|3ctAt~kKBo+E!qWw*>|24rL{clP3cftNeu5sWr!27qt$IHvd&&S8dFTf8Lft><> zm7PL6|5k+lsqFe&+5K06{=IC2m4K4+?bxvc0{-n078Ks||GR8Yg34vPJqGOJ;{lb4 zPZU4^9QM07b>P3Y|Lr#5+wS?VHvB)-AHMD0|7yek<2LO3$7#c^eUhEQ-EA^Kk5HPW z!5wz|C2NKn%kEd(8A(%mDQWji4xO6z_=1{eX>vzkA{ZZQnEhY_zfV}fw|D2uZG6$? zB_jc8&vuTs_kaBv8V79k#i{4;{wLd@+x`DA9l|%OJr+3ap36GLHbCswLRklrvNSti zW^P#_2?2K=OUIm`1Z@MjIQ9lpf7(};af0*ZH}lrJ%}`7fUez*c7NTeeZh z%^v}ajkwYCe8@Be&9==(5M{^7#vhiw)Z?k3BIs<5$oUn*3@mi7?h7?TLXXoA!+@XG;ltPU zTL~gfk-nnJPaCm=EaAnmU0}4IiS&LdI6u+0YJ&OD?+X;x+FGA@z6vsW!y+;6G09 z70x8yjwSmg31M4Z-oH0i=UbI#><%Cy5-?RB&BL4t1Dn{kw#@sS)}r4}6<)QW-wgjw zZmBOsNpA!EM$A}}G5LhiMN)CNWf=#_tI`YsDFijWOCx(fY325B}n118f z(3?^L=NwbjekN*gL#+iTic2u!ClMuc{bky*zCkI(?nLBP55&Vv!j{KOVsc{ImaniV zD1(uS5(&f{b!z?Md{!uT!8%0yDZ&#InJsDWzbAO(Ooivx`wW^OV#j1A!0^^2X^Uf; zED>(nyDWxQnWNesb00i*)XFB`6w;6z&UV@cnl7RR7xoCQCGTd&+g`E|kcHg58_?9Q z&bQVa$Nqs~Y6Lw|-UgoeHz&&wLqi+QcxeCUm7sl@|kIs@Me}?Kag0HgY_|_P4 z>}Eu5LA&ho<_`2vwAS@C))_^FLH7XW4soovl+BT5gb*5UcaOZX{>!{y_Qd^= z*ajX&p-%Of#CISnhZCq1;hT3#&(Lr<;{Ycq0`2lP5NY>m8+hDpMu$YxH}K;HRx6x` zA9A35pmaniD8X5R>oy=J=>&s0H9J-RxMZ4)dnuqfN8n=zGEM1>r~xW#fzb5BX6mGD04O|7;QefdSOw*+j#UT z-)fG?IZZNB9@BIRaT~ki`&MXhopI1rIj!_pvJ*dMdnEa7W}W4=sh#vi@?}}f=;AcI zyznerxHL#gG?GIT{I$D^hp|jmn*M}WL@CyIMy zP8wMu9rXYyPhykxw0MS|+8I zBzH9Hi6uxbbg&7>qJoxQ8u*N1FJze;|CKN};CJc0iH@Ft(LQW(n*-A5E{wW5hn zA1>8;oy5D~*r?O^J>1q;bMZAD84@hc2xn^1exB%vY>>|Lg6{2jB~s#}8CFSAW(|Kd z7dxx>E}HM-UJ0JfM=qes=Q2BgfAWU}8}uRTZhE8S$o>BLD+Hsk|=KEQ;&nRwsj1FjwQ zk9_d8G~5#{36=b0522(;Es8BdrF2W3_jPFaW5j}QZZd4r1o5oc$z(d8p zLNyd3-0sVXBSTO;oVQ##Zm)t!avPctzp9}9eC4N2`b^)gjodWo{;2j)TS&u2GYQ}y zVB`6ZMjUd6VW5u*3qIE9c&Cn#uwHL1(ERfvbDt>W62$6BVf8|Q9=9kUIzrKb;9g-ohPKGo<&3S_Fo#1uCm9OmTX zkS^?yzBl9Df#{2Cd~sR45k}Ia?j-_Em}LFpp)-UAf8|pCx+Iym`v@HG_7=O23$l2w zE4X*8=m;gKa;XoZ1fSoGEl8ERQeY84i|xgQPxWBi%txtEovuK5UO~D3v_gh=s95wz`HV6sr1~;#c*&n0&xjtJrq5FI$QgB&U(?5%Go7mJ_Ux{A zKMB8SJY2qv%u|5U5RV)9-kFlR1?KIx;8}OxUXt}}R_DtP7+wg;fp)`qF-<4e2%_FT z6x>)=TL$RWv8@ba$3|zL8y}rIKf9+bWrZv~*yBW?$3yP>}?QM{LcWo~HV#E%+ zXUYcydY(nNv4)-1b9TsG>irkRkc=f;Lv84KQH9K)t52;xK8$zz9#u$`E4muF73FmQ zv3mqUn=t)mYX1ORq!4AvNjJJMOC>^eLuA@sZv!RepH-fnMbs-8B%Q%Umy%Jb!Y(sLEWI@>wFxV5uN}^EA-atYJLTpqu zdtmn=>XkoF#KI~Pc0H7Pm;>!8@6Y@P3H%V-|L(ZsZ`3V{_O4)IlLk66;lYXHiKVbN>;!N{X0C};Qk;co;O<_Y0mWTm4wCQRE< z7&0_z8>rHz7L;~QFOOQg(fnJ+Lu6#P0jVjot{zrNP0?MA}ssGP2Q0Sna9Ke1zL& zhYeU2lDbY8bU)eLQ%X?h-d)){?{dOWcm|nY-LIUHdb#DVu#Hj4UwCCs0XPJA7Q^7&`%>zj)#4P!zh zVr-m@TN(|H_03=G$26P0b>qJ%M?_C)yNNu9oVOLIWg9uQ)paO{GX*KKiNqkPT`^>K z^)iC=aT~bv#+7S^7|my()>v29?s7xCIcJ@{MnFI!jX4a?yvoA_%J6he8i_+(rK2l- zx27{cVrgq{!eF;Q(=ahnnC@0>Jz|-}@cbW0o)&<?)fI4UP*pJ!{;!!0kc8h-;YdeTpmio-h^UWG2?vGh?eCibuq1x}Na-|qwxl`V&b%>N|n{Cc| zbuhZu@=xd*?g@Gqrb)}D%@+(A$;s_3Ntyz-_)i#Yx7VR>T4f>T&n<;-MQ{~zShkP> zFw{accFUps=v&-jL{)XA$k}O+7DtK3msOpozgv8r2uXM!IQ$tma8>9^KqN9v9Ni4s zE=2R)P3|#_9%gtTPXjD_!iMIkMtPz zmNG~z391p#YZX^_3m!T8(Rk;9h{G4p2L8(|{U7DZVg5aNmYhMW`f(p&FMn-!i~Z47 z4N0ep)PFs<0fg9{%nz*FOd=T<_XjP=Z8x|{SFPFGf+4Hj7<12r?mDd?A47)v1(?9j zp?e9{gcigo@j}wLU0O9(5{asjkh@;tkO6AewB%KUCr3p~P_nXx7A(xIHwK!F@VtE1x%VgKWWC+u5iBehqE#1*un26(_ z34_GNqa_)_*;M~eYYKx(=r&|kL7Sl2a0fBj;K}gGFr>(b^5~e2y})bG;rZMU#4<&R zGd;YAvkmC^uil^itk(6(?p8A6asWq@LJ$LA${H=g`8W>~zONNX7GXbrn)J%OeYBhN z;Et>Dr?SOH80|vxXkg=Taj^}lgRYQ&*X`3_nevy_y+JzPuVK!yU@cR-XvvRD%`&2^ zoQw}l1pFRz>fog>MF;`x9|$?n5^V#Ly2{8Hn9w0KY`$M{6!FweJZf&Xvk7+o>Ndc1 zPaba}?<3M-l)7N&lP8}OTNnkmAVrUU?3CO}uJ*bMLjIR6z{$szt@`E714QhUCS5JT zzp3;1Rzga12i|2LtTcSzboWRL!-Xbmj)>vHyy71yAo^6}yIwt=v(gJh+Fmr-JES1r zQ}y0rt;=An_cG6!BkykRemTbPLuGpn*a9d1iA3gso@3*|M@2C0FEWG5KyZsddwfS1 z5mQ?}zTkqO^p#=nH0&;T?Y1Vl6@49(%$9wRGNn0JPrrGnlHTD|ojzpSC?|NOjP&R8 z*Nq%uG?Wg{pxEs4LLcgN6B}6=>b>6F`0GyEX&$T}Hu`?`X393OV}<@FkMzmNm8H%c z3diqfA~DKRPiJRR&!^5lPFQL6`?j{je*VkD~PFbcV(t@UUU`8`%avmg$ zPoUE4RIx19{CmU$y~7VZYL?t1;BN99OX~L3I!8YK1BX{ousO0$qmO-1%_jbLGA1wp-MDAT=YjcVSezGiIbIN@j zt&?;ze38U**C-^Kjo2Kx#|LdF30~4%Ba&)cpuB7q+810D7dF4gOXl{w=qs@%hXXnd zAGjNjta$Rx5Jo!~+BEwnFJe3Q;Ae~s>db)P^9?5gXDM<#-9fTK$u?Y*y8r#^%m9U1>hE@Ak$HnoZ71s4sDI>o7iL+5>b z$WVbv<;-7Fxh}~0r2xegY2mbehbAp>eXtm~Q4d}<7-mK%KJjpRqwiRgL{?Ks;@QuN zGLi54dvp{Xv22-|2|SRDDGE+C>E-cty;xhphkJ9dV;guYvwFjo@suf^qbZN<*pe^5 zP&D=!bh4MXR(Q z{po!8+noP92MqjW4s_t$`8akxq8dv5UAhf?{lGG8uCEKnb6nWlK(K~=2a$G}8qCH* zjr2($C-o;w+d+Sb*BjuRo>1>XyPA`^>!g(Xy=E5Lu>U8>1?^+Y=2WXeyHPECU z#<*G?*yRlUbO+OIeGY_!UO$O|7u0j!;vo(mRP>2H*N)OY*e{=q22L5qJ$@GlN7hSL zFqokrzS^gaVwwyvZccI`&X7b9(KA*{+XmKD%PKk~G-@V2(5BAwm^tS<7oM|QJIY?v|%Y`6Cs?<8z zYagS*N>xe+I9V8vPwnEQf+vmJz(;EwcySIC^mAjPxb2v=tM{?&#BHD*49x%U2Np*# zq%1HfCvK@ufv{rJ)xU1c9`Hh>j3&PGZ?W1I-X|smSF!9*?y^9 z1yR<%ZJ_r`A7SNhF9&*gPy9Jp%v@G*AgH)@gugEOt185*HR@ys=Ts?%ISB-VD8CVm z0qWMf;`iIYFMqDS`Tuypxn&#JMP$Lj+VyC&T%o^igweV{A90x@?hi&{MWDJT_CS&` zElt~iD`M+loelRa=t>{LWC7|H^J;O#{bgydz}bB5 z1F){>VDtx;5cm5S9^F4JymJH7t+GN`le2&AjR8rHk=d)=*y&N%ZZ@6pIer^31>FK) zCuV1}y>G>^WBIEuVl%3UT$za{D}BHGYG0|qmX7%UMrPf^G-(pt!>&2|i@XL$Wc-wZ+XFy8GF1dkh z!6Xud@P|iBXIqjbMtmA`o^|*it@>I}-|=RV83(L8s{f7t{fh$rS2xJ^ze}>o`5xZk zH1;iK+cY9_YA2q)(JEqj==h?Y?;C@5%MwvZYwW7Jlcpm9KUYM-3yHx4kkJc@&Bt5(yO(a%5sJJ$-myX~?$sUNd zHOac6yTglTjUDn(Jr@aSmM~1@B?raW>kRJ;p&jlx2V_C(ja$wRbKeB&y5eGViNuK2(c1^JDK3wq}Nb4O=3f(hsXyFhDk8pcCP} z67I8?cZQZkyyiP(Kb~GA?e+_06lvw+;;uUCKxnk$3gRHZ5v1F+5@NVQl?KW2MyFl#oV4vfz1g#Ss=Bd@b%ERc ztn4;3Dp!56Ys|iL%Z4qs$Z)FE3Mjp{Fh-q-+IT*-5NP>n_T*Tw=Zc{WU#EUB2-IWQ=eo zk5hwj8<9T7zS<+sS!|P>hE?fmRc5$FUd%?+i@$2}nn%@X#rm2}=d+M!u);1N++K}3&Vsd{ zWLD?MVIIzjZwdKkfJYRGUtMCzWsggC17SJ!$u;J>{bno}y7MEZi0MT7t<-N5&pv2~ z9hqe~HP~I_N(ZC$3MC#=`0Mj9-9+&?95bZ*VR4T_%!d z*z!C$i|qbIAjLap$^NGMs~E!r$;CQLhQp+S2!c0}scxQxx*P^ttFg3#R$o13e@#d3 z_dVlja?+~>qo0y5;2%{ssL?hUu{2n#Cibsj*}q8(NzN~lKQmAmz0_6Y z5Mr0&3*40Wrqs`i-=wLvB|jmGA5t1<;3peu-4i_fn|1vAa`L5D69`cgh3Lq6E9=Q6 zpR7TY7fA#f#2Bh|Em&G)#J_ykF&riY%opNbqMTSB=*}s~VZ1UkK5zWR&olS-ZH0y? zt|AeO7~19T(V2;lwA=Z$6r*tB(i^y?K1cs?4zzdS7&4v0pfP__;BYZ?w*fbA22*U1 zrIH?gEVa!T5Q}(hWJse~_AH1APhxMptpvxoS=VWm);$Sb2XeLn&q($n zI3sfRbuzg0r`tf>A|)?9mar_cyEoMnF?mQVFPy-ulY!ON^iAt`#xD_Sx7_J^9W3Y=Yn5uV=7E9_N@`@aB`C*T~UGzlMg5dmq!bJp4P; zZX4*KZ`n^Aw}nInV;HwUI`^=ICz`j?`00FdDL8`*I= zX!pc`v~+q+z`kV_2PNlHMWI~!2??H?!>d_zanem@G8sG0yJV7F5{$H~8eID(iVmKQ zcrL4i{amlhY9VVU5_cMDhEwvj5Y%^|F|PMt$i| z&omH!aEB}zlAEJN+`o+%FRO12+AMjdft8k8NE}jf(ZaRbbfQi4SN6gv0<_>Dm`><` zMH6>a2^v|_kF`pTX}!}>uh4UUkxYuySv3sfL8cNV!EskImR?>w#?)r`(6olCi@cY_ z+W&0n@lrw#=4%Gjoc|R>ZorUXEz2Uz(;X?n%Eas39%Pl>$42q{KgR6hy1HK-GAeUj zx_3fuwGExd{k9F1C&kdte4`6@RI0_IRlF(TQ#o@+^>>LY?V~!6ug<3ok43=G(d^mc zm=2i2gRkhr=rINDx26_Y#bDN%AA7mz4<%e{8#>w;!Pf9nn4e5pUh@Id6{~HCOe(5 zgSpXGlRlgP&F~P9ExV1FJae8s)gej$u?^H9s7iEFmJKHjEqQ(1Yo(@*4tZ*xdgo2W zP1e+A7l6*|4BWM|@BE^Sx^nsnV0S_0CYG#EO=Ib@4~Z4Tqk;w|ph5Fq5&8kY71h ze}Gu+_g>8Ot114WGE6o61e4f`*z;$`F#plQmPN_8KVrxC7cy`k8z8LXCc#-MuU1hBQ}#Ky!6?aOVU&ROJek^ZZ_x1Z1JcZ7Kd9o7?@NQf{7 z!{)b*sTXkHY@)EVE6I;yrio9=*kM88;gp?JF-?}Cu>I%PUDDs3_!98?50S4FtlN_ckr!FAf~It&@Q1Jek~8{|WA_ znFgbsgC%1`jZE;`%oaMzvgBB-1`bh~4@i@;~O)<+I70k);Q|ZOHY4cht zJZmiuE^tyX%Pcsptj_$VkobC7_7>{|3i5GSyn|Si(e7j;7n}&|(yPrN51)Tx+Wm*R z!SgKaK0IwM(;TFSo25T?_|rAX+Oa4zxtk*C8)uu3MRLBj2(2&g#x$MS2HZ;dyy|F? z!>j_hL}E4#;fp|Cdw_Tvf?Onw@&NvN1)!#^MDc>$7f=XJO~pL4EHzSoe0 z)WdSqr0nb7gs-6fy`yWl_CikyhYJ9L*6{7hpJE-q84+9~O@D=ZrI>aY1%pWwYL z9$eusJ$~JD8-UstgT|bOC~^f1*q-Qu(L!9HUqL9>jQ~O!XM*t~Rz4*-ASKF8g^K$gtYU=2+XVTf!7=n%FvnE zPnYM81|T1fJ2{P=s$ujV(m8viFiz5h!50TG`x%~`ga%ET?9~BO2+l{^S(iRlmE-Ka z6}u`Q^36g2UMv8P zIPTv^?LR!9QErEqn#gNOuGSD(*U(*D>H73;XJ+hsM{A)!503q5+$ucKP;3uc>UeHP zrn?=Htdb2zwv$zsZip=)2U=T*>k7Bx3T3cPI+j}>ZfSM=HV1FZH;Uj09w_f%OT>i- zanB&4;F?4F;oW+~rO|BwUugm>l(3)K$H5`)_}=9qVMb#v$EmSur9%_W5#p#_uDDhh z^B^>?TF|xENR+g^%jByN#`;3S#sQFqqOwU&~dixkM4Q!@dCjwZofHeY*8lM zij+d{W1iJZZRKk8-><&>$nUUgGK8*6JAT$cdt*{E!S8_p_h?W~tE{&3}J7&`5lc=pS zALv%dzo6~grF^WwwoLcrTs=f@>4BOgtKyiY6thRI*`tj)(0yQvSv*Y@48+d7kw(%r z5J5{@_j|#7ZO4``;6r1XD}SUgLg=5|BLg5;nj&@L^ZaYvYTMmVWHQFrf6Q?!+-f@L zaTPW?8~6-3dCRoD(_QObTXhjm&{?dCOm`4jrDv}Nu753(!Lr4c8Q1Df>Tct! z-_`vpcJRJu`Y7y~M3jkK0tkA;sH5aLXM_y8SBh?W@Y${Y`-2f>Vg9yIitRkudyB@G z)ZLjG^sqLr;%jxWGntQ59Ltv<|HL>}g4j)ehx5K!608Fw#zcB-m21lO81qbYX13SH zbA?W_3}Ht@O1LMP_oNPe$Mjaa%cJSvBOrdBe4|E&AgS5UNmc&K=zT( zq74tG$$~4qFc!!3Ah+dh11<6)4(7@Rt%sh4#4s=2-02raZV=`Q)!ny|VDF$2+X%c1 zL&HG^0=YGYSs`}kn?i((3lH8Cq=1SC;R@ar=C*T1Q(hE44>!wD+9&YmLfV!BAg?)t z9a(L<8w_E1GQ&u7z*X+I+Ru&iS=Hj$!NvK|e?buc8A<$~d~g4oEz=^wl~HGD14ms4BSXebA_Ap#MxJpz#j`Y$iy(~mi^7H07mT249C;(!H$8<@^z12RUHwNE?-bOi-!DY!l5pNG~%@LulOr@y4^`|Qx704xry zB5&?~5pmNc{a;pbY6!O7b3RI6j>0Rv^k>>aganmT`F`%8G;?(Qd;?R(qoSS#Hds+4kYl-E}I()%aI{(dPL=OenGhWA(Mvod_^$#0 z_%Q?JM>;wyTw|uFpb3(a-vHL`(XE=5Yw6(a8C7?m!Dqqjoua_{v=%Z{rrUM(Q{1~ zLo4L~<8NgAL1sTIguRPtj^;{!Y)EZa&^qLrY|#f9Q(X;HPRMz>x)5lhpaW%#6WSD1 zGpI;u_(^7QtANdV`m^i0Up}mlNj%d0&fSmtizvE-?yQie-zZ=!XREtD{^;|eTC+1Y z#!N@-`(rQ-4=5X%L)OMnuXk|8WM429r>$_C4-!J^s%Y6C6u)Yu^ghvCKt4j2t2JUG z|LFQESs2Vdy^dzt4Q5d@?!j*Kxj|h7Jo#v|O$@B0A}7a6>PW3rx?goB4pP=JGl0AK(>OzkvyzWxO<9o*;f zM3Q*y=|GT+1iFexS6*{=8vrrlYVAho<8caoHgRoIk7VHVYH%iSuJE%m%l?}|GFt*` zLccMPX}`2VqqHK#{I9(Dp-1)F<9}m?cjtx#&z85t?rL+}!Q+#vz02!Xg;cHF-|y3! z_ivRq;(owtz!2&@Tt`Q$CRDBYh61Mk5O&@mA%wdko&>3NyaPg?HZQB=op93JJ}{Zv z=rqOt;}ff_=tu75)o!s?pFJ<1+zUzQf%FnV0M#El>O)FcaahEktg6GCu8fZeGz7W! znm#@{3(vzsGghPSHgcDhoi=SL!L2~xGMW^_Dv?@v>j zOe_-smJ9=t4f^_f98Fc)TAq@lt?I=iigJ~)H#Jwqxq^$g)sl?@=mm^~`t#Q0FX$Ub zRS|6huTAU}I*#*ztE{wng7q6Sy}cAfdJnBR9S3%nDq7el+vb3)Hm)0lUg{Gci;#*t z&$=vQW}2aB{<#gXG_wu2v5DvS{;*8GCV_GMrHhTj>_!>wUCdVLU#eMOJ#33{1eObN zuhy~SnhZx8OJWGF=K1gkBD!q&Av#KTMy8f6fnl8PtE_CNFMtRX_C)p_j?Pd7eD)pT zxEeSzi@854%A-!z(03OHJm)ok|AVI^_v&TP4V4+t_1_eO3k4S=CpR9p{rYQJqY12F zp9DyJDr0M;sX=8ZybR~%gL)PJdX@D){;k*hi@NCcTp?F7bW@ru#SAkS>1Umr|Fks? z(jjLiH1u($Xy-C;7Us92OS2!ZBL#!+fGIy3S^oW6Hem9{J@9oR7e~U8jJO!H%Nx0s zeJM=iC~@$itjPH;R4VH}$gy%EAQZPhIJGG=YCd!_@42kc({Z<_j&Anq9eWK0+fT0H zUilGj!V(o!>T9qa$SSG&!l&{6tfS#C-%LKF-hsBt(6M7dT*2Sd$e3*aXz-x4P>_9XdVp_}%W`rLReq%ik8NU9P>3)+c%M*Aq* za>3r#_Lm0lTnZTq` z!(xVB??jt^^79b$GmrXaF4>ejd@WPm;0guNE?oyx#MMaKz#e8Qi{RG(dlR2EU_UN{ zXhJ^D+~K07)U;(?m-MpYG4{s?-BCxTYfJiGmQx-1A zCSoNq@$l5yv5M)D8^3Wm$2F+292@p2)|^*xkwpcq z+C+wGX%IKw6XJgV_5{z?@I2y?wvlyVu$9FZdftoBhhL0KY{GqoH&a^fcD@pI`UH8K z1N|9Hn0`H_Hc0HIcXurBTNuZ)1@F7W(0D3uNP=+_h2im{1g~|&wY5^)@XxwoWa`4H zFX(3%O<*#?K@1*FD*IRfBMZjk_;dUec|MbLcXz0TMOPR+gJp~o?&Sr+GB%>8^xT@x zJWYe$?Ed9>95B1qEyVOW3wRk^Eqx|$^ztI&St&sSat8M7gJ+IFw8Eno)0cGiCx^0G zoC3t1lWgs>#tPw z`%mYg@vo|`gqaBw7qa}~l2#+%T#JvtGL0|0~I9SfM zD644U3OccLUjE=}-0*0XdEEduR>9rp-zPhFpzP;u_vV4W-Ou!DDvd> z<4v{BJ7tt{rGtS<)gW5ZbZJ?)fb)iGq?z~QqZ2dPp|Yaxj(odb%3U5vgbmW0!$(t1 z^LoqFKHYc7)!}AUMQx(wSqc8cP>>&XiB&X9QWh;r0CE6G4qu-2KM@9(L^B=L`F^6p zXjvpeD+e?!Fy_4ur|1`jtn-3O`;B{_e#ZtNe{N7!SO>h&`uh76n z$Dud61J6fJ-_70de&x#gA*Pr8h96Bu4`5(bHly97!^M=zGqKeG{%n>PHgjg>f|3dR zi;XuOIpV><407dy%`Y)a>FT=O;2QtFH|AHL+k6qT2r>ucKSH|}KwSGUx|K+?UFI2M zYMx^1(!X|*e8Wyb&Lwew!OE}emahyUj<_iuD1-#?C22CWtp|@&o!jMY&V5c=>HB@U z?a(0w{mVVYyB=xMGn!$$@N&W0j4IH8=&;>-e3wx$y5*DF9Nkt|u^UGw?QS(D5u3xuuI~&3HBMLyzy)@Uh+p%HDdR5i@wRxQ-lsbYPN)UPr!r>zo}-zC64i<=f7JI_&;4A&hu~e6A`-1O|rQl--OmB^`2I=bTE9t&^`pOF#rXQbNLOf0i=$5lz+K2nr9UYW`pq9twI;}-VUirv1oE`)hMb*=R9q}Cm(k^?zTSLkWnks^Qs z*mq;9)u^(haIfNL5x_J6ZQ0-(0`pvY@GHcw75W z|B*9h@}pVcnP)YD*chzD)3rkqUC{ZmkM%q-ulrpTGRaw|E->|V_)_Cb{Zu&l!UHH@C-4R86^60o3@k!D?1w@o0EkO|wQ9)5rT2xfPP%LypLXqAC6cnUM7ckP57CI;*O+bny zp-N9E;X;ag-v92-?1$aiot@oJ%s5O8_uO;N^ZeRV%qu(S;1zCG?Ur}@G|qGRJj`my zOIm@IN_Av5HwWot&6Zs#57~CgRA5;>+Pn0{s2~^Xws+R z=08}n*O=@3fk?FlnH#_ij0(fbQ!@80oOVJA4}e8Oj(T-+RbnKaaz5{=-4Bp?Z&oGo z2_iyehAGC%s5*BGiknBjwlQGGcC<#l!3u!?Ko!d3rNLv>RYQl@S&*{pFpHi^xhuFV z=?zH2^gs62zgryZ(^aPI39@^yZ>a>?qoxsKs$}oLdzg4(X!>&5&7US?ISFC15ucf9uk1=oUCUeUss(fib}B2VErC5EcXKg&9D{=5xTBEzFl z)a!^azkL-7L2Lo%l+43en=frD9&blWr&2zrVqLGVo>BVgf^vYzlBCy;(hw^_v_rln znABv zonvS1K2?i8#438|-#aGMUP>KoIdkb*mJ^x3=>AfC5vfr%MvtY6PLB=iz^E0@pNeK|+yB1Y^dejZtI#L&)6 zNVta*Me>e})$WgQ@w|Y$OB=oB$1#x#RkRVSfuUh!>RjhbJ=r3sSG}#r({s*J%q^rn zo+GPfak9Xu0g_c>cCqU|q~^xcBdT+@9~M)-3FlgRCCHHXNqxzJlL!&0YW#9Hwez`8 zMdz-^3y!wit8VG>S?h)|EXzR#W}G*L1L@LH5$9x`OLGRYe_WLubjA>!NNP5Pp9c?-;vc{YPq}eg+D3CDzBR7#eQLLY3Pdp2n)*K zE59U5I~9^QZcumo-0Dh-lT>i=<3_Ct@cq$PA;9~-Olrf))3^y^TiS7JpN56U{$mIJ z!G4p>UR|5y5~+y8c1L#?@uCcmD{>BKkjC+JOX?)0n0aaN*!T!WFLQTK6_!W?di%2s zRScS!iKdYDK))8n8`x>j+}&JP96NR_2)7MjGT?gq+J}D#A1!XR!IuN0mRUtX+8&_K z&(X5Vu4yKO&_>N4WbpUj5B6}H;Vl^Nd~-h}@qh*Q^vLovhBsCYI>FF{%qTN#DVkte z;X?n<$2z$8137x-mEjmci8W7x4C^)C^&oYm10}+Im4wuwheq@zNk4Y7~6xuwW z(7kt5Y#~Ewvv;ay#hGz}-ED0_&5slSHRb~CO^8u{w(0TxnN6#K5xsRIb1BR53?#0f zR9O?~DPIe$0~9{UY|8cd+Kt9b`00PJ8;8EA@H}cZx*o{8W3J9I#JtY>0$5V>v9*@n z@K)kz4rMs|zJump4P7YR-a%}~T6E$~?2Cyo1xc$iCO7yz*Z5$fz~)*QUJ&odv)O?B zA%aO;ah6YZ&P;jJ;iK&DwSX=r?Qc8+$x^sOma%ZMz$q0~voeE^358r;qNi4d-fk-# zZ-7791^jsvQVA?*I)+G_rDO^~cyDw4HU?hi2`}@%TgqbOXnSuPoZDHk4O?~>^)_cw zc7B8K%LOQ9nBY5y*|NSe4Nz10tZc!wIs)A_<43?5qsy68^WLb`A^~t?nY7n_M){rA z%VVk?)%YK&++%>b?rns03#Zva=7*t_Hf_fEmiB``fXz#?^8%#a-Y!<6I#!rEJ3EJ( zU$RKWvb@Dvdp`ss&HMks?yrrSnDEaq)dx8T-n;nEu+;V55R^1q7}qB*JRgY^!bE=h?YzBjc9ylUO7x!;u;vzPjIfKDNLPiBM+KWDt4-Fzu#W&B(BN2Ah|g zB4E;*S&>on(RO^fV#G7DpfVFhqaD6{R5fm*2q1B-QKwIsTvp^btuzxqPUu39YE7Ab zd6N~-&{`{!iJv^B@_r=!Kcnn+ zi~DHjRe*oTEiX16`@-R}X>&|^o${Mv+@Bu!59S-D$hr98**86_E|etEl^8_gq~)QX z5UH=AM3?9Qged}3_aVJ=nwM^>zyn-Fk;DJf)I82OOpMYRJnl_qHd)GG5Hbnnzmjst>2qwJZwj+q*;bx zP`{=2E`#$n$^q174?r?g=o}3Zt+@yat9py8lQkbrH!eSZz2QwsvLDsk3sgf_aadzzQEtpBPDPg-pPP7lQ<7T5ZW0{KK(p!Azq7 zB_o0SQqGH?&Ns1k_MEo)tVaiNC?^g32ConG=}3K_2-Y3^%L%}waS}N`2B*ms%;;{i zlF(Qa{8?LC!sX4MQnT~&?s6wWwZV&2ZoVQ+=^f*zc*Yex=yoJ5@Kjq@XRI*BF@-Rb zz0zKZ=QOqq9VM-1=2twa`$%+r${p5c94Dq9l5Nv*+`U%(U>Vn1e9G8CE%WuI(P>U8 z@OVo?@>Fml5Sq=eoBu?}Ia!C$DlzxEBW!DB)gmV7om?c(xAWg%8&ND@qIQ8 z(jcv3Gp~NuLQ1nT^-wPuqrP#jeokpzCKqJ)I*zlJ#bLwXQX(E;gQHKP6o|eFi1BVm zYDKfvmBu53a^IuJBjUst&-WF{cuL0US}oOn_{e1e<`@XREivbZ+%JMqie)`DO82>C z^*?702lF^se2fTz-NQNl+OYY>L5*LbP<3xYNz|XDDR|%pcRW(+iblXOpUySW)(uk; z$?92d&U_4jLLQ@IYqeJ3RCgm9>%+^hUt-1=kNogf7kP%QFrFUKV{2?mM#x=w`S5fz zcOK5rpa%Upe#PPG_O<&EiWW70((ioUqOab;{#((WY-JFwkk5S1if7u8*F?=22DmQo zoK}0an0M}*&;G%r#mhsIEfIX5NY~6YmeJ)kD?yaCF+ml>mejd))lfY=W$n*mss^cB z##7g_U{lV&jnC%{(zvl@d_$R<{0unT~>6sFZe0KO24VptMx}mBz znkQxP{f-D{j-x0S5k&AZem$H^M;~E-M^y!ccPjA{xuAhx5N66TtT(B6L5Lau_1xKu z@JZvPmC44w{Q%>Z`hVma`~N9_o{)@kMvb1O^sXp4Jo216i%gliDs00zYgO?=s;5}! ziwC2-F0tNmxUnF=4CV=R)BBlztZbAE>i2e24T%RSUxGUw(njsMPw72uaCxGLkK>Rr zhw8}_lDPcFPpsfZHFmfC5y&)~sY(rxaTRK7zuHm2HRt*%uQ6@z-S11>T(vLSZ?bCK zN>+)^_|fRA4L;M=<+Q^iiIp$+@*LED;M3Vnit1mPzYwmRNC53BeChk zLe2Jh3FH>#AgB?}5udCW)Ah|ek7y!Q>SI<9Es9sQ&Nf_5mg(bO(uxJ;cXnpEcW`cE zKNBNZ5peKmsmJfhIhVNKeB7X7{shwDsv0n6jYI7HSTPzrO1b2iZ{F8>!-9^4jx#^K z_jPe*=!_&mXX&1-vPOi7IN0B7LCO!KB_182sZaQIb$?-dPWrUA0_!tg#3=XhV;+%F5BFMaVCa(j&|{{xBIYLZoO`U@3F=zYE4UTIFh&02F~l_ z)@l}{qpbN?$N!c25_*q9OD1%JHMI{VUazz#b9Di%>533@@hij&E*$x~x3PxP!(j;t z!&0iwz<~>Nhzq;NKD>-^y$%}l9m@`mf3PL1*)`^w%#|wq&r*ir;a+sb-M!$tG&;?0 zC04ou;c_U^Ss>u-$Z}WFjt6j_yA0iRUtSsU*vNHY6_DaQwG*KP zP)46Ul|7}e!zE>A*Mhn_O8D^(RHXRdb6pM{#DlAz`vcahme{v(#0Jq%CO28>c=GE; zZmasCEgOks!;RC!^K}pKe@rD%fxs%nvY}_QGB))hNZ~n%_tDI6Uo_#t!Y-bS5NM6Z%lo??{qJglbam0c*R73VhSM%j_z7VkdF5 zvP%UihWoag5+R3LT$Q*Oc^^4DW823)YDJ>n08dMN1oe>S@B}n&nKsT3dk1HQTS@q4 zfNeQmD$v}$oiycYeF15S$*ogDTuJ5zaXM^y_E?5IWLM4)B5ztIC7geoNP3^SFjCmF z{lax08g<>yv84yk<}+a!UvQ*mq~~K*sIy~dBo;QI4^K8#9(xeFkD=7vi8R&Fzf9M5 zh>&K;tzQe^*;fMiie`jHuP7#Z$~*>rgy3msd_mf|bb7-sjqrW&`98e(Zb54%)eJxS zq3OJ8^wck=-3!;iL^S%!N40;jEB)1d+!V()JHx4z=z2RKl{N2hkCK+4ohs%$9<(vOt>V5LV`IT&_jD!RmGVaqsE`wY!N&v2GvL{+$kSK z0@3shnL{_P~;;L@s+GN0^=n6m$WFW7^~(c z)Pg**UWq<(GEw+S++J@%ZkS@T%CCedmi?fogo4Su8x29jY-9}iv zu!RG8Sr`%lbyDZ;p=VP*$uX}p#IfPx@P@2&fcFq@?N2pG!Bwck@&Vh_plOF0g}R{&$?SDC~igS zA);L~2M378OfG6PC9{=Z{xcOGR^oB#jaQQE9@)=Zk2#eCdi*r|_5n5VH`Os4a(ol% z_c;9;4agw_J>>BRmZ~#Hl?v^&#yt5WRq-C?ZzpEldO43ZF0V-;Z#?~FvN|az;kv?JHD}r;;4nwnAojus*hg*yZkWa1*Z*h1qa#OeR!DLTr=vx1<3z-2BR}?pt7;2=LHZmmCd8~? z#d7XVe%h?_h3$hONd|}{REx*o3tdde)3X%0NLu9 z=q6ztF>2Oa4dAVG@M?LRo1Z$j8GScuTGapLp+-FU3TEA;6VKs_9o(b*2ZHjn9+_H$xl({ce!QHb?Fx`#g8u0Wg%~>*Gj$nR1vxZ(Dd#| z{|5IPtfie8Q?#<&+3Y@(D_uWb2sBOCVrSMgEvJM z0`VK;&BTh4)&P?!g_wtbgtNxoU0(W*Sk_ELX)Kze-rzh<8Q|S*Hqj>8g zgY%fkIOEwH9N)(c-=;sJ*xuM&$u!%GE z&;3Eq_W;+4ui|EEpj$CSDO9*Tbz&@FA)Lb+_2I>Wam>YLi03E>x7KW@ne^_VdHurkq2#0v9Z ztPwfdBd8Hha^Ak&MO<9Y(sfjtct~ag1<)rXVCo0K(Io;EeEf^wzexzr;Qs-HcBMY4 z8nvqOuDLSTIwfO@@0*tfd;|Wi4r|9Y_+BS_&3;?`xUY^}6Bl2sUkM6CPV0@#IWE(< zNGn>5$37d=y%E_$KHij8RQM*BocaX{d@U2P(SP<;02oYQNRDq|!O0^n|6p)%PcSd& zx=Ifyz6)$lv>@umF8=UKZD!>m-S4|{ck-*h z)I_G+J+$DFyx&k^kEamE3+RSalRytMUOjI|_kHOOd+l#t@0z`Gz3_h3;ccMx!O4Jo zT@3FgRsihJr~X={Y6We<|2%0_s*h+(y!&{Ef9{`Ib{+7>Y#46 z_%EjAnLp@-u&a7MOHALX{5%+EFfS^+tw@l8gsA=i)ZBv<{)^(rYOZKxM8Z?%&vDE? zH#=Lcn}|QTwJ{KQAU#I|B7n6#47L~`#R<#pz7EvEw&dNmG2nV#^8ah`iZ;{r^33~3 zrra6ttrpx@P&C0-ig%N_gwJ<|1^b7;{uzqv9Ky%8EA&37+MK?^{6{F6E$+~9cr05D zdj{mQOQ;@F4O{ix;aV+qz)F@-Begn@`5Lfk%`V|hk{~4Mjt2VoG})>%K13S+nT87z zZeUeMKa#4>et_(GA$Zi*)nifrJU6mxM}(F}Kg0rs8HjMS!&*ZkQ~W(%-@AM>F@wEH z0sEate%6THh1u?pyQX8c8JqQ&o`L9BR#)Pv9ybrx^=a1DJ!X-Uw5(+DAtCsTA}6hm zjt9$KhDFx(yVR>Oj7IGs^EP^yY{o*id&M=&5ZOJPNA)k0S(wrK|4Kz&NX*@tl|~H) zzOE@mq^hXlBgcYq;v2c;r^Rx)*ubQbeT`*M1rQ(Xhek0f#5OeV-9^jGr`;~_dV`IW}oeZCIHQN`6?ysK#;iUG5sqtY|e zfhpPzC+otd#NL~+%afY=?`HWjOJM~V?VjqR8}qD<{ADD*|qw5Lzuf1hV#a?kR*U+ z=Jyl8hsL*eo@QQv+(?g-ew@>)KKX3_LdG4}CIzB3>wto{@Xk2n9`Gk=4C!6ZV-KQX zZbtEKcy42}aV`!Gn@5cPOa7m)g!a0Hz&-U zpVyy0={t6b+{gWjJ%TO|E1h2IM#YjiRq+%tsEqRAcuj5ijQC6E;YpXL-hv$3n`;Sw zaNqD%r{2+kIb%deB%<_ZD2=;SVR>vgN$Z>33x)3w4W3?B6Pqqr#I-fK5ic|U{ugJZiQAhruj7^T+^H;nt_0_%lsFV2gKgX6hKYbJWoQ4!;N>@`oUou;Zmb}mZgkKnD z8K30EKg5qqOx52|?dXj^^p`%ud1%zfYr=#xWXR^3Vcai{-J?^)D70Wb|6_ON{V6kn zV-x#RzI?eTiipL=P9vZbsO2Jxsr6WEnP1a6*fzD94`BxUZjKdj*09e z`F!}v=n#L)*^_Bmmw0FPKIxlWVQ*eQ5Sb8+;zde!l=+CXSi41hJdNyeiFmeS!QGtr zp9-x~p-r-tiXsb^`MN6{T(r(%WsGOM%(i7$b}?naai9U^#Y2~{x3ZYZRVmqn$3!Yl zW?IZJhjt?pL)NpP4H{AcQBnITOJ?2#;^n9n!;4)2@y`FeZU<-VEz z?FpKk$g9}$Jq-qOPcMl9Y5yhx?xZ8mvuUR})~ps|)AB0*8?5v_pEV$P^c9;n^ZpwW zG7tj?0S=rBR(+eUxc(B2Ivx%F$9qLrkKMJHA8i(r;psi+EY=U$kU>%aG_Uc^)L z%2Kwy{)a1_P`atg!SpasH%6baS|Bh2Aj9ED91n@ zA8UUy=-AUXv*!bn4rSAspD_*rkDUl#Ka0{2! zZ-98S0=mx8VRypI+TM;{VOtwte=&!zPNYvh_d6GCG>KF*^AL`ZC7`45`uvAISgdUc z?YCMeJNI!UW!US;fIa$JGWFt_^-IkMO^O~j0k;cQpa9=|21p{)9$S9&dF*;G?uD=K z)16&PyEh&68NKZP;o?<7tNy9OwugQW)LfgX538S_A~FvfQmjHXc9EBjSLKTva{SD8F++$rxeifr(r#S6Zcu4?boo&43O9RO{xTS^F!8!NY!IGW1@9RQ`klvtw#28|Q5KU@Y0L zydIow{1}1W1I6WHvE(=27^F`Z~u%eSWA{V8>wylT@jawg+=*}ICFJ$|1T4|~8y z7Cry4GSXdDW|<4_du1xV$$mUmxcZ|FhOFdpkFt$o&eFD-htnv>L#Mh)pjznDAVk!r zzdQKtRP>X_m8M_!X{E#nuNs?Vf3ibi5aS_s`@q`)$^_*a9l$^qC$3q=jop@})f@{% zS$q)&xO$`9-%K8y1O!mG2>ClDl@g|>B%V>;86O1Av;h;d(Q5(NMJ=pyZRJ;14x5YQ zqkA#+UODORAAt+!j;+b=+zS+G#DqXJn$8IQFH}KBk8Y3w20^b0$~ujilqW_AM~n+P zghn>cpL^H=NY!a@%FqEw_$>7SOr3(sLKQ zbdINCa-9=+l$SqTIvVT4EBQqDW&mtY<$u@ueNR|Yha$)3Ei)U2(%&D$XY<*?OwDQcE5*-6J%7S4 z?{L#sS!qZfNWz*r(t;n&X&q6botolZRWMU3K-#@jJFA^;!ZjhNUS2;pWr>qPhsD7tv37_ zzPLfOSmW6xX(g(A@Plg9{(9{x36;I%F#kVB-+XpfV=Oj1xb3T0l26dI>1Y37wwVO; zTFj11zpCr%W;&wzkkKLV{F&E-X|Z3Fd8!gRM0fWy8%ML?AK1!1-DWi76iViPz|9L* z#lNiW49|*Fk!{~Svlj0sV|05gyZ*DmPn$SQ78SKJOOvJh54)=4g`sg%XqGIHn{IwB z!SZ%h#63=B{Wshe&&^A53s6c+h9oUH;aQeX@s*mP%JDoUWf8SVSx@~4jdiP7;B3c( zn6`xBwWiyt4mxjC@{^n`Qg-Ir7q-kNzRcPuLF)u=6Dbk!?kN>h(a z^(7RQE3KbYh2*qat_pSTTE$|8rdT$H(WZ@6^-<%IapR6w>&&U<&+UHG@t0Zdmzaga zdda_G-?Sa#X13KiPRQ&}3RGGrviUHKt4@>qAYE^2QnO#KRiipBO+K)^=9yeK=EV4^ zS=)rU6DJ$D96=v5PqUeF?66TC<)ph1?NGPA1m)4B%SC(!S8T$J9{n7VdB4rg*@&5O z#n7KXW(;NAD4G)pru;SY@)vJc^mrFPQTZ}~xnO)`W>ww+wj$%mS(GKXMD|{O!?=X? zgd8Zuy-cTHvydyb=3-5ht~=bBRM*gOYp1^ZolfzgYcF1%Uueg*fO$Ok$;6i+@t?_0 z*4NZOYdV;7XZoUrSX7Lg*WwTVB)dhuN4IihfGAz(K!AR+NSnPPb?xQmD9E#Za(mbA zwM>QCi<1}MUQg;yNLp6p^p~-kCj#}B%_8vTEI009@>L*@K}A#OKZcTMb-yPlY3%Qx zd~pW)Vg3*5d#4muz5)SbEL-Laq`?q&KC`r2KmMVXCf8r-=lVK8`r>1l?kQa3JHj*8 zTjJw?Fiv)lHONnnsCS(*b3eemFf!v@{eVk~l8*_dBgOW!lxLQEf=tT$rg*S2ySp?XBx3A54Cml`5?F z+T?!x6BaiskbMA+m1Vu(yyQ7}beMUir}PQ(UNggpyx*VmJ9z`0jIUH}i~kJ*SR6Z5 z;Y_zd^|d3UMV%|j>vlHI*1Bd#a$RlJ?H!O4_Y}E963}kv83EXYJU>17up`Sx$M6vC`FJSoxUV_FoeHeJ-{$n;3Z$_t9|yL-|5BJnO6 zuAwt`TY@wxF?4|#?@r;}gE_bsabk>&h+q7Q{1jTa>9=xUuht`rNO#Z7n4gp&>KrMps%bI7Fd>a!;&p%8R^s!eni_uQRh zxR>#@CftpRoD1+V51N;(Jr(Z>LbA7qbVKWP!rh$S^iY&j&PZYWHYYm*` z$Xb_y`Gu&tQz&vFk(+RRym?ZHruoG{*I@9`OSRo<%%+eT5a#d974YSNkD=L_|P911f)oB_&8?dnaA8uyE^h#3s%&LoITmg)avZ835ivuKc?9Y z;}<@tvIjMG-KzT(TRO7*6$>JMdBAX>kqT7>Erf-=u|p;6b-ig-Im+K7&HR^WxG)8O zaEla;7gG@j%y3y@-EH=X**FEUReL#OIj=dQtC}(3`Q9TcR9EoX0Du|K+{@(n#6*6v zcL>&h_zi=|KbCOk8QRiE0r+vO+_@G?Jni7uXjaME>^{XotvXmxj^0x;|u{qlrrt5S><>a zbD_~wIayfovSF3X+~m~vE`kBNBi}L);3;LB<}t5u14IEf&m^R4Q**&HqBKv)`iVtc zql@CcJ3-$hx0g~`un{8pEvjNBWnjsEPwlXt*hlT}-S_dTDTwlxOBPDWN%YICavTCn z;zKzpl|GjH2eSghHlE2{<~Aaiby5tZ&r^Y`Fq9TQ<=HcwNyZ0hH6CpojIb&8Hyhf> z(HC?$@x`%5cm+kJnn(Cum+eGU^hQ<65PfLp5Q!>SLs|;mh1Eczg%aEKgXDNyv1s%;^!buNpi5!4ZF4lccRx*RGXE0eVRd46`WV@@s zp=zt5?XKj#*be>rkR`M*?ngC>OHYhp?$b;6{-wO>egqO}dpE47?|U@NX{F}Vj!KY1 z;2C3`q%kmnRh=}Bp<4`D1{AbQ3CVtJ=mLZ)<}V!X)7_Gx^f~+{b&`N7vc9Gz_v*^0 z5_rBKX5Q72F3(D;zv?nKP05eS_v}n}cPndzKV7irF9lsVa=-N-WHB`jJ%U6mmJaw! zjLI2pjtd>gISfQS3C2b^>zXD!$cAkh{zDy{7EXy>2A5+p@>uncpCOQ;K$GON_d{1r z=nbsT$OASdnc_GuGyHvtmjPx*Um51_7BBMfgFf^2hem$rKPpy|^{yV{c_gW1Nkm$3 z__z$e)RQr@yD$El+U3wR=!N&h%ch|>cX3704saVMf& zeLLfLQoBfBda3J&@rIe~1|ArQqd+d^S8&a|0+6{I2>)|m(WhM!Wy6^KjTkZF&|>W` z;^W8{gC25j+eb5zE(6$O! z_Q2d}T(oJ5j`4qGvjv6<%CoY8MPD^WJD#H2+@&Xy-`hE^XZZBcoII-S*!Pglb~U^M zVk~Vc?Omfj)4wrp*yVHu;E1|9;CH$M&*(lTT2d83a8hvnLGVS$thahfFQiLL{#yDF z?p%4iefw+jlyT?w>+04Wt5IojDm++Eg0GpPzpvBeqJ+t)%Jj?Wi4QR&c1AF*dwER& z7UTQhrtXP<|HSvXOWz1*iR(ji>$x*jm`0g&0_(l!j@o($N@2z_ePJsMhS*jU52D(MtZarcz3*k%0|LC`! zpQ~^L%)sxR#7n(Dc=Q}a^^N>LYcHTPiHCq4n8?ArTZoEeBRXGDm)btg-C3)=D}Hz* z^5@R6pNNdnJ@v_$HAoS?{DUC>OA}xivQE5{Jk>)lF@I`fIJN+hS7(HKSG^ZTUj2dJ$-T?X*178RUnAQi27)2Z-c8Lf&376m;EU~z9=VIk z=cXFP8c2P6zy)*8cz;WRW!!zGDw$!Cp^Ndk32+0h|6+cwsiA?GSs2WZMRE>qGdL~%VrSG>>v zi}x`+z3FKyw>k#^359{%5y>@BRiwv3RWPZA3Z@TvsWc|X(95KQa^F9?9P*2^-8Y@E z+|0O+8{Ae~B37BlkU;zNTuM(h8`)p;X|w=cU!oKITxoGFd<0RBUS?%0gxA9hLF`IZ zbh29S!G!TT-I+24qQ-Fo!;SrIcYk8*N2Yl{IT2B>*YSY&FY*=&Of5&XxCf$n*u2ha zAoNc_Ps2GU_wvmj5#p5QrP{~c)dBogWn6n2xrT`3JYxCd^e?}mC7!HOqRX1}XLKm3;@8-dZ`%@W zS}4a3|M!OpgZxtb7YE;1nt!gTzDeepy2vS=W>D$^{D2Q}{NMp+FijgX8Q$%?BCSed zx2|=cyTOcM&021pM$QZ|@Q{LL+0@q&3#f;d*2b29LmajlpOCd-XNLE59<0QD4k)y*}5G>&g6z}?eTHESUv!-)ykSU zX%rb|1vDw@A2M>(T{(lmobLZQYYYdH>pAJ6tPgs;3~fk!x_$D@mp@Oztedj3__;52 zUr^7_^*w*?^YdI5JPxd0Uh44>-~;t}K@T3-a#BZ2Vo}7X>1)aq`NoKvHP@S-^5MuP zaT+RYSF6(;I-z{pXJbmRev%iu5IcK3I^T?)fS1FX&ebx%=gu7XQ~Sa`orlxiNov*o-dG5kxR!3S^IYG z1@F9n_dqJ>+*t7@ICPAtHDpq&dk9i0q!l5ssT3goU6`MdEA22{*M;*^_++ZF;1c~S z&Uxx9LfU5@{0dW{$Y-QO>s!Hs_!S^`|76f2^OL(sAGQjHFJ+E9OnZe=-O24tks}8& z*7H$-_P2J(dTnR>Q!}RX=dA7Q7eX+2BuV1O3;s(~JHkE;)i%2_&pW)pJY6k39UV52 z*0hi;Dm}D-uOPl;Ix_6BeyA!!Tix+WszUf^Hq|Zdoc4nfld(}jwMEgbpK2W#6Z#b( zG7{)!7|xi7=maob82@1N?o}|{r~hWcdJw*$$Fw>S!gy!&m^oVvn4O{}TG*2P%SSfa zQe)quoJ@Jo)d{H3B8vsOS?; zAAxF|#%|3=sSqnF_0Jg1k*=8R)8^Hi4V1XXA@e?pB})SW5(JkIXyn`N6&mBO4tR7~ z`$tFGJTVd9U#74C_3f2brV(G(^A?;co7R6Yc(Kg)hH%FEqp-8e;e0{wgA)Dt7GyG% zA`+eK9>y7n-Mx0+vM=N>W+wvZQ?!_dtm3U$&UU2u;9NOm{;0$#->LWXL)Xi+nLT%_ zw=ICQ{yh0Tjdcw2Q!?j-IL*VY-l(`%Ue!6O_mY{Adr+WL;WK9`?CNwc0x|)qx1X5z zr(>^4$zCe68|c;Ly8bsu{|;ShY5k+Q5Uw9ZwNO3y$J%Gl?h=LA^!HBNZUp)isQqE& zox2im%paUqYhF}BwWK1z2=iR@!B3$2;gB0da{CzXPzEc1|9&&HdM_Z~R3fGTw(CXs zEhTbspk6~E?{iIX`^^w z&*#u=hVi$Vb%S%gPv%iiGRG`|0n4#<)RXZ>JUn9SnCoVM3Ve-lDvfUs!S3TFi zrGDlenbGV6kQjCCHWWK;mdzFS?%<;<%#Cj5L1WztX_)ZNHsdr_9_-Z_gS)nBHFvky7jtaM<#CLk_Hnd?yJ)oH{uMUoL7=Y0n*@eKz@upLP=*9G7 z<`Y3q!eoy-=qq?j#7*N-2lEv$iu3*g@9`cW(b*4VSoKooBlf1cx0=JCg0^kJk}SNV ze!Xi#oKz%vgfbaljJ5yD%5p`D`Utg@FJv6WA3_oeoV^Ed>)M+2!P@3owu%0I+*?eY z0g>~+;(rpAT{hjJlkTzE<|_@3Eg6C}ukhU^uJYgGp8~tAwITg9tFYes9hAT@#R#2O zAXSuAUCNQpI`=>K@AV?gm}b1&h+oy_k*5T!WFsR)q{bA0t%`__?)*k4F{A^PPNIAE zV|*pdpp)-MzU$zbhe+gy8~ke$P)J+G@jAV-FTZl{jE^XCZxNiSy~~^oS;#iGnk1;s zsC%s~^oKjuHf~1+`0{7m!%0=>Wqt+{3TYQ71ZmhA+RzlD*Th%Xok~{S=H5k~JAYy? zmze&}S}J&WPIwRqM5?k1o}(Vmq;j`U%9-4k&o9`!=g-O`%QuNy9^W^9>PT5wag#HV&bV zZC@Wy=b;|8bDQf~b%+<`$atiDNh;K17YqzW(|#ioMTzwp)?6H3I5)kDcP{N3T zc0-~p;Kb7tPFZjzsF-R+iSOv)!fMfU4MOb7Vwr7spNmO|ey@GiodM~MH0uz-T%4v| z?Dh-h$^V8V>}gf|aobCzlzyjk`{}hQWIpjm(P>3aa%L!=daXAQ0pGf#cWVlR0rTuq zWzH5ZC20&Mk<`i*jr|^7Q(7$+&}qF=71w>WCT@80;L9j^o+$l2g|J&cfHM&m_#pZJ zVyZ)~j5rVx)E(Xuo&#e!;8;zlJ==@|w8R3{HI64=v)18i9PF8pd2@(Yc)`Phd&(U! z5pO5esnP`jg-nj&%^pjGuPjPm6+=D!+x+&kKc^=me`A{%Bk@cvut=U*Gun1Xsp@Sg zo4Vdf2@k7e+#OywhcCLz{+T#%@%gC*saGNKbwP1MEFQAo^*}|=bqbN3k)cbCt{Q1E zkC#>$$X!f$BE>rmYlCxU8b({-^ zvo&IPGhL~NGao_IR3V$sH>Ye?-bUgj-=@0wCjC@^W$>X zdG*Qu5?@qh_&ZAjdX?3#g=xRi$;b|rVehMt?j(Xa9?YxNni=|_z$oc3Mg_QKu`!i> z+#(-+Ea`Tv?9BzP9zu9MTDaqd`aZFT$S=vL%yo?gJRe&ai-OKl&gsFa<5%qzjH(~| ztPESdR?_}9XY2rG)|>`|6c26F@BNyX@bMbCNiAubJDZ0#-BawhGOy7MbWI1?eUtkx z;NZBvvEfWtk%_X#P`3wIkNwM|U{`PLi((dk&1CZ>Q5P@8JcArN$6U-e_6i8kL~$&d zb0X`3r?e5N;=>z^^@HF9pC^YYpIpqx`@_9%83>{P<8B1N6e@vvI0b0BrH6jiTPlRk zy6-rajGH>`Y<5Vb?)J8zg&QTHrEB50sPU058fG?u;#y%8-g|!7-2bJ!FOP@%|MwlK zgff+#n2Ms1WGmY!*%D)mBBm0OmYCLdw=IX?!ABXn2edv$9(4Ve!pMu=j*wIGuvPRdj!5XJMYff8yNev z2IQVw#Q#&e@P91f_pO%k3=!^!G^hc3DAipm@74NDOzz#CIsG{xS(RoO14_ai(z~j# zT%k(G!)dJ>ig8b}#9UFX}n zRdVXjW-L{QYe+G?g4WW$^&8e|vN3n7xHwf#eVz3oLwUXAElz^njo@Glocrv@*(B!q zR9y5hhupV-z5PF~Lt-!}2RDvKu#bKiA^|meqlYC`o!6_RbYS`#KAOMka3*mY*i_h4 z1ny{g(WFd)|Lr(D^`r4aV}IbMcvrZpc#&liEB#nVw(-10aKT9!UGO0AqwhxZ0nF%B zgP?*#9hivBK)vQ>TjUL@o7I6>Ea8NN{m(T81IaulI%JXSCzM5>Gh8H|VS_T4A{ zBy8D0ZVn^PZU)R<65&gG1(kscA)g66qULG5`s~54RkS_e2R$1lGWn4$VoHis*BNw_ zj^rao{1r#7(va^LW9kGgkk^Q@A?LubxCoUyO@Mf;!3(j*`;RCB970t31qTH1?nc1+ z=};P`r_wO&Gi+76Rk{e&cirR2w~ZC#OrhT)@eE@z)$!eZFR?HM)r%}@kwLSKmOT1=K zmScg@^wV`9Xbxk`n^MM*0{G@iNSLvk~tfMnEO8;rmnUi;bXUk`UuY{ zy3TPKxwB`S61(OFmoxzgUhf#{bG;@N#o~?$*crj#2jWgdda*oP zd|`i`6I(}N=&sWD1AFBbqhvWht>MFfxdyWQRtCKP4QRUDnYoBFaeTBRy{P<#xSyr$ zaBx8;$L6I1S&lT}w+PVHPyQF_cmM4C^!MiyRXFslzsRdNXe`-$k+HYel+AF<^?GFV z+0#Xu4!b!#TLPx&-S9Dc`qLq#8(!?nCVLz8e8)v?;EsQ#=>IO!%KeBdO_wY4i*vx=~4=XL>)Kcthx`7@(1m5~UDGYCHH0mv(psZK4I z<0HNtljklEq93Ts*mUUv3bX!w+h79M_+V=#kC2$(u&_}=D>95keF5oiN-9BKCx^Xj z2C>sc4gPz5HIw`#D>i)02c6%A_xq~~=~q}g9ZTWZ#?iA(i}uNc6Y(x&0$U8YxT+gL zc`3#o-^Mlro+VYXk{2g*)2~))_-NOZgsGN>nn*I^}N1p;>iy&o^+`& zF(6r0T4_H6l#fexbYcO!&k=agu=)J@DS(Ewvq8qaYtQ=PdCQR#I!^a69)~m^oN2!- zX^J->aW@G2=}pats1PG2xhm`(6pbI#^kC;^s>3h@nh2KvwUEsy7t1- zQ*g5nT-Y6ktfxo%5-n3M4JHJIWDGDgY^tp$9{4P^2M#AKBFYIX&J3&C@5C}>=r^k2 z!&O2uTXu*eR&U?wQ}(Tm*Mr&osjwCN)GN?x=lDatZfPU)rL-nfp*n}CT?%iUu1kNj zvvyN2nE$x*WUEknpluJi%y4;trcO`qtLLR42|!b|YqbTnOW)I5k=LNwgmlcnwPsIP zrQWaIpuntL0tPgMh+kMS8t#eDYm*t&W1S-vAE76fH~ODEx-NUU>2$1`PseM?FLRX$ zKIByPq&PLEyOS*_aCXSVl+l%{z69<*6 zT)bC-;N>^oCcBOOHNDRpr6h@bzYGhsZR46A2I30eB{7>K8g2}9=bJk7>_ajO7QKm1?@1*mxf-r=2>kG zN~PRaAE29ET^?~&8UXaF;m3**`#PNRF7{Pr?)T;dJ|6<0M2q)Bw}1hLYQpnE1|JmU zE)3M`dmIp=PqjxDbne_nBU<{G0Cqwsfq8bYoDgOw(~RP~+T~Hiv=}T>F}fKUN9&N1 zGa5lO>mCm}Tk;g?Mv5W|;qRcgy$aKkU}!^8+(n-Imo5(dIP%kGXqxX5U0^mKdiWzr zLd%wMV}xl4DP^-im)&9ulKO3oRo#00z4Basz8p3!1p)Ue)$*;B>e@JX zo!AL8<)#}aHB-Ua%4kkA7NxPx6nZ-FV4m4?aq~fjBsD3aasef7H_b89dw)-$;qoxp z9dv!sIpoF*$Yi4ot3hCCoUGuM^U=Fs+|Rhj#YJZKIJU4#;yY*jZ`h-fY2v8fj7|(t zDU{MYQ>O9ZqX*g@#G8%po^VYyd#pNcA#}|vw5g+NqNEy7v8M9CD%c&0cZH5GnbR&- zP8qy)OZ92uyw!N=2yDTzVw&((m~KQRrkr?Aoks;meyB=UO15=zJgYe#`@S@4%g`9| zozmW^LeQuFNWW1Ut(fS>vk!U%cmO`2W3Aqb7p|#-?5Xh9jUK-%s;5nJP#F)EIt1r& zhyjx4gkA^kF!X$?H>{Q`Sd}dNMlR^}#BKDQgiFCUv|6u(Uh{$N9$r4z{`#fuH_prh zJfNQjqV0%~If7~qTqf|Hzi1t1eF{0CcW0*`l@kf~VC+OuY`~a&p}sZtxIu>L2~w@~ ze#72`nh=g7?$(JPv|U&c;Gn8UAg5CC?+hdIgzx*Anc95+`IGF3x_fmi>4DsqZ68jY zmDa%Nrz^vh%HZg`b45ezfdv<(#-m1cWzc+wraiBwtk7ux_HbztYki)~Kn^sg-$%ME z@iMET{s_a?FVLo{ymG)I{MB{on_BPW6?wESW^b=#HmsV-tqDcJbWg%^|J6eD_XX)M z9`oi>RAA+o+&ou6H_PF;4C50>^X^%k)S!BX?IYR^EicFUCeNs{%Q?REq1A4aD-p}2 zmnenGLYlf>RVrtML7hV*;8Uk8A*dFF5jn#iEte{w+995H#In?Ylf1X>-1}jspeEfT zew5rYlyPY21V`g#@5eyr4*Fg^U5RWSg&74a_IXSQ?l^7dYF%WsIB7KpfW`ykQOf8P zJargfiH;O02`9O{*Sk2eVQ*On!<{~RK?nE& zboWo_81cu>!g0ru(G!fC{(Xzf!kfe2T0nFY7F9%k@*5_C^`e58LaR? zlX`>J=a(HWgGC|C`cK0h$$08T#a{ZQDD%-4=ZvjLmUY%pJBnA>zSs zFKc1G`Ub8#&YY`Y5!eqcf64Y_xV9=tuPl8V&mnDbsLqXoJr0Vl+qV%^HnW5Dark4X zKYney>aZLB?dmcyYefuXMITpquVaY$Qw*s+XJ}$~_m#5Jr#ueJdw1u6RqN%kOnA}} zFbU>>9FKe9AKOyYAM%yD4ZF(F2&xWXM877!TL6opd$$eVG}XBmnQA+J532(CaD37c z>d)>#D8y8=jctV+8+cGPnQlu26C*q*S0RZ%Z$*{?9ED)N=K+P)t%heGE<}Pp$LjW)BI0ec zb0rW$GqRML-HJ6B??QCJAN|5l^rX^lm3Jave5F3bKMe(yA%#NYe(NUTm;C$uSOEp1|2*)F_A~0bW7P% zAH33(_K=t;>(pwegowDb2e_uPE|k@VZVic#xlHV7mXEv_T^M|}Y4)!BbK>+y$cf?| z-+CidMv4Vyjp%pF04cByU|DvNrLWJ!WT#*!VVPVO`T`vPf!J@(Im~Dp-HkfGVoDvv zYS1L}y|OzbJ~*`9yQ6;ULevNKLkBgc3EPL~Wk6vUiU%N_dH?|5h!I=Jb~sPx)ef)y zZO-}4uM%7ybYYyg53l5k>P6>f<~b*gug3|zwHB0pIj^!9vN!$mFj{M97MH+Yu)`SY@;*YKxG zu+dHh_hgwFczY_ledD#*e22+3GaOLea{!dp>GrZbX)2Rk`Xfu(ji!vkY$Q0dM0W(X zk~kaonAN#Zk3O85om!}zPaKBio)03OS4ZZpc30u~*3O9^TrPdA@f%i~6@2;$W{g0$ zs(a)bF{6{($pnkU=i=L53=j4PR)f?6abo~aQ^g^G&iqEG(thlj{s)B1XOYkI;mbaZ zQ+p)R*`_2Lf=M#ab@|3`i)omQ?y` zxj9kmBj`s?994d1aC%LGYuXCmBEkMdS~DvrFu4Rc2*{Nd#<3=TQ<>JFlgD=_i1u=h zdB`KHxRwi5+>c`o2Y9NtJHNOaR5_GGDkUwq$$N+c2>8O=rdAlD2LvZL5k_LAFAq=m zBtC-eZscy<$mBs#$MEl}SOP)H>@7U|=u0AfhV^u1#w`~jexa%MGWq%G%1=GZsmIC^8GUGn`SqtmM>?4NaQXvLc2~;f0d1`( zo8d@x(7hDqE6lqJZrt~?r(78ca(F4*kZzoFFIYX=sUp2}RBMTdTSkUKmfx1EDgnvl zH@p;jj9;IXspZdcJ@_4&>+BYQgsjSpRERqwAbbk(`Uwe=4# zfV6sA4@5ffCUV?H8ko3II#${kW?1)d@>yz1X#H90Kx1tb=RN$6=wFNc&6GLr|Bfa7IlNy(Dp<8C{8Ac?wAH zw6-Ot2;}b5Ij|y*%l8LGbw*4R59PJ=zKootskE0mE|ZQF#*KBLx7cl)hi!`Mic;~-#fV9o{hUEz_Enp#5=EsA<8D7 z(~%JYyUiUtt25XbvZGl*`p+tv4Be8flX6Yon9(Qn2gA+jiZeQ4%Iegh20?tAiOYLK zW8kx^I>q;-_zK!{VRqbLbL-k?u1nDt=0&Z0Hf~z2UAM$oeVzkuTu1d!{6QpB|B$r) z4FLRa&qq^=j_Sh{RO>8ft?!$NQM@>M?*l0LGP_%iNUcM95To%Ds;67*{lqYkz6wNs zW2MJ_XDv}x5C_x?xrBbwA*2)Vwcx|;V*-8)2npqE9ewa{!%;EKD$3;JvnhiphmTG7 zIS$67FZcnDqB=v$PoN%190=wj>+4fAwB zG*wFOfDlwYU8->Sa-ZcH#Z{j1;+^WX!s5?1r1^Cv|JXXv6{vg_423Rg;B;k1s_A_A z-rE{leXt|!&y}M4HTf=+&a9sk*Scc9Osz1q0Mt;Aym!|#dm#YWlLk}0&8BFo_?1ACPP%r%jQ2B2iO=-)}?0@s+jHajM z4V|pR9cv(q9c)K-fC+NNq-FYw4_d6swALV9g+X}rsX(s3UV;I`b?NZ<5HCPMu3AeQ zId%S?CRO*(ziC-3$y0$xNW!SaWXJ%k{>n{LL)_lzr4$Vm0h^aF38?EWSt&*qS zTM%gYKDc^!2!n{zDc7b*(9lP!vM?K?~b-xF|cu!BO|CoNQr z?}yaaaEU)%-yRFE2=Ec$m_qaYS=PavrO!u?qE!GbQOJ~&tIkiv1saq+-s)gEGe0l!;T6nTS zeHfZm2o^}d-^iA*no)}^PIro>9|OGKhD(n#;V-|J1lOMhU#t=aN zr#&#HoorM*Z5*>Ao%<*pN2x9)?TnL#MbgZUg_J;}qbc z5nJL$0-I?)81t^s8+8JxLvbhch0uIhg=u?#jSE{Lspi@jMBzWd2CSZ7cXjw%AEX4% zEkkobUxNB_{Op7opGOzEl&{hGtSP_p5MN~|_$cJ;O90(Tr{Kx#Pb2Qb#X63%oNL95 z)&|M`@wWWi$(6D7NvVF6gFzxuQ>v>3^iD0MeQEZz%6QMhE)Z<|sFNx9m?bwOq0Z*M zM}1zRKOfC>p1}(_tG!zk{^ZL@c!ZjEEX@S){%KHykl^pSJ*f1_nd@B%Gcz+cItC-+ z2>rn)mOy3$8PpLiJ)b9-`sJxUQ~KMjF0^j#d2P7lcs(C%7aL&B4?uJdO(wDz+yJf% zmYw3??LC5AGuhopSpBJ}T4W1L=do_dVMUq-f9BLnoQ${%JXkFQ@t8fkF`8v` zH}EMZ;RDGWNSFc0ke!EbvZ}xIVF_5T7uBuXJj#1+Sjs(=iyHBwPtpwF(a2j*(uMJp zV%l%bweKZVY=r?J+zAdSUb#gHz`PFwzGL+unskFMhViW%;|9hJdgMYgy5hDSuCTDj z|3Up=UeaYyhWeHC)yi^GSa3QIh>JX`DBPlbbOqWhe#swac(3k#0Q(6;hq;eBM_yLs zTu{>t@VALCMqZ$c$#R|;KHs-|WADhi{0zzw-&UiBk( z1ayPkLA#g!M{D8^Hm-3cLOjfoVZ1vbmQu~c=`&&)Xwvq~8;xntFC3$rp zN_5n|)!MSz2ti&)^J6az7qO*rBMq{N9U31_ChysQ^jOYFM&@>r-G=9s%7+(DJj%S) zAl6^BhJ=4@dF4ir+AnfYH$E#i#QN?I7*-uL`F2rd!qx|&BwCnNHIznK5V^1wUihnR z_j|k---TigS5j^eg)WXfcI~Is&(GIRG?l}3H7=F532=lVA2H7WUN%C*A&0a&)=utr z@2Nk_(82DfnXN)bTKu_=t4j?dJH6OHU>=V+x^JM zup9MdHeiyu%Kl^*CiK?S-9Wpc<#pFCgjvPb8E|XbD>C_IP@jD`@l?jle3ZA)u6^p` zX~|auOJRiO66Eq@#&yV#i<+{cUNC7uyg$0td@4A=lMkPSOYa9(D<_CeWU4ii_r)zh zOe%SN3IF|wczITcB6q4BPRH|8uxX%ZPCD!yCRG} zz$)^N{8I1AP+X*Ua&@b|U+jeE^Ohlt90_b5tGw?WlA4gkOg91%_@UJO1{)ud^V zaKO2aSa4O<-~U;$ohRf zmGSTZq5p-M+)p5~mLauzNIaa}$;zsCezoa(Z2JKBA(4glANYM2k-*F)3kM+acx6g# zO2PSb{!695B!XAsVgUY?^+SM%NkZ)fldZYdLBmn3(lk;0;i6NG5TLcJ?Y7mPL4tkl zE6Cx1FjBaIQ$piwr_dF7jDGW@dFcc3#QZiGuG9h@U(3Z50^XhtPsjWS`a|BwoHWth zF-Oc>inX%ZOSJ&fv?BpJ_UatHfrCoVE+)TajhVh19Y@eV?rjVL1!=oWqHhIG?K`s4 zbtRCNCym%suQ^5DGjn?dub=!a z^k#K^?XVSdR0E(NFEZ@=)*8*SgLb@@z>Zjg75BXDBfkN98S90PWC}_cd$#}1O*0D*Rw~dQL zpOVCtn0T_X=UlK>3L1QO8Mq#Lf-3RhoAp&8hbjPax-2A^@Mnu%m8Tw)U5%@^GV)m$;g_F3)%gf<9Q9HcrZ2N>`C9$1nj6m#OD%N!5_gfN z;z_%({KX4f8?6ojlnz5P&W{zT6COoZLOREzJ{d`-6|Of#!8-cN_lUPtD!HW!K2;Nn zlRY1`Ye@ByBdj^Z4r&7{gKY=0N~Yd`Cs|!{q4Dn6RW!LtQwYUo1-{&QB><};gyBRohA;b15yav>u3$XCHg2Ug)I@G zBL#)L;zwAx$&A6j?c9QG6-P09{#0K%*uC%1u|Z7cW2{pbFDotY!dT?mcvcxdox*yl z<@OsUT?T~FH_5=^4fPe5_72G2*5Oj`#UpMrNr`P_sufvm_KKfk3yu@sms>BK>op!- zp^J1SfF?&YifK!fkoSH~EVxy9L&oAexBgr(67@q-K|%QMY{X)@$YGouR+ZYia~@68 zNp}`oKjokwPq@}P+;|rZ4^R>TCFraUxOXX-Cy6Fa82ZW&niW<>_fv)G{){PI|wL@t&s`85X@UmA)dU z+ovLjfA_uedjWxVeZ@Nh{P1M&)N?vEe)j#X(#VS(EZz#h3 zY)wnePi}uu`WtqNyLe{o!oVA#@*NtIz4sfYMY+U2S1y~meQebL5azc13pLh1;{Wjf zj6CdYmHtMbl6_Dg<2?2##QjpIh9-42s-;}5;CzY|iTdW=v2hdc?ZMjLIme#&ot4++ z9BNR27z|G!m{RZpP21%7IY1;5M%GpKsl1&3)Gzr&?!N|5f z1vkU~==da3+Pu`#ftjr0<9b`)KIz(WceyKYk9Vb7IKgzqDALp`w4l`WmwrwyBwmmC z1Av@r<~er>IdME<59oU2-|rTXYjEAw@J1I==iXFKS4FldS?*=k5&m1R1D*-8Cpf^c+M|e0Ztj-q0^Izq! zAzw~k<*f3mfad#yPu1K0ZJ(LCW}lr4-Jn>~9%PQ}Gt9l*rFCCD^XXl=hX8GDVin<} zk?~ZosXcQQB>@M05HTVM0uE7>WnGIBUKhZjJ3`%5?&><2L;Y10i|TF0mi)6kns(tT;kPK($X z%F#N)K3p%JlW7Z&FM-63YA!l$>p2Z=wF?Zt>(fQ-f>PMrB!=`-^spE@Ot@t@hPW1^ z;hz=9KknR#NbB~Pu#>g-gNsw$r2rojCDLkNcv2RQIlUYui8T%>^k2=~XUEL#o zsUlF?lJDdvCJ&?1{?<{ERMkY*H?Ga$ct0{d5IRCTQr|1#Cu2NBbaNOMdcDlC6xIfN zASnz*OrgZC6u+F-#(lJ@!VxeUMtr#Nx`Q7K&d!j|Fiina+{Vf%QH-scI_87oyj@@% z>v3YGUq!oAn78fjFdE3Sr>XrQbrwnM!=jvc(%(W^r_Qa7rkS6X8jsgS6kGwpwckpZ zC-9K$MoVc`JAzxKMB*%B>toFEU(1limn6}%$O|MV@L?6G?2x;un09!$<1uPdk8Z;C zYr{hE^Z9OPziWp8$l(JZ&qW|BWtPWi7vDI-X_G{i`8QTwbXObp0>8)nXhYOnkhW+u z?y%si5y1NicsC>Tj!{cg{(L5^R&D=6v%GNq)E%+J*NnP9S1=aSs?V#?5e z?*#9BrB|{R;~KD^hse_RPixKTDx+K2c81>5h15HWDSfiyiw@VRz9Q!6u~Olhe-+qz?|`cHoie#R3YudA5iPQ zqZQP1I&Y^^ts!@CeNRBaWSR|A|Ff2`v*P*wLoPMCL6-|c|JY9HX8aiX>N0aP5?|Sb zPxnVZ!D%r?sUlt!xY&Z7K@aIxZOpx`;Z`X&_m^V7atzcVk0xK~9nr`B`mtCoT!&m%!ij*B^8LOE*lJejKB;!70h{lbLx>w;2rbr*`f0I+U zdm{KICH0p-@N~rQ$J$MznpT5B6qdmKppP}5$IfZp$? z=%|xBD&8IC`sNrF*CDp@_>aF7A{Pu8xCrRzHyi@SS4^pCBIm--->{GNX%PuDo%|QL zBn0!6;>r^WDQzZYWsmQUocfC7B)0>HI2N}DyO1nO%>YT%0nX-rM7?x`VMx%@n?Z^j zb(}hp|5~}Vqnan}u6E%9d?&6QSUkalMG?(pKJP-?ixR#2UL-DJ`!`GSUT5+JnowVb ztLO^r_bo5OW`i;&PlF{MD_a~UP;S2MT7YHWKM{ik{>@_ZANza!KQ_7Z)0c`ExpSq7 zmP44srR5Lz|NOKhCVSxLC*90F8kBku3h2==&wT!&WlRaWF=jAO^t7zo>v;QV(Z+Fq znYRa0A>J9o6&ms}_N-zHazv)Z3Ts3&yNC&h{FrMOch_O=I|F6W<^oC41!<_ZJrBs> z)z4?1V?7GDNk2LFC~841o%ueSbt7yk3f49B8+HdBgDl4ZkcIHIqxqdUtXqIB|0VmD z!Xeny``T)bksv;=(f4vwDa+i`aPB1%^&Rfa?E$PgZMJ((y!+yFkD?dpZ5}h8+vekT zQ7VEcnUJp@wf*_dC(}#2yq9>Lxdl!hJP&p&jYV&GU{SI+qEw=e@I-Da2nmLLhe;IN z{%7@kCn(x3#+DDqOP%|9@{*&m3=F3N+mh>KVrb;4)s{e)I$B3`dH3NXqDS2yc5>_@e&u(+}@@ z4a(>I02KMvUQw(wWJ~=ilhV$X?_YBWPOq}PcYa01z$Qm)`VW46ha7bV6^7;@8iqRxVFb)PL~R+3 z&dMtmRgK`YVOr-WD63Bb@S)xdq@l|TLQB$_h#$S>89EhPaXXLQ1+c2#pY5$PQ*H1l zfEJi;GpNYo-!PT?BVsaYuWf>NuyqZ{y^m zAPIe#by;cIz)F9AyFgXQPNCC-$3vEP!U`|{ZFK&-gY(%RQA@c`fktdn-XguksbI7X zSZwY&&?&9AZqr$`J1X|djc{e@;(fvipYC$a_+`SM>Ktabkl(GgPOZ)$IWFtp9cdkM zqZ`^RH#S>I`^+`Cf{N1<4V@Gxgpx(E7SnEf69wO-@Tw-v&f-=j3V*;6>^?LnTg1Mi zH(`BWlP+*o{M7w%V+YKQ*uW~*^#FAGum<#Vy z{W#e?{!}mniXmgx5Ru9IWPVT@V&uElb~no1444-@n$NIgPmuU_%gi7fO+0J_?@D9f zSKp7lz*ciM2I zmQTLHea9=w+iwJXJ6GDYH9R26#R>pIPw@=20x)( zuQ0o)KSEeE^3&A(dZa+kqyRIzI&cK<+S3_-Z66Gm5lR(q@ ztNm3&_XlptXC?g}iY>sC+2TgO%18GjXCLitj-P^W=oZxj<#j0p7$G~hL$SWhvrxD5 zw1WxcU^)FZqRe0EO|@CEvoM=e#V^6?E_E`}_u zC>1!K!tKG0J`<)+g!4T7N*dNZp!`--3obc|X#^{b2hwc#Pl@WUI8 zliPxI;-OWB5B3yvDWA9vI(4ibPw8SCsiYsmeZJHS`?QdBiEGs>PPq;H%blUX?ju%w z8I(N2D%LtTDM~GQRyO8mVvJAZOcFk!R848{a3#x|F}FDb7-L@k^q1uJBgQ(eQ$S(2v>1jfd)PIoY_ zc_PzcI6vYj7kwRSFann!-fe#?r+-zGg)zIv4z1g*ce z*VE)ua}-y=cs7PSz1DP6Cuu9wTFeKA<)6YsN9UJIr^R!>_$cnFdc3aIluWTrDrOF? z%gz=B#ZRL-Aoa!}{K({;DcGqi1wkR^IFn z4bIVxq8N?m#Yv8)k;S1x)4oHTn#IN0AgoEuuZqp%OyxCw@4??_Gg=k9?it^bd&OAV z65$ps2cYz*&|~U6%xcsqKltEvNf3&9f4Ir!K8;S`|I{U`$22OelBpJXZMf{quwh#3 zU^+0d8$*@+tQGaMF&+=Et@EA~MOpz`y&r}03hWdk)cSiVDB*?FD-lPslNXVi1fv!V zG70N818k>DnuMwoQIKu+5^3M6V3bGS@{yb5A3fP2<5A0h;z_qtSkLNZ_BW|4#FTpw((T`Ud3Hh~uSVxjm*G_&yrNDwXrv`%RzT%G?gJ6*lW}DxmDw z!=1=Shm&`E_j0&-;R^n)^oA_11M7h*0M)M>$Ao$4d zOqt#zHlSZ7aj5Lkb?^rB9X{6PoVslq|G4?=-)G7E$ItT*@IIeukn(FEo1PER(xZI* zD!E8*sSWzVjBD5R7aCPQbg5VL&|TSWt52BD(*%z1>Npu%_@6Arkz@X@>CFc@GhXGd zai%g`hmf~d38V^x65lD(*QJ);T)+G3C&wX@jh?_+uh60VusW%y*L&{8$@S=PF|}xh zOaUoNd<+qxburOzCvVo4?ZZ2sm$G84zv+M1OK%Zv!A=C)F58APwWn8ieIII&q;^M( zxuo3;IaF13DOTFz>+vabu6F!3(sg76Vs`}|LNW0^>a9q`RfL)c+J?1YjFN5qfr36u{BAEll325dO(l@eTB=Nk?+rXCj~jH8$K^9jg`OD+XJVElJVxVz}Zy z;o)yGmaal!xfh*!uD`1`si_8Y<2|9g#TIGNO(5#?=sXI)p zx_SpWdCuP5X}xd@&*aYoUK0JqFKNGKh9jA7^2DV(3A0VFs*0tq?n{Mj5FV4Oe3!pa zYi$QA;DUy47MJ2`aZmGp&YjbgB^*aFc^dAg(8~cvre@@UcU27g`F-mu)9?-Sbdy7y z*M2Gy?SPeI#o=91VMg#^Cj7elX^)v1KlZ>~@j(-{IdtQ2f5A&@SrN`mKoq!)zkwzY zMF?Yf&_jq$ebiP?TJm<-l@_=kZjLwi~tM+~R!SIt;(!U;m zEzza@dfOL4T5lU-j6`>VEa!%8Xx?I#FVhR%a`CS&px^D|Tgf5XZBGA&0XSkbjUpf8 z%s9gosd-zG_{{;;`pM()as0O&y>DEx!GJb+{#^%;O2SENi$9LSzA_cqc^Z;l$;!a( zZO2cm(He-Ddp%=*&cghfcyD?8x2OiW+0%F@@+gtQ|AaKEOfmhI^pvDDpry)=EI`hu zb;2e!`O)XGO00)S7tEud3hcD0B@bI`tuFt3LZyim*r`AEl|=&kOeC63M(@WR8Lv!Y zC}9r_Va;Y&7!L{}P!*upkQ`;N`P8Q%pDIqLL9-@ICn%e%rCW09z*j#vIPqIX>8I{; z{;zTF>p~ye2h1vCd%$L+D$>JV8{?i;n3uzGE$?6DI{66M??A`72w@9D!1n(yQ~YtXj< zgr@(eu!R5J^Wgv2z2*L?#w`d4C%P7lpz;<^=5`nLt5~)j9FL7X`Jr)ryHDX$bFMky zF$>^pOcLIa170fsAOCOz5|@d$ql!@n>u zf>wDm6=Wz{GWh0C7I#$yo4W#EY*0u;P;8(03^kHxCxV_Ttp;=6s8bMTbB8fh7ox?j zJuql(;DlZw{6c;3y8D`~Ksm?H;V{w-;s~ZOC4Lbn0c6Q7L3C)E2RJQbLHGiutyG(~}_UuNIn`)qPN5OT*p)=^?CD{+OGZ(#`S> z%N(U>uZ{(51=-Sx!CW;ZN$gYX5po$=$n^t}`=Kapy~`b4d2XZy-**VQlit!Q`j|e|7Ld1d zFJEQerDXwQtM?r;22_U2h8vq(=KBXjbeifqvWfV$kRAj{TQXX3;!yy!=L%f3BWzt7 zGoA?RN~qDA5`%4;!AIrjvjFf6pfLfB1~Wz2(?hKJ!n`1AcV633MdVOvpOI=ln9;Vg zp+~e+piMZ6p&YH53GVP8SX;ogd5E&7oV%P?`bn1Cjz`Nj<^r3%bessgi(IzaENwuw z4J}`Ce+vuDKg5642w(qW^J8GJ-1l3VQ6fXK)`w*qFNv6I2hV{0{NCO7Ou&2xqzwPB z{p0vOz+(R8?eSN)%s=G0a{$CPj+2{5#Q>AJCRFeP1sQ@Wlw#p|XrQPwmF~-)IbU;# zz_?uUn9y1>WHZ*!RA`0)0j1(iZn$Qo$rXL6=n@G@~rHGe)rJ*x* zc0f*3@Nm1U0gAy`r0dI3gO}&*T1ykST<-l+pE30!NWH9APYmMc_5%gPblKEG4V-&Sr8D>ei&s{5igE2B=2w!Dy> z_|Cc58;hv0Z9@L7LWY*nYeRW^~4&0zzfu zn~BstO`|>@m*Dglw2Zvd9TPwVU;zz(1``YNIy?-&Yn8uEV^-OZ+_H|xN{0v6jM%{zSd?l@T~_v+Z{MH(>-N?d zZ~l|@4~5@sxn8#G2fZuJlGPXC3_kW%!tEBU{r`tslw-jQ{@X{eS*5=kJmK0uFfLJpcdz literal 0 HcmV?d00001 diff --git a/src/Controller/Dashboard/DevisController.php b/src/Controller/Dashboard/DevisController.php index eebc812..6a00347 100644 --- a/src/Controller/Dashboard/DevisController.php +++ b/src/Controller/Dashboard/DevisController.php @@ -6,6 +6,7 @@ use App\Entity\CustomerAddress; use App\Entity\Devis; use App\Entity\DevisLine; use App\Entity\DevisOptions; +use App\Entity\Product; use App\Event\Signature\DevisSend; use App\Form\NewDevisType; use App\Logger\AppLogger; @@ -46,16 +47,17 @@ class DevisController extends AbstractController PaginatorInterface $paginator, Request $request, KernelInterface $kernel, - ): Response { - // Gestion du renvoi de la signature if ($request->query->has('resend')) { $quoteId = $request->query->get('resend'); $quote = $devisRepository->find($quoteId); if ($quote instanceof Devis) { + $quote->setState("created_waitsign"); + $entityManager->persist($quote); + $entityManager->flush(); // Déclenchement de l'événement de renvoi $event = new DevisSend($quote); $eventDispatcher->dispatch($event); @@ -145,7 +147,7 @@ class DevisController extends AbstractController $rLine = new DevisLine(); $rLine->setDevi($devis); $rLine->setPos($cd); - $rLine->setProduct($productRepository->find($line['product_id'])); + $rLine->setProduct($line['product']); $rLine->setDay($day); $rLine->setPriceHt(floatval($line['price_ht'])); $rLine->setPriceHtSup(floatval($line['price_sup_ht'])); @@ -154,14 +156,14 @@ class DevisController extends AbstractController foreach ($_POST['options'] as $line) { $rLineOptions = new DevisOptions(); $rLineOptions->setDevis($devis); - $rLineOptions->setOption($optionsRepository->find($line['product_id'])); + $rLineOptions->setOption($line['product']); $rLineOptions->setPriceHt(floatval($line['price_ht'])); $entityManager->persist($rLineOptions); } $entityManager->persist($devis); $entityManager->flush(); - $docusealService = new DevisPdfService($kernel, $devis, true); + $docusealService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class),true); $contentDocuseal = $docusealService->generate(); @@ -172,7 +174,7 @@ class DevisController extends AbstractController $devis->setDevisDocuSealFile($fileDocuseal); - $devisService = new DevisPdfService($kernel, $devis, false); + $devisService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class), false); $contentDevis = $devisService->generate(); $tmpPathDevis = sys_get_temp_dir() . '/devis_' . uniqid() . '.pdf'; @@ -182,13 +184,10 @@ class DevisController extends AbstractController $devis->setDevisFile($fileDevis); - $devis->setState("created_waitsign"); + $devis->setState("wait-send"); $devis->setUpdateAt(new \DateTimeImmutable()); $entityManager->flush(); $client->createSubmissionDevis($devis); - - $event = new DevisSend($devis); - $eventDispatcher->dispatch($event); $this->addFlash('success', sprintf('Le devis %s a été crée.', $devis->getNum())); return $this->redirectToRoute('app_crm_devis'); @@ -206,6 +205,7 @@ class DevisController extends AbstractController 'options' => [ [ 'product' => '', + 'details' => '', 'price_ht' => '', ] ] @@ -223,27 +223,39 @@ class DevisController extends AbstractController $devis->setBillAddress($customerAddress->find($_POST['devis']['bill_address'])); $devis->setAddressShip($customerAddress->find($_POST['devis']['ship_address'])); $devis->setCustomer($customerRepository->find($_POST['new_devis']['customer'])); + $interval = $devis->getStartAt()->diff($devis->getEndAt()); + $day = $interval->days; foreach ($_POST['lines'] as $cd => $line) { - $rLine = $devisLineRepository->find($line['id']); - $rLine->setDevi($devis); - $rLine->setPos($cd); - $rLine->setProduct($productRepository->find($line['product_id'])); - $rLine->setDay($line['days']); + if($line['id'] != "") { + $rLine = $devisLineRepository->find($line['id']); + } else { + $rLine = new DevisLine(); + $rLine->setDevi($devis); + $rLine->setPos($cd); + } + $rLine->setDay($day); + $rLine->setProduct($line['product']); $rLine->setPriceHt(floatval($line['price_ht'])); $rLine->setPriceHtSup(floatval($line['price_sup_ht'])); $entityManager->persist($rLine); } foreach ($_POST['options'] as $line) { - $rLineOptions = $devisOptionsRepository->find($line['id']); - $rLineOptions->setOption($optionsRepository->find($line['product_id'])); + if($line['id'] != "") { + $rLineOptions = $devisOptionsRepository->find($line['id']); + } else { + $rLineOptions = new DevisOptions(); + $rLineOptions->setDevis($devis); + } + $rLineOptions->setOption($line['product']); + $rLineOptions->setDetails($line['details']); $rLineOptions->setPriceHt(floatval($line['price_ht'])); $entityManager->persist($rLineOptions); } $entityManager->persist($devis); $entityManager->flush(); - $docusealService = new DevisPdfService($kernel, $devis, true); + $docusealService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class),true); $contentDocuseal = $docusealService->generate(); @@ -254,7 +266,7 @@ class DevisController extends AbstractController $devis->setDevisDocuSealFile($fileDocuseal); - $devisService = new DevisPdfService($kernel, $devis, false); + $devisService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class),false); $contentDevis = $devisService->generate(); $tmpPathDevis = sys_get_temp_dir() . '/devis_' . uniqid() . '.pdf'; @@ -264,11 +276,10 @@ class DevisController extends AbstractController $devis->setDevisFile($fileDevis); $devis->setUpdateAt(new \DateTimeImmutable()); + $devis->setState("wait-send"); $entityManager->flush(); $client->createSubmissionDevis($devis); - $event = new DevisSend($devis); - $eventDispatcher->dispatch($event); $this->addFlash('success', sprintf('Le devis %s a été modifiée.', $devis->getNum())); return $this->redirectToRoute('app_crm_devis'); @@ -277,7 +288,7 @@ class DevisController extends AbstractController $lines =[ [ 'id' => '', - 'product_id' => '', + 'product' => '', 'days'=>'', 'price_ht' => '', 'price_sup_ht' =>'' @@ -286,7 +297,8 @@ class DevisController extends AbstractController $options = [ [ 'id' => '', - 'product_id' => '', + 'product' => '', + 'details' => '', 'price_ht' => '', ] ]; @@ -295,7 +307,7 @@ class DevisController extends AbstractController foreach ($devis->getDevisLines() as $key => $line) { $lines[$key] = [ 'id' => $line->getId(), - 'product_id' => $line->getProduct()->getId(), + 'product' => $line->getProduct(), 'days' => $line->getDay(), 'price_ht' => $line->getPriceHt(), 'price_sup_ht' => $line->getPriceHtSup() @@ -304,7 +316,8 @@ class DevisController extends AbstractController foreach ($devis->getDevisOptions() as $key => $line) { $options[$key] = [ 'id' => $line->getId(), - 'product_id' => $line->getOption()->getId(), + 'details' => $line->getDetails(), + 'product' => $line->getOption(), 'price_ht' => $line->getPriceHt(), ]; } diff --git a/src/Controller/ReserverController.php b/src/Controller/ReserverController.php index e7fd999..b155148 100644 --- a/src/Controller/ReserverController.php +++ b/src/Controller/ReserverController.php @@ -213,6 +213,7 @@ class ReserverController extends AbstractController #[Route('/connexion', name: 'reservation_login')] public function revervationLogin(AuthenticationUtils $authenticationUtils): Response { + return $this->redirectToRoute('reservation'); return $this->render('revervation/login.twig',[ 'last_username' => $authenticationUtils->getLastUsername(), 'error' => $authenticationUtils->getLastAuthenticationError() @@ -231,6 +232,8 @@ class ReserverController extends AbstractController EntityManagerInterface $em, UserPasswordHasherInterface $hasher ): Response { + return $this->redirectToRoute('reservation'); + if ($request->isMethod('POST')) { $payload = $request->getPayload(); diff --git a/src/Entity/DevisOptions.php b/src/Entity/DevisOptions.php index 73255e2..386aa4f 100644 --- a/src/Entity/DevisOptions.php +++ b/src/Entity/DevisOptions.php @@ -3,6 +3,7 @@ namespace App\Entity; use App\Repository\DevisOptionsRepository; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: DevisOptionsRepository::class)] @@ -16,12 +17,16 @@ class DevisOptions #[ORM\ManyToOne(inversedBy: 'devisOptions')] private ?Devis $devis = null; - #[ORM\ManyToOne(inversedBy: 'devisOptions')] - private ?Options $option = null; #[ORM\Column] private ?float $priceHt = null; + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $details = null; + + #[ORM\Column(type: Types::TEXT)] + private ?string $option = null; + public function getId(): ?int { return $this->id; @@ -39,17 +44,6 @@ class DevisOptions return $this; } - public function getOption(): ?Options - { - return $this->option; - } - - public function setOption(?Options $option): static - { - $this->option = $option; - - return $this; - } public function getPriceHt(): ?float { @@ -62,4 +56,28 @@ class DevisOptions return $this; } + + public function getDetails(): ?string + { + return $this->details; + } + + public function setDetails(?string $details): static + { + $this->details = $details; + + return $this; + } + + public function getOption(): ?string + { + return $this->option; + } + + public function setOption(string $option): static + { + $this->option = $option; + + return $this; + } } diff --git a/src/Entity/Options.php b/src/Entity/Options.php index aa60a0e..9c1178f 100644 --- a/src/Entity/Options.php +++ b/src/Entity/Options.php @@ -41,15 +41,9 @@ class Options #[ORM\Column(nullable: true)] private ?\DateTimeImmutable $updatedAt = null; - /** - * @var Collection - */ - #[ORM\OneToMany(targetEntity: DevisOptions::class, mappedBy: 'option')] - private Collection $devisOptions; public function __construct() { - $this->devisOptions = new ArrayCollection(); } @@ -153,33 +147,4 @@ class Options return$s->slugify($this->id."-".$this->name); } - /** - * @return Collection - */ - public function getDevisOptions(): Collection - { - return $this->devisOptions; - } - - public function addDevisOption(DevisOptions $devisOption): static - { - if (!$this->devisOptions->contains($devisOption)) { - $this->devisOptions->add($devisOption); - $devisOption->setOption($this); - } - - return $this; - } - - public function removeDevisOption(DevisOptions $devisOption): static - { - if ($this->devisOptions->removeElement($devisOption)) { - // set the owning side to null (unless already changed) - if ($devisOption->getOption() === $this) { - $devisOption->setOption(null); - } - } - - return $this; - } } diff --git a/src/Service/Pdf/DevisPdfService.php b/src/Service/Pdf/DevisPdfService.php index ef1e4ef..0fb3a71 100644 --- a/src/Service/Pdf/DevisPdfService.php +++ b/src/Service/Pdf/DevisPdfService.php @@ -3,6 +3,9 @@ namespace App\Service\Pdf; use App\Entity\Devis; +use App\Entity\Product; +use App\Repository\ProductRepository; +use Doctrine\ORM\EntityManagerInterface; use Fpdf\Fpdf; use Symfony\Component\HttpKernel\KernelInterface; @@ -12,8 +15,9 @@ class DevisPdfService extends Fpdf private string $logo; private bool $isExtraPage = false; private bool $isIntegrateDocusealFields; + private ProductRepository $productRepository; - public function __construct(KernelInterface $kernel, Devis $devis,bool $isIntegrateDocusealFields = false, $orientation = 'P', $unit = 'mm', $size = 'A4') + public function __construct( KernelInterface $kernel, Devis $devis, ProductRepository $productRepository, bool $isIntegrateDocusealFields = false, $orientation = 'P', $unit = 'mm', $size = 'A4') { parent::__construct($orientation, $unit, $size); $this->devis = $devis; @@ -22,6 +26,7 @@ class DevisPdfService extends Fpdf $this->AliasNbPages(); $this->SetAutoPageBreak(true, 35); + $this->productRepository = $productRepository; } /** @@ -139,7 +144,11 @@ class DevisPdfService extends Fpdf $totalCaution = 0; $totalHT = 0; foreach ($this->devis->getDevisLines() as $line) { - $totalCaution = $totalCaution + $line->getProduct()->getCaution(); + $p = $this->productRepository->findOneBy(['name'=>$line->getProduct()]); + if($p instanceof Product) { + $totalCaution = $totalCaution + $p->getCaution(); + } + $price1Day = $line->getPriceHt(); $priceSupHT = $line->getPriceHtSup() ?? 0; $nbDays = $line->getDay(); @@ -148,8 +157,11 @@ class DevisPdfService extends Fpdf $lineTotalHT = $price1Day + (max(0, $nbDays - 1) * $priceSupHT); $totalHT += $lineTotalHT; - $productName = $line->getProduct()->getName(); - $ref = $line->getProduct()->getRef(); + $productName = $line->getProduct(); + $ref= ""; + if($p instanceof Product) { + $ref = $totalCaution + $p->getRef(); + } $currentY = $this->GetY(); @@ -191,14 +203,14 @@ class DevisPdfService extends Fpdf foreach ($this->devis->getDevisOptions() as $devisOption) { $option = $devisOption->getOption(); - $priceHT = $option->getPriceHt(); + $priceHT = $devisOption->getPriceHt(); $totalHT += $priceHT; // On l'ajoute au total général $currentY = $this->GetY(); // Colonne Désignation $this->SetXY(10, $currentY); - $this->Cell(150, 8, $this->clean($option->getName()), 'LRB', 0, 'L'); + $this->Cell(150, 8, $this->clean($option." - ".$devisOption->getDetails()), 'LRB', 0, 'L'); // Colonne Prix $this->Cell(40, 8, number_format($priceHT, 2, ',', ' ') . $this->euro(), 'RB', 1, 'R'); diff --git a/src/Service/Signature/Client.php b/src/Service/Signature/Client.php index 6b33949..53db773 100644 --- a/src/Service/Signature/Client.php +++ b/src/Service/Signature/Client.php @@ -32,7 +32,7 @@ class Client // L'URL API est le point d'entrée pour le SDK Docuseal $apiUrl = rtrim("https://signature.esy-web.dev", '/') . '/api'; $this->docuseal = new \Docuseal\Api($key, $apiUrl); - $this->logo = $kernel->getProjectDir()."/public/provider/images/favicon.png"; + $this->logo = $kernel->getProjectDir()."/sign_ludikevent.jpeg"; } /** @@ -42,7 +42,6 @@ class Client { // Si aucune signature n'est lancée, on initialise la soumission if ($devis->getSignatureId() === null) { - // URL où le client sera redirigé après signature $completedRedirectUrl = $this->baseUrl . $this->urlGenerator->generate( 'app_sign_complete', diff --git a/src/Twig/StripeExtension.php b/src/Twig/StripeExtension.php index 272af0b..eaa51cd 100644 --- a/src/Twig/StripeExtension.php +++ b/src/Twig/StripeExtension.php @@ -5,6 +5,7 @@ namespace App\Twig; use App\Entity\Contrats; use App\Entity\ContratsPayments; use App\Entity\Devis; +use App\Entity\DevisOptions; use App\Entity\Product; use App\Service\Stripe\Client; use Doctrine\ORM\EntityManagerInterface; @@ -62,12 +63,9 @@ class StripeExtension extends AbstractExtension } // 2. Calcul des options additionnelles + /** @var DevisOptions $devisOption */ foreach ($devis->getDevisOptions() as $devisOption) { - // On récupère l'entité Option liée à la ligne de liaison - $option = $devisOption->getOption(); - if ($option) { - $totalHT += $option->getPriceHt() ?? 0; - } + $totalHT += $devisOption->getPriceHt() ?? 0; } return (float) $totalHT; diff --git a/templates/dashboard/devis/add.twig b/templates/dashboard/devis/add.twig index 94d7ba8..9ec77b4 100644 --- a/templates/dashboard/devis/add.twig +++ b/templates/dashboard/devis/add.twig @@ -172,10 +172,10 @@ {% endif %} {# 1. PRODUIT #} -