From 20e7dc02de5efdce1fccd9c6e98bb78bbe72ec35 Mon Sep 17 00:00:00 2001 From: Alexandr Date: Tue, 18 May 2021 22:26:48 +0500 Subject: [PATCH] Offer print form seems ready --- data/fields_default.xml | 88 ++------------------------ models/sale_order.py | 6 ++ utils/misc.py | 31 +-------- wizard/res_partner_contract_wizard.py | 25 ++++---- Шаблон_КП.docx | Bin 112685 -> 112684 bytes 5 files changed, 24 insertions(+), 126 deletions(-) diff --git a/data/fields_default.xml b/data/fields_default.xml index dd74abb..f88fbfa 100755 --- a/data/fields_default.xml +++ b/data/fields_default.xml @@ -337,7 +337,7 @@ partner = self.partner_id # Functions _ = self._t -# get_date = self.contract_id.get_date +to_fixed = self.env["client_contracts.utils"].to_fixed # Parse date months = ["", @@ -355,8 +355,6 @@ MM = months[mm] dd = dd if dd // 10 else '0{}'.format(dd) mm = mm if mm // 10 else '0{}'.format(mm) -# order_date = self.order_id.date_order - # ctx keys must be declared in this xml with id equal to "contract_field_{technical_name}" ctx = { # For manual filling on offer creation @@ -368,20 +366,13 @@ ctx = { "offer_name": self.name, "offer_date": "{} {} {}".format(offer_date.day, months[offer_date.month], offer_date.year), - # "delivery_address": self.delivery_address, "commitment_date": self.commitment_date, - # "products_amount": len(self.order_line.filtered(lambda rec: not rec.display_type)), - "amount_untaxed": self.amount_untaxed, - "amount_tax": self.amount_tax, - "amount_total": self.amount_total, + "amount_untaxed": to_fixed(self.amount_untaxed), + "amount_tax": to_fixed(self.amount_tax), + "amount_total": to_fixed(self.amount_total), "currency_symbol": self.currency_id.symbol, "terms_and_conditions": self.note, - # "payment_part_one": self.payment_part_one, - # "payment_part_two": self.payment_part_two, - # "payment_part_three": self.payment_part_three, - # "delivery_period": self.delivery_period, - "dd": dd, "mm": mm, "MM": MM, @@ -390,11 +381,6 @@ ctx = { "seller_name": seller.name_write, "seller_company_form": _(dict(seller._fields['company_form'].selection).get(seller.company_form)), - # "seller_representer_name": seller.representative_id.name, - # "seller_representer_name_parent": seller.representative_id.name_genitive, - # "seller_representer_name_initials": seller.representative_id.name_initials, - # "seller_representer_function": seller.representative_id.function, - # "seller_representer_function_parent": seller.representative_id.function_genitive, "seller_inn": seller.vat, "seller_kpp": seller.iec, @@ -402,14 +388,6 @@ ctx = { "seller_business_address": seller.full_address, "seller_phone": seller.phone, "seller_email": seller.email, - - "partner_name": partner.name_write, - "partner_representer_name": partner.representative_id.name, - "partner_representer_name_initials": partner.representative_id.name_initials, - "partner_inn": partner.vat, - "partner_business_address": partner.full_address, - "partner_phone": partner.phone, - "partner_email": partner.email, } seller_bank = seller.bank_ids and seller.bank_ids[0] @@ -427,68 +405,10 @@ if seller_bank: "seller_bic": bank.bic, }) -partner_bank = partner.bank_ids and partner.bank_ids[0] -if partner_bank: - - bank = partner_bank.bank_id - bank_name = bank and bank.name or "" - bank_city = "г. {city}".format(city=bank.city) if bank and bank.city else "" - partner_bank_name = "{} {}".format(bank_name, bank_city).strip() - - ctx.update({ - "partner_bank": partner_bank_name, - "partner_rs": partner_bank.acc_number, - "partner_ks": bank.corr_account, - "partner_bic": bank.bic, - }) - - -# Person -if not partner.is_company: - ctx.update({ - # "partner_representer_name": partner.name_write, - # "partner_representer_name_initials": partner.name_initials, - # "partner_representer_passport_number": partner.passport_number, - # "partner_representer_passport_date": partner.passport_date, - # "partner_representer_passport_department": partner.passport_department, - }) - if not partner.name_write: - ctx.update({ - "partner_name": partner.name, - # "partner_representer_name": partner.name, - }) -else: - # Company - ctx.update({ - "partner_company_form": _(dict(partner._fields['company_form'].selection).get(partner.company_form)), - # "partner_representer_name_parent": partner.representative_id.name_genitive, - # "partner_representer_document_parent": partner.representative_document, - # "partner_representer_function": partner.representative_id.function, - # "partner_representer_function_parent": partner.representative_id.function_genitive, - }) - - if partner.company_form == 'sp': - # Sole Proprietor - ctx.update({ - "partner_ip_number": partner.sp_register_number, - "partner_ip_date": partner.sp_register_date, - "partner_ogrnip": partner.psrn_sp, - # "partner_representer_passport_number": partner.representative_id.passport_number, - # "partner_representer_passport_date": partner.representative_id.passport_date, - # "partner_representer_passport_department": partner.representative_id.passport_department, - }) - if partner.company_form == 'plc': - # Private Limited Company - ctx.update({ - "partner_kpp": partner.iec, - "partner_ogrn": partner.psrn, - }) - action = ctx - diff --git a/models/sale_order.py b/models/sale_order.py index 23c61ef..c6c6c27 100755 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -87,3 +87,9 @@ class SaleOrder(models.Model): arg {str} -- String to translate """ return _(arg) + + @staticmethod + def to_fixed(number, digit=2): + if isinstance(number, str) and number.isdigit(): + number = float(number) + return f"{number:.{digit}f}" diff --git a/utils/misc.py b/utils/misc.py index c2842e9..813fca3 100755 --- a/utils/misc.py +++ b/utils/misc.py @@ -1,38 +1,11 @@ -import datetime as dt - -# import inspect - -from odoo import models # , fields -from odoo.tools.misc import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT - - -'''class IDocument(object): - """Class must be used as an interface for create new document based model""" - - def get_name_by_document_template(self, document_template_id: fields.Many2one): - raise NotImplementedError( - "Method {} is not implemented".format(inspect.currentframe().f_code.co_name) - ) - - def get_filename_by_document_template(self, document_template_id: fields.Many2one): - raise NotImplementedError( - "Method {} is not implemented".format(inspect.currentframe().f_code.co_name) - )''' +from odoo import models class Utils(models.AbstractModel): _name = "client_contracts.utils" - """@staticmethod - def parse_odoo_date(date: str): - return dt.datetime.strptime(date, DEFAULT_SERVER_DATE_FORMAT) - - @staticmethod - def parse_odoo_datetime(datetime: str): - return dt.datetime.strptime(datetime, DEFAULT_SERVER_DATETIME_FORMAT)""" - @staticmethod def to_fixed(number, digit=2): if isinstance(number, str) and number.isdigit(): number = float(number) - return format(number, ".{digit}f".format(digit=digit)) + return f"{number:.{digit}f}" diff --git a/wizard/res_partner_contract_wizard.py b/wizard/res_partner_contract_wizard.py index 362c710..13bd372 100755 --- a/wizard/res_partner_contract_wizard.py +++ b/wizard/res_partner_contract_wizard.py @@ -239,8 +239,8 @@ class ContractWizard(models.TransientModel): "label": group_description, "count": 1.0, "unit": self.env.ref("uom.product_uom_unit").name, - "cost_wo_vat": group_amount, - "subtotal": group_amount, + "cost_wo_vat": self.to_fixed(group_amount), + "subtotal": self.to_fixed(group_amount), "display_type": False, } ) @@ -255,14 +255,13 @@ class ContractWizard(models.TransientModel): item.display_type == "line_note" or item.display_type == "line_section" and item.name.find("--fold") == -1 - or not folded_group - and not item.display_type - ): + or not item.display_type + ) and not folded_group: lines_data.append( { "number": next(counter) if not item.display_type else "", "vendor_code": item.product_id.default_code - if item.product_id + if (item.product_id and item.product_id.default_code) else "", "label": item.product_id.display_name if item.product_id @@ -270,14 +269,14 @@ class ContractWizard(models.TransientModel): "description": item.name, "count": item.product_uom_qty, "unit": item.product_uom.name if item.product_uom else "", - "cost": item.price_unit, - "cost_wo_vat": item.price_reduce_taxexcl, + "cost": self.to_fixed(item.price_unit), + "cost_wo_vat": self.to_fixed(item.price_reduce_taxexcl), "discount": item.discount, - "subtotal": item.price_subtotal, + "subtotal": self.to_fixed(item.price_subtotal), "display_type": item.display_type, } ) - # Line with product inside folded group # + # Line with product or comment inside folded group # if folded_group and not item.display_type: group_amount += item.price_subtotal # Last folded group handling # @@ -287,10 +286,10 @@ class ContractWizard(models.TransientModel): "number": next(counter), "vendor_code": "", "label": group_description, - "count": 1, + "count": 1.0, "unit": self.env.ref("uom.product_uom_unit").name, - "cost_wo_vat": group_amount, - "subtotal": group_amount, + "cost_wo_vat": self.to_fixed(group_amount), + "subtotal": self.to_fixed(group_amount), "display_type": False, } ) diff --git a/Шаблон_КП.docx b/Шаблон_КП.docx index 41b7ae3b364aa30c4397834e3c00791593926ae3..030a0bb359b66871dabb66c4f03a5923026ce4d6 100644 GIT binary patch delta 6119 zcmZWtWl&s88l3?K7~I|6B?On??(PACyGsTbAZT!(KyY{WAcF^j2MH5gf;&kd@YrN) zxAwi-{?qsC+vl9>d+Ju#cj_)sYcEi-wAGMNhydv5=m3O%6BZs238CLY19bc|r^h0( zKs_S(h(b0R=t5$2KTipUeNhU|`IzR^ep1J2bb?yuRCCb(5-8Jg*Vq9$6P5f?bLsk$ zWF4m!KT{nKEV~=NYrtZgU%2Rfrj_czl}^sd0S1eO$+X;X?7zKI9crm3a^xHcoK~io zFo+OZ;&|J%MalLK{9abf+u|_I1kEpr7`pS43ymsjOOOZNoL~}7DfbdP>A>;bC0y6d zZ;ry2N)E`Z?7{~|mvZ7hm^TleedaKsyYeO?emW5es}%iYthVgI&wa_!{&nGK3#j>F ztF_j^2sv4ORP$Lh^&R7uC)~Er4^vC#KA^_%S!s?Q$)}Yl@q1Hgf2b!7sdtFd9{-Pm z)N-|FMJ4Qc2{VdE*sBv1{>66?CtrjiwdX?nm(XCOjx}{;&nDvbFrKv-sFdwJwze7? z`u9_tYDXXd@D&LF_^&M}e|$;jK{@~93oS_C-~Q;MilhATCl!Mky5>$POwzYeL58JW z2y#wlLNwRanRoi92X1xByf4j05|mTXo54b3Vpaeni8wW_71;D3PD$bwdK}&TJ=TQQ z%kR9xrQip|S4@!cyE$cwkIh`Hno}rQA~CyLTU(;ExT2pwiJ!0gQ`beYx5ODOU0;h@ z4CSkEA!@R3bA@@JQ*{RvJL4@WauViC;;_T>`p5k||Bnpz3nMhkVQI6y9rDhCh~c?xn#Dr9UU=8bX9<<_5|>SAL4vXt!&_-fiH#HXpR;tv z_uit8;B3?Jx~xdWceRbSZFuK(nnThI5s{`+%q;d;L|bA|>mHuw-bf88VVM|EL22|0 zl}QqXQ~mVE2-oO$l1Z+yb_}BuvG`6}-oVhiuYmqF)GM!Kvq#^rJbLptuiWcJRXi-@ zf8_Md!f+W)+o*E`Y{ww7d!$;di-ptWJFF*Tf@)@d$=dpU1NdR7ETs#}1Ekf%N3k9+ zL(NOBT(Se8RJCnt+`AdK)N?LM!tyx8poH}R{c!s|1?Fk+b@C^ebA+%>jx#}qRjHIP z?7==@8v_$0S?t;vx+-F=HPm3S?E>$QDA^=`cyV$T@FHsF7o4z=${9Yh_PEIxNF)(8 z`6P1`bRi-_0u=}aC2v8 z^BqYr@Z&Gji&vfi8ropA-8W~nuLeFxoD0TP&O{Uxam;o@@nHjvJEcY2UKE}RglH*A zuqPR&9$IA1kJl!HtTqztfi4$*h0J^-Ig81S(2sW4+ReX$*#0Ug{F#1+%q9wUw;ui} z)}mvwF-%)zrr|~!q)wIuE?Q=O>lOUCO1Vf=ZfRp!a>6C~C0azh=rsHdBN!#^ZEx3Y z?(2fr=g;?r{83Z}(B&P!e_fiUONuYbd_{p+1l#8?yI5(br?=etT@-C9BO5`O%&Q=@ z5734ROIs7|l^^7EY}lE$BBo8kejK$q#o2o3>s-p zZZ5TAB@`7^ic#_{S}L>(^Od0T&r8_y^4i(5R#O|iShDc%o8wKG^T^1qa*MO2?h}qB z^k&~Dm7Nax9PGuOEn{hHYB@#MK+=N2+rVY#WjW66ke>ZoGM0I-=zw2pmQ%z{EFQ`k zBwA$d@wOK*+%cj~A`o{B+j0oLwQg7@r?KZi6KBQAq5&^8?s5#rvF@StP$xL*G7df* zl4x2kU>~n&PO8WXNKPY~?;RDZ2jjBM@3xuZ>ro?}y`KUc;hFhO#bgc;<$Zko6|puM zP%j(T2O4zmtC1~ffzmuzFX8eg9Vn%0NpAiy);+TM>ieEhAHLv_%a2Cn)^FyJ->P?} zcvfC)Z*Py>T+9w3ZB@?c6NC50B{K($PnKGH1Tfg9k=PVnrytsSa5lzm~%3FT~!PD9{b2p{k&0{s@OE!Ob`UqZYE_)r&XPIJ15CyVbh(OOQe{`W_ zNa_Dnx^T2aruxYrnAJ7{p(2WXBnE*nFo=lWLpll!sOWL#CGy??wjFacu$r!`0dl}- zqy$W4vZqwFBxLTNI0P@88}aU*1^#SbT00M=3Kpi0t}K+ZjvY+FjHJf}at;F<2}@$< zdcr9~?KeibxrlAED>@T%XP|pVEkb%Db$b@H%nnsq#OmxYUA|iat0UJiFvLeV04@CR zjPkuRA8O82Q_YwBeLWjN4ZNGg+J#Mw3?epmZQVlO^1|oaM&d|SCpr80p=q>7@4J;2 zR5&+%*PGv+7iub4t*B)NvFHt9v4rg@_;qS;eHgrZNjptTYrLLGzXz4TQX^hC*&wMV ze1m~Pg#MwAjxU$k5rv5R#3a&C-3I%SPBRaz?^rY|Tcm)&O{G6F?JH8G`NR&>=JV3D zW|&;g&7Z39@$>7}>gx8s^*K5cNJ3YizbTId`&DXfMGnScz9CF7S}mQIT_}lq%Rywy z*4l~g2+uLl6rt!}sk3H~@zA;Xukyj13&I zJ;>pxywZE2ml~d}`sOqqdd=nqd+*n&G{@=5lYJ`hqPEo*9z^oWr^J3%1b3a`Zu<=% z#(c;c#*9nl3@tDWf8k4Mw%QAk7Rb%8nK{un9;-{kcleZf#ya2oxz%vIH+4zqz|`sf zr1k^k#n2#hr$FtK=`kUuDE2itCA2Hh+b%H>xK6tE3xG?&n(xr}`G~b>M#>^?HvOb4 z_UzPKUIE?7Y%VO`XgvE?)ox)B(cWQH#YJSui8(T|7nM2a+=Qnh*%f$6XvMh|mXx*= z;uKg!RFZ4l6L9YKMeXv)>kj?o;_)P%Y!Xq?m?Z$Em~9hAYfa6!SO{Q4JChvE<7}l5 zwD%~7JS`QPy?1O}&zX50vfXu2bq$xG0EDTNa;>&-u!Qe5tT)Ym{?G3yY0UuY@{Ud=$eOgI0tGw$Mt9#EnWU{EY zw=O0a8v7Pea3Xl*xYoUOsN>;;G1wE`G#Jd76CC@R$IS=HZkEN`GTJ&-`Ngh7Kl!&V zXgG_S*EhfNlA{Vxt|++X|6FRD&Q7X=8r6e=qqKORU8BH-Z82di7CeE}#!EN2aVV>h|0;1PdCcR70`!p4; z{MPTz&v7jUl!jGOP}XS!P&I7}$ux#u4znF?)aw`pr<=MB9H(9sH}TlsRR7AjoP>4e zD2I*HrP?N&BDm7Hc?iH`5AwJdtZJnRY$4R9p0Sw(Dun1E3Uq%_2qG~5s)-aXk9&OL zL0%j>lR~N1>L~!t^gwY!@AnX!Iu~S)F>t~rp@TEzy^ZZB-i^MMC$T{EVPxodDAFz~ z-k#LCR9H>PW|c^NHRuTxS}?eQJT4K&@N#-+jP!Dnihi?nR1I5t_`F~+ZP1RtH_62q z#iO&sEYYR%&=W>s`+&*Qh3BRhFVJ=AhDNsG62>$)m3V)a=lD&$KZkRo?44&pW>jY9 zfPs8^rnyvqBdiIQekFb8tqGMf$|Z!sF{3;ajTxCtNu4jH{F1eLKQ6>8_V+FLdPEK` zne)81U5#5uNwX|rI>xE&tZ8&wxFEIh>XY-(FQHT#{-EyWVyt658#09|LI8Q%I`c-J zTMO(ErP?;WjXnrp1V84&G)VV%+n$jBv{w0WC?y3p0I;3?r?tZPU(4HaNos%erHEyE}y*H)t+@%4Pk?v6rsu(HtycK(eHt7HZz?9 zJCfQ4NS8>SMh4Xw1h{|*B;gCJGs?@Egi}c-Yy=aBQ+HqEx1Tf62MK|vTgr4UK}FbQ zWLmgW$7*@Fiu6z<7TSI`?hm2+ayW>AUX>k=?DMuO=+$xh@hd1V&O2Z__{YHj7ujVX z-VWAfA{Ur!?>PY_a7uzgK_#pv*<{KJS%8G$2Uktb=VDQoSyG)WdZ2+&>rI9Q1ra&R zp!e!&{)p#Wl*Wl2rf-66b56&}&8;-TmUfH$cGlC5VWMc%wpEtGa$u+Nl~ZDrEZ-dR zI}Xkmti*3w=C)8_VgK=w-;)LW=bE<;)NmmDSYmKi|I=*Kk!6WRC&`e~^m<%ort#^MjTWI63A{!OXn)WJTE=1+Wijg^|}`_a17#DP4c&qCk(jD z;P^Ox_!>_1-#_AL>M7utu~ToL%_{5EQ~2s9UAVo+dd1HtUT#xSIl z>J{Acu4fGDD8z@HLqg7f%>Sb#_Epo~jT_>uyRh_bsk<7?of6V2FQkNpO+K+>H$mB} zf#~z+*i&-G$XC`Q11isZQT6O}m*a;?TXZ1&zp8RjDTv?|92ZrknN$kvc|cj7$Y5P) zVbw15*f_A%ux{!FIyPilPAJb42NZI>mg_O`(iJKS4pI$cs{BBn2h=5cJC(YsfJ6>b z<3Um_rNetAu^hFzegG8dDswTv6Tf1?pWG#7ox@i0*8Y zl)t0LL{1N%&eV7GjlmT3Hmn|-2$lVj_S_)8%(e(V&%KmjWRNyjt3PisNklfxzyqgU6>1K&-FaBD%&%WPlbYzi0E)zH^34*N+Qw*cF~K-RoEHvZ z$3u~>r6L40D5^C(`^D}=&wmJ+S1e|`?Le7`n!a`BWpUOt4dOKHw7=HQJhSaEfRWkc z45^|ND;znN>bq<64kN*)9pPRnEbzGjqH=m+etgv+L46-rK(#hHTuXc{Kfb&Cl2}8T z8Sv1l%=SaVnhwr|^jSM=mSfJi&exXPar!l-CiLg#+N0+Hq^0H1cOC!3Y3Q;a2lQgS z^_TzC_CSvhL7+G-X&~ZJvma5v*z@HS+PcZj@|XN*=Yx=y=W3{q!HGt%btzsEzWkAl z4B%Z2K6Z1Wj5bl&T_LLmx)c{v))pAa&QPN<`yjyZYw(~0uE;JQ@g*HFd(|GS%3Kwg zdr@9rd3WDCv}h#bGPRNangg}J9%^=Kxz;>Him0^@p+}YjGebGTQelY$+yzpCA^=kR zWIHSJnSAn#jG4*oJvHQeCSc;62PrxuPkRs&{tpm|FgXgo@R_b`nJ4f?)$Nlm+>qH> zcAO)^f=6w!JxHgIB<(H%D4|`&M zcurfwhq8FpX2?4rI7wS~RT0E3uuccQF}J4Ma-r(lrg_l;xx^Q(e!NFp>Hh#5BNick zUuo>(bnZBH%8@$>WL#stpB+1jsKg94NP!sUdypdee=1(DIy%hWc7}H~)g@Wq(o+e@nu31eE^ zB@yq#Bs3qyL`zu%kAu`i*Jki%#q*ntIg@mq<@Yr20qgAKi!FKWYgNt6?Q6%~%g*oC zxhZc`_7O}URH6#sx#!uHeP!Xi{qWH8Q1M_u(>3v8VtH@F69vKzO?(>!u+^BV%c*ii z`Jvcx1N2M=g7QEV(`{dYJy+M|tyr=FHuBMdx!>rTZ-60+l75drQk8#s=ss)5V7YeC zPD?dx0+spbF_yfMH<2}zCU)R=5b#q}SddRsaO>MSDiGvX9OGA{Z>Vcl9uXU@C}8PQ zpZrK{`^Ac8I+*;Ijq8h6KOT+t8cs005q;Z)fk!)=(1&`7LB%8;EHy;CQAS@0AdbkX zDQDRrajn^BsVmDUHE7Wz_VLs5&Jxd1&`y?XzvcaN`=uGOdUm4%0NL#S3l{(6iXC~4 zz?gq0y{Qbv%#{c^sKr}{r5e6a7KUuR2+J6gfkfsC4$o@}oAoU>#y8-}Et^oi@{=ub`)d6IN z{?YsUXTkf&9#|C+5a8i$%j;-oZENSv&lBk8`cLs@UDtZ71eM=uttJQn_- z&*wY;%)N7;nLGD9=iE6nwdd${=jgb4ny4UB0463TU{vV?E+G(QRH>OB==4{o$D^=A zb)y7GLvKvq^eS>{SyS6xumt-gBv^{{F8GXA>*co6Ap6?-?F?@=kWX&%3w|v)v^HpX zVywhlypIPlUCLcbQ8cN2c9FcPKnQ1j%Fl#HlhXAUnfqsYDF@YUnlE9uklD#Nvf}M> zDbu);jVzzz8BKt6nCLp{{YGk|I{RNkFZfLWDTC+ergr92JVSNG4JxWHTPE(Ds#-fw zaD7sWqp{0Gvq7N37V?)6zNZJ-!VtC-`2poaxs;a$Qci{s#HnQX{q1>fZct3-b7tqq1So?S>Wl3iB}paYCb~iGk_m z9k}cW1OQf10D%9`3hEzP()mH({?fvTCj5^cV{~cIUwYE8*`Su5G~(o8>$ZZFMRGXv z^wuE@CVW<1>fK(ej5@Qb5xK=>RgST!X=z&^V1CQ;S^4srf7gipXTDt6nrT~dn=>EZ zjIF>=oIAE)M28b=vV(aRNyjr3SBbct%|9}#i0^ni)zxOL>iTTVZ7cKYK164!(UExk z`Uvu{m#pavK8JUTg@#rz+MjMD(0~IKG9W1JD;zpStdWde=T)7bfNb<8=NhD858n(aKj6tZnNw z5l3FPk}`P%8R=5krI=zj?wexY<~SJ@)wJ|W)id%dVgaydt5r0}+g1|0+FFI)`6iEz z^Q{L!8yETDZwwa$l=?c3Ld zB3C<$i#Lhz;G33>_V042NAXPuY+K%+W#V&Mtrwwjcfq838P28&s$s{2sXVH2tjT_< z$r|=agiqZmV`9QsFh^PmNB4`!XNIY2_qG(|k*#XMsJSp=j+2sB2*=MvYP1ZrWt@2~ zDEjg!vjU|e-cQvu#5GTmWc$ZbCzmA}@AemlAKTnFgLw9QAD(DCP&ZdcwPtHlSr2zm z3)eHnDU&-o&QMld(@(`W#(sRm9#BMWK0%Esl0zhzQm2~nLhHO=9Y=lnwBnu9*uXjf zk06QxK*WF+7oM6LxA@l&F0?*YrG@#3t0Qdbk%L3Y@P;@H%F@hvoR zM^}n~aaW=}hG_eELIn~^0*&?%gaVI@@Ky53v#JbH4}Gnb8ACSnD$Y!rX-wUmC4;L9~>b#^nYpbX+O87gAu*helE z6QGS!zl5unaQmGpJ|0(7n3JreKiDsPk->>u9tw`3AvJbHja{jU_osPb#-frNcd$E>bf5$ux*Y9U37%;K@`t_3lTicLJ z<5;BK%Lrx?K2}<;?!eFsd!N7q`-p?e&w6B7y9m+D!N}UhvKnD1Hh2mZ9LqCx5BCKK zr()Q9%-%@^R%?f|&Bhs+l{6|n`{WwQ<~krgP;Avsm{>MCaI?APvX@?;KBK4wCk+Ij z>uq??HlO8yGU$zNRnMJlP-$-k1GC`6!NjETS7c~t*x00`6CrJdSqw~Kvoh~cF}4EJ zlyN^?Rs$4)u_(}_C3Jz`EETkI7Uy)Juz5S?OUU`Td!6shoy4t&5U##X+#q2LQv*?~ z45*fnre7zSS>*=kahvx*+16f~COUFR?K3hI`K7rrMhtrd3}X4)j6P!?D5b`&TZng(_TDfk^X7%#|Gl`+$L zPG(T|d&yLet4K}@iq1Z7-W~o*114^8m5?sPDSHsm*j*$>!If_+@pwFRmrgg{HCvt^ z_oB)^_rarhMX*v%E~0+~E#h!Oj-|-y*)(&DJ+bRXj0BuRuQ)~lCx)D}#Y>M&I(;*G z<)Ok(VE{UuG^k`^>-kEou(qaVEws9(rv7QEb?6vMFyW85$q7|rd%H=A{<))#w#C_-ZpL20vVWAywjvHzEweCv>iW+KyE8 zvP1bTB-61u$qcy4x&x;iZtNI8*>)X%xg?9L>1t9p6AMk!&2fNFs+c4~-hmt(-;2C0 zRDNN%H1+XKyE8o}E1rmRw^8ah3$sq^IgBUDtc3!W__(3uxt|L-+PogIl)pHMOev`2 z81|kmUn$jd*_(moRrV<~X#2OK^!S+uSYXib(#HDVc@brigdY>7RcMhKYqPKXhJfV? z5_OC5=A?A%e&4Bk@-aAs3(%UWMD_KD8mPk-&TC?AMenOOP4W6%ZjFZ;UNuS2rLw)h zau8Qwx;ShXv{SPhM19I3W8o1UFzoz&K|(cAbG+1D8wya9)P}^lC$6Xq!f?8;NNr zgXWFFoCVX3iUqRBwfyjV^X1e7E>7xtV0P=`D7g>u-gCx>%h|(B(H-0_eyJNEJ*$q) zv<&Qsqj;L$8fz*2q$B?9)JG`>$Jr99AC+jhG5)H&$$8TqiL5bt9kZa}?fk5x-N4NH zHU0};8 z_cGO`A0%VFj;Y?e*zR5hU-AxD`WDuCbr#G#Cmr8~OOS-Rh-Itd0p1)&DhHd4Kv@MI z$c}MO+ydwObe5HW8X{ik&!Y>+6xk{id;!F@zorR4%o_&9X)W>OUC=a@Ce8$_J4s_% z! z4EjbD2+tqBHrD1~o|LU%%@^S+k#{*S6rNnxaB~M;SQGf#-gey$y71ML)-N=ES|^wr z6STmIGm>0%S@5_*GLGY4cm+BVWv{!SV93Lm$UQqMQFdTSKNY$#&9bsv!R>NXd#->Aep`!&lK+mB3KPsy z$jTv@5%&w>kgSd4(|Ij~V{}>)*JEw@doy?Dloob4hutoc-P54IEr8MJlH>#9%NHIt z$GNxJzC<<1>;3D}b>{OnCJTAUf@Takzv zQ_vPg<#PRZTefb&gl~@lhn4hx`2G5!D|bABU+;X+=lIvrQzJ*^q_GR)JLLBP;79UD z=-u_7-)umUkzU~k38O5K|0ZZ3xJrkiJK}H5d&__Ri}W|W+zu1#oezCjZ~XLgP+U4S z{{oQcn`{iHGHe9;L#qDSX7}cqi)elE`=Mt}Z+`Q?{AAyv#e2Q;F_o?;v;ml=L?C|D z6;P7-?cPNv%%zE`b6UfjO~;GuvjaP9nu0=z-PeHr!Wo%=FCxYv5J`c(N&7)XO@x1b z%kPM<@Kt&RM{-zb#o<@Xn7R(Dc|;3I4;E{Wiuxjn-i6UKSHOUq|1#I%V)1ql*R1`8lN4v=ABZ_i?8S!q!Fk$i*R;| z!1-C}p}$9US)sOFVHxF%l)mzmbSoY;?v~lHJj^deTKYm7yTlrKnTV40#=!I|hCC<7 zd4*Pa&|CFk-fXRy=~(}PD*i!`qgpM5bw{hwtUiY4yE$z-p(%e??m(PBGvrKKN3?3h zN2{3sg^VI`b;wROr!)_bkXHFN92pw7O{#8Z%*sk33cqkZPHk?X7ndBbCiz&J-%N-D zltLIZd&FY8Bic`eF>4P*gfE+GX}v{qEPdWW-_p%VmV#5>x-B~aX)>=x$cpw`VFzov zdMS?cDio#u>CMayRgg{dvPnW&9-s0Lv^>;rG7wedAs;i4J(Q;7Qql}hc4f^Ez9oaV z!D>wC;cv>@o5h)MeIAzgfBM<#7`kcS3u?q&^CmG*xT{`yiT3C8)L`A4G1RtXYD{oK z(*pDKu?iY!+DOoA%`tAhWNA_7Sd22gX3`9&p+3HHW(0>4%4 zdhY5^{d(~&yNI!_YQU}*A=zkKZbw%>6rw2Y;QUsFTS8zqy0PhH`}Y?#B@2yLcr>0Sbzv+UfN-zoQ{*^Wneq_7YaPCW4= zG!NISS5Xo48xt?~tq^(HkSs1-cYLWOgW?N!rYnSb6@AT5P9&RiHHGG(Lez7Me5!`d zvXU=JPx}RzRhzAnW62lDP$N2^IxGqPQM;VlH3jI!Yq$tZxx_4Q4`X9oGm!EOt;HwS)bTZoQ>X>wCBp}K_f*YL#;LeL_=d#v`0mb@E;uBmMn;NwedKo7 zQGolFxziiHrPf~iXp@s6$3zvEQIZ(!G5da8cZ^cPsCf&;smQPS;>ADW2-emJFgll{ zk8SpOi;;9M(P_w9YrCMR0W-mlGi#Dqojs{Io$@{POO*jVzb+KoWUy0=l4=4_(JM~L z{YI?Ck;>>q)QV+i6r^4q)J#DU+HDAZ%*Cjb480INFnCB6^QF1yfQtQ$+W zc$Hc-NX8|RB!kP~6FHf-wIR-gujN6T%3^Mh^+OHieW!=tFF)vbtC^c`?p66~9Nvtd zB>*M+r|1nKm&3&2mf5lf-jFAuE&~lACcR)=vzZD^%J{HmIZCV!HcZeeh1u5)LdC(( zA+X_K%vRarqb6EjW@YqjGp2tBk1=vD=&mUw$j{w3d!M1qojlv$h0ucOv-*3!K7ME% z!A;H5`p-q&@JJ|1Z`S#zkmwRj5pENWp7!TivQoRc-!=A128a$i1_hW+z&>!gFppzm z##d%tR|JhgK~Gb;yqG2Q8>VJ^Kj$Fz#g9G!=S-{oHm?pVO`;ec;HUQHsin z30bRyZc3kE!V$Ib$<9y6tQf&2O*P@pISqq%<~xJG(Nz>L{;Y6(J(U-=a{jaN7qo`f zX#Hx%qe3IC-J=gFz5j?o-x!jpBA%VWBV5<)VAPzs($}lQ3c9TCGoIeOGbkeNEuH2H@b9+BkNtvtm!D%AE>YI>@t zm>6zMUL`Sli))Zpf8$D+DI6&F z*PIFm(xNbf(q%z(urW9g_pfdFuZ;vPT>y>#pN-+K+g<`18~_3UIEeuO0>FPo4JO+P zr2hx{Z(%0-F9r|;3uy&1{*7MH3Zw<@!n#_4Z2x@v-`)q|RR92LH2?tl|M+Ob9{+%> z|K9%JmlOUEsGtf62=MfA;CF&NbAb2=@&&rP>1hH{NCE$EI^Ja9R*##c{%1m~g9ZTn zN&i3c78cP4Wcrr}aqu|_^3RdfAK?GyP7NDq12X;toi=7Zn*IUo{fR{KpEv-3NLD+L M9etwZ&mrLd0E$Qb_5c6?