From e9cf75ee4872c0fd01915f420efb11fe18c3a765 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sat, 14 Mar 2026 12:04:20 -0400 Subject: [PATCH] changes --- .../controllers/portal_assessment.py | 5 +- .../__init__.py | 0 fusion_chatter_enhance/__manifest__.py | 43 + fusion_chatter_enhance/models/__init__.py | 3 + fusion_chatter_enhance/models/ir_http.py | 18 + fusion_chatter_enhance/models/res_users.py | 31 + .../static/description/icon.png | Bin 0 -> 55366 bytes .../static/src/js/chatter_panel.js | 424 +++++++++ .../static/src/scss/chatter_enhance.scss | 341 +++++++ .../views/res_users_views.xml | 23 + fusion_chatter_enhance/views/templates.xml | 22 + fusion_claims/__init__.py | 47 +- fusion_claims/__manifest__.py | 2 +- .../models/fusion_adp_device_code.py | 31 + fusion_claims/models/product_product.py | 182 ++-- fusion_claims/models/product_template.py | 105 ++- fusion_claims/models/sale_order.py | 14 +- fusion_claims/static/src/js/chatter_resize.js | 40 - .../views/product_template_adp_views.xml | 77 ++ fusion_inventory/__init__.py | 104 +++ fusion_inventory/__manifest__.py | 68 ++ fusion_inventory/controllers/__init__.py | 6 + .../portal_inventory.cpython-312.pyc | Bin 0 -> 19432 bytes .../controllers/portal_inventory.py | 422 +++++++++ .../controllers/product_configurator.py | 27 + .../data/ir_config_parameter_data.xml | 25 + fusion_inventory/data/ir_cron_data.xml | 36 + fusion_inventory/models/__init__.py | 23 + fusion_inventory/models/account_move.py | 59 ++ .../models/inter_company_transfer.py | 316 +++++++ fusion_inventory/models/inventory_booking.py | 71 ++ .../models/inventory_discrepancy.py | 183 ++++ fusion_inventory/models/product_brand.py | 151 ++++ .../models/product_brand_pricing_rule.py | 80 ++ fusion_inventory/models/product_product.py | 167 ++++ .../models/product_sync_mapping.py | 34 +- fusion_inventory/models/product_template.py | 356 ++++++++ .../product_template_attribute_value.py | 68 ++ .../models/res_config_settings.py | 112 +++ fusion_inventory/models/res_partner.py | 60 ++ fusion_inventory/models/stock_move.py | 44 + fusion_inventory/models/stock_picking.py | 222 +++++ fusion_inventory/models/sync_config.py | 630 +++++++++++++ .../models/sync_log.py | 4 +- fusion_inventory/models/sync_stock.py | 30 + fusion_inventory/models/sync_warehouse.py | 34 + .../models/warehouse_ownership.py | 78 ++ fusion_inventory/security/ir.model.access.csv | 33 + fusion_inventory/security/security.xml | 50 ++ fusion_inventory/static/description/icon.png | Bin 0 -> 66146 bytes .../static/src/js/margin_widget.js | 17 + .../static/src/xml/margin_widget.xml | 10 + fusion_inventory/views/menus.xml | 72 ++ .../views/portal_inventory_templates.xml | 847 ++++++++++++++++++ .../views/product_attribute_views.xml | 38 + .../views/product_brand_views.xml | 175 ++++ .../views/product_template_views.xml | 174 ++++ fusion_inventory/views/product_views.xml | 81 ++ .../views/res_config_settings_views.xml | 117 +++ fusion_inventory/views/res_partner_views.xml | 24 + .../views/stock_picking_views.xml | 137 +++ fusion_inventory/views/sync_config_views.xml | 404 +++++++++ fusion_inventory/wizard/__init__.py | 5 + fusion_inventory/wizard/serial_scan_wizard.py | 135 +++ .../wizard/serial_scan_wizard_views.xml | 34 + fusion_inventory_sync/__manifest__.py | 32 - fusion_inventory_sync/data/ir_cron_data.xml | 14 - fusion_inventory_sync/models/__init__.py | 6 - .../models/product_template.py | 33 - fusion_inventory_sync/models/stock_move.py | 116 --- fusion_inventory_sync/models/sync_config.py | 257 ------ .../security/ir.model.access.csv | 7 - .../static/description/icon.png | Bin 46059 -> 0 bytes fusion_inventory_sync/views/product_views.xml | 49 - .../views/sync_config_views.xml | 179 ---- 75 files changed, 6991 insertions(+), 873 deletions(-) rename {fusion_inventory_sync => fusion_chatter_enhance}/__init__.py (100%) create mode 100644 fusion_chatter_enhance/__manifest__.py create mode 100644 fusion_chatter_enhance/models/__init__.py create mode 100644 fusion_chatter_enhance/models/ir_http.py create mode 100644 fusion_chatter_enhance/models/res_users.py create mode 100644 fusion_chatter_enhance/static/description/icon.png create mode 100644 fusion_chatter_enhance/static/src/js/chatter_panel.js create mode 100644 fusion_chatter_enhance/static/src/scss/chatter_enhance.scss create mode 100644 fusion_chatter_enhance/views/res_users_views.xml create mode 100644 fusion_chatter_enhance/views/templates.xml delete mode 100644 fusion_claims/static/src/js/chatter_resize.js create mode 100644 fusion_claims/views/product_template_adp_views.xml create mode 100644 fusion_inventory/__init__.py create mode 100644 fusion_inventory/__manifest__.py create mode 100644 fusion_inventory/controllers/__init__.py create mode 100644 fusion_inventory/controllers/__pycache__/portal_inventory.cpython-312.pyc create mode 100644 fusion_inventory/controllers/portal_inventory.py create mode 100644 fusion_inventory/controllers/product_configurator.py create mode 100644 fusion_inventory/data/ir_config_parameter_data.xml create mode 100644 fusion_inventory/data/ir_cron_data.xml create mode 100644 fusion_inventory/models/__init__.py create mode 100644 fusion_inventory/models/account_move.py create mode 100644 fusion_inventory/models/inter_company_transfer.py create mode 100644 fusion_inventory/models/inventory_booking.py create mode 100644 fusion_inventory/models/inventory_discrepancy.py create mode 100644 fusion_inventory/models/product_brand.py create mode 100644 fusion_inventory/models/product_brand_pricing_rule.py create mode 100644 fusion_inventory/models/product_product.py rename {fusion_inventory_sync => fusion_inventory}/models/product_sync_mapping.py (54%) create mode 100644 fusion_inventory/models/product_template.py create mode 100644 fusion_inventory/models/product_template_attribute_value.py create mode 100644 fusion_inventory/models/res_config_settings.py create mode 100644 fusion_inventory/models/res_partner.py create mode 100644 fusion_inventory/models/stock_move.py create mode 100644 fusion_inventory/models/stock_picking.py create mode 100644 fusion_inventory/models/sync_config.py rename {fusion_inventory_sync => fusion_inventory}/models/sync_log.py (92%) create mode 100644 fusion_inventory/models/sync_stock.py create mode 100644 fusion_inventory/models/sync_warehouse.py create mode 100644 fusion_inventory/models/warehouse_ownership.py create mode 100644 fusion_inventory/security/ir.model.access.csv create mode 100644 fusion_inventory/security/security.xml create mode 100644 fusion_inventory/static/description/icon.png create mode 100644 fusion_inventory/static/src/js/margin_widget.js create mode 100644 fusion_inventory/static/src/xml/margin_widget.xml create mode 100644 fusion_inventory/views/menus.xml create mode 100644 fusion_inventory/views/portal_inventory_templates.xml create mode 100644 fusion_inventory/views/product_attribute_views.xml create mode 100644 fusion_inventory/views/product_brand_views.xml create mode 100644 fusion_inventory/views/product_template_views.xml create mode 100644 fusion_inventory/views/product_views.xml create mode 100644 fusion_inventory/views/res_config_settings_views.xml create mode 100644 fusion_inventory/views/res_partner_views.xml create mode 100644 fusion_inventory/views/stock_picking_views.xml create mode 100644 fusion_inventory/views/sync_config_views.xml create mode 100644 fusion_inventory/wizard/__init__.py create mode 100644 fusion_inventory/wizard/serial_scan_wizard.py create mode 100644 fusion_inventory/wizard/serial_scan_wizard_views.xml delete mode 100644 fusion_inventory_sync/__manifest__.py delete mode 100644 fusion_inventory_sync/data/ir_cron_data.xml delete mode 100644 fusion_inventory_sync/models/__init__.py delete mode 100644 fusion_inventory_sync/models/product_template.py delete mode 100644 fusion_inventory_sync/models/stock_move.py delete mode 100644 fusion_inventory_sync/models/sync_config.py delete mode 100644 fusion_inventory_sync/security/ir.model.access.csv delete mode 100644 fusion_inventory_sync/static/description/icon.png delete mode 100644 fusion_inventory_sync/views/product_views.xml delete mode 100644 fusion_inventory_sync/views/sync_config_views.xml diff --git a/fusion_authorizer_portal/controllers/portal_assessment.py b/fusion_authorizer_portal/controllers/portal_assessment.py index b69c4311..298235dc 100644 --- a/fusion_authorizer_portal/controllers/portal_assessment.py +++ b/fusion_authorizer_portal/controllers/portal_assessment.py @@ -722,7 +722,10 @@ class AssessmentPortal(CustomerPortal): # Post message to chatter with photos sale_order.message_post( - body=f"

Assessment Photos
Photos from assessment {assessment.reference} by {request.env.user.name}

", + body=Markup( + '

Assessment Photos
' + 'Photos from assessment %s by %s

' + ) % (assessment.reference, request.env.user.name), message_type='comment', subtype_xmlid='mail.mt_comment', attachment_ids=attachment_ids, diff --git a/fusion_inventory_sync/__init__.py b/fusion_chatter_enhance/__init__.py similarity index 100% rename from fusion_inventory_sync/__init__.py rename to fusion_chatter_enhance/__init__.py diff --git a/fusion_chatter_enhance/__manifest__.py b/fusion_chatter_enhance/__manifest__.py new file mode 100644 index 00000000..ac22c15d --- /dev/null +++ b/fusion_chatter_enhance/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2024-2026 Nexa Systems Inc. +# License OPL-1 (Odoo Proprietary License v1.0) + +{ + 'name': 'Fusion Chatter Enhance', + 'version': '19.0.1.0.0', + 'category': 'Productivity', + 'summary': 'Resizable, collapsible chatter panel with per-user position preference.', + 'description': """ + Fusion Chatter Enhance + ====================== + + Enhances the Odoo chatter panel with: + - Drag-to-resize: grab the panel edge to change width + - Quick toggle: hover button to show/hide the chatter + - Bottom position: move chatter below the form in user preferences + - Per-user setting: each user picks their own chatter layout + - Icon-only topbar buttons with tooltips for compact display + + Copyright 2024-2026 Nexa Systems Inc. All rights reserved. + """, + 'author': 'Nexa Systems Inc.', + 'website': 'https://www.nexasystems.ca', + 'license': 'OPL-1', + 'depends': [ + 'base', + 'mail', + ], + 'data': [ + 'views/res_users_views.xml', + 'views/templates.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'fusion_chatter_enhance/static/src/scss/chatter_enhance.scss', + 'fusion_chatter_enhance/static/src/js/chatter_panel.js', + ], + }, + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/fusion_chatter_enhance/models/__init__.py b/fusion_chatter_enhance/models/__init__.py new file mode 100644 index 00000000..5f0fe0d9 --- /dev/null +++ b/fusion_chatter_enhance/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import ir_http +from . import res_users diff --git a/fusion_chatter_enhance/models/ir_http.py b/fusion_chatter_enhance/models/ir_http.py new file mode 100644 index 00000000..8719aad7 --- /dev/null +++ b/fusion_chatter_enhance/models/ir_http.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2024-2026 Nexa Systems Inc. +# License OPL-1 + +from odoo import models +from odoo.http import request + + +class IrHttp(models.AbstractModel): + _inherit = 'ir.http' + + def session_info(self): + result = super().session_info() + if request.session.uid: + user = self.env.user + result['chatter_position'] = user.chatter_position or 'side' + result['chatter_hidden'] = user.chatter_hidden or False + return result diff --git a/fusion_chatter_enhance/models/res_users.py b/fusion_chatter_enhance/models/res_users.py new file mode 100644 index 00000000..7323b4a2 --- /dev/null +++ b/fusion_chatter_enhance/models/res_users.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Copyright 2024-2026 Nexa Systems Inc. +# License OPL-1 + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + chatter_position = fields.Selection( + selection=[ + ('side', 'Side (right of form)'), + ('bottom', 'Bottom (below form)'), + ], + string='Chatter Position', + default='side', + ) + + chatter_hidden = fields.Boolean( + string='Chatter Hidden', + default=False, + ) + + @property + def SELF_READABLE_FIELDS(self): + return super().SELF_READABLE_FIELDS + ['chatter_position', 'chatter_hidden'] + + @property + def SELF_WRITEABLE_FIELDS(self): + return super().SELF_WRITEABLE_FIELDS + ['chatter_position', 'chatter_hidden'] diff --git a/fusion_chatter_enhance/static/description/icon.png b/fusion_chatter_enhance/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d0bea687fd3ff22f1f96062efcc2357b30d95e GIT binary patch literal 55366 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�&P(GOrTC#KVS{AW?P%v_tz zO%j7Sb*+{7C(&MdFBWm#yvjv^1XT|#RnJsm+Q&MxU>@%y`1g7ztLljPWKurd0|`T` zBJe43G!Hp&-`D{VY(P=xE$vuWHuuOI=Z%339#wYVi)IAR{Q*OX?mEBIg^i!>gkA?B-0AfxZKpL+FTV zW64@OUOc-=3k_gB;bf0@9_Lca=zC4`1ftjwDcZxiScGScUXA~PLC&L0E)x{(bTY{s z_gg8^Esi%;Kz%9x{V;pfJdbds?)85nRtL|D24{j&e_GF%wg`oSiNrK!9^(XEq z;oJ>wv@?fB{r0HD!0%eY7a%}Vna_u%IPewMbcvL7+u@rbm(==bhu$=2Oj}H6*rv+u z7CEZA`Ln=7E~@AtXI&hq0+c=Spn%#Y-`~~vI0A!w8RBdjA`da_tWWY9-k7C!LHGE; zFW%ec`!-DMK#x1!w~2Fku>(IFaufP=JGU+r2qQui_x7-q#`WNBa3 zF1twoQ0J5AExj<_^37=X$0QUkziXLNLx+OakiY`^jRlfZgljLKRR|l(!``DNad9%u zAv>1vOC1Jxe|V6dgoxEmPmT!H^1xO1U=AOYHzst{`HQAzwr9A-6gh`iEQPa`Zx<0G zaxe*z^4i=*w{@9^>32j9s)V5*emBK_B2^1ugHZ?XiPTGfs)vr6E0#E^BO|{hcTv-l zv^qcfJX*8Vj+(=v*j*~dn&beZsLk7no!y6!=*PriM<8>dKS0&LIUrHwC)eUww1XJh zDKV3D8V!+y$HoLFE|~oLbWDEh_X-$K!WNs;lL@QwnFQmABNFm+PmH;fE#VD5tix$d zH;!j0H+001X6p#Y9!m%k7`HXBds-`ch7cB1`Hqg<35DgR1F_d%EIcvXH0%jV>6$x_ zT+I#X3=EApwdo2zz(qJV3jgLm_jT}OMS7+CQu%hX-Sc*TnIm1UT`1}hxFrr~CyzL$PdEO*Cu zu@rmRM7(lgI|`~r3oX<}9iLL5ir3o@y^UYa(B7Hgeh+otA4vHjh`n$^;J5BAcD4gM z?{h)-Nq8QmB(Dr&)>xQH>w6}sMeeHg*6%_ZA&?I_@Xtoe>A>--+BXMb{F61*h91+< zr+G2gY!QU&?|q$tXZYaiZ1}aS7~(-wN#m%_5fCZe%_acb1b5eRmT;o?dNbyIgG0DgAu0G8oAZrz4eZeAZH@0~=c2JG&aV05Z{ z?90hBgXR9~?imbz))nhW6YgOk1HU`I{>{dsGx#G#Ty`UnPgYhCtbD<$%~T`5NLCcU z{{8+=y4QrcDyXiy&DQNxlN(P1oBe@QS2ABhF)qzIGl;h^ zJmCZ{cCapYg7gCH(LRYjV$dZrKuZ#a@;&Zq5ZyO$6gxLUNyR!PUkg$a5#1#TRxQH@3#_ z1?5-Er+}(ExF&&J`dIhPShX-fhSk8clr*!Eqd7Cf9rE`KcqGO(-0`_=q0aR8g+yBi z^=})*I^t+WN==7R}~9<2I!ogj^b7TW)Eq+%!q1eBE=s z>iNOzP*CdI5wcO(aRKpxNGap#-Pzb-~GIrFCM#2+!^(JlV_I) zTdAX6Rnwp2m|`07tO)k}knof}v>VtaeqgwZ5M_5n;usq+Nxxg5p&x;*i}C8`g$iyN zKvg7a4C0RiiS3<6MVjLwhbH?YF580Z&L)BZenGUKR!uRjvmHN5G|CO+Tik0IA~m5b z2yRJF#n*>0`Db<29`VxbCC$0rtjNiOoMq0IY*V&i03#y~0-X z4>n9D0-NN5OFlkX=V1ABY|%L~xO9KM67+rJvz?2~zUn5qxT|vsCA`1NBupIO_uy=u zQ1@^=T?L~Lo9e6HZGy7bcg#9AxgVn|TC5K6Ub_}Wu`Y{jl zwudh`;SlZ*@w8s%)cO{6k6tuh*JGDmbbtJc6Lz1#d%mC;x+mBm8kcJ$7P0#;JiCw# zz6Sc*9|3gX$uqb&Ct>@Yd<;eMoNy)6iQ)1H7+{7gb zdp*|6{*GON-2gcc+wTd`GdysCfc_bRK3xHQseTj54JNbtp!qiVV3Gyih%JD3Mi;<) zV+!EyQTgz8Y(Bh0G?IztN9JjHs!?2|oV3C6w_{PfjO4rUyik`|)|V!&Ez5V2WGEwT zQJrJ*sAwJ0Z!9}b7o~j{gWaq=y!2z~(rhE8y4=>8l#_NN@|a>IVg4;HgIyJ=6C>*8 zvVDwfGpaK`C$(R8{m8w<`-*yf1m?#V!{DS+7@AB#wohvhwbDcT%HSV;hN;ctt^lnXC7l~^J#~h!{oh9VceIE zVECqbFmP=R=)0&I99)Hrwo*Muh)fFUv#BCEV|JS_Gf;L z*W&@C7r8j-I_yl$lMB&Fq0o;Lpr3+%;f@0qZMAaH?S^nnc=K2e`Ut$?LlO1?v#ro~ zW-;`hW`SN)QB#Vb=TssK^dxC2B|TNHW6{ccaOw3d#yV3?B=y(JtbA&bbZq$;7TjBc zkHg#a;N?ByilE>R^u9%#?m@@Y)7|6M`uuoPEiBECC63o!%}-|1&QDQy zQAeaF6=J^7&_@rcj(Xk6{p>f(iji9>z0c7LOJP_l^XL@xG=05JWd?dxc=XF*9>%Gl zr}MD=dX62gXZm5)$<+|M_c>gjH>VywQ2~861)NKJ0LMYcuzk|kO(AYaLm0NPE(}^z z3wkbj4hAIFfKy8*fMe|{C|bJ$iauTmmi4Q_`srG*Zu}5RP^B9`0^g^&mR>s>X0EOe zy&R&%zV?qn#Iq1VE=vA;rzsy7Tdj$x3kvZfU z6ml=soje3R+YXn~J&=5OCXC$odzgvdlYl;(hU~%iOt4I$|$f_|(yEaV=YJd{gD*cs?;6wuqUAHF!Jd-a6~`T_)f z-OcH63&Zfch2&Rjz5LyNldl}o_P9xv$$q*kuoZhw^H@xbwf$?(U+?qjUsqE$o`g0h*^gm$gmg%H3XC9XzM{hoz zfW99=|Edv;-c}EyH`IiItExl)rO!jpInNOeXXv; z-iCs%hVSH0YRL;UNtc?zqN}~(LRJwjQ#|O^$?xC!Lcp#+ao0g7591sZ^zH~c0XYbA z&7+g2?sk}ikQZ2-;BfiC&gG!;bNMvUayJ*25jotv9@?l}s{F>ZTke0MT9=ngt>*=sR)%Q@$?I)wrsb?3?OgF% zxI6)Hdv&=`+%5KJ8F51icA@-Vi~r3&Yme zfT)$vL-*8Yp-bX_L9glm0dr^n8aB=QIUHT^uW)V2|Hk$Bze4(kU&6I5{|3iC`we`) z^*o{Sf}0Aj4}TCxJUV$R?w0J)F?8=X)uMpzWa2lJ++YIwSI2D#x&v~G zJWycuG8KFEw8*QrO3B9+uFOZ@v#+Qwty9AGg=j0(`e5loQC7n0i8h5n{iw$_o=>54 z9)6i=0J6rc~Xab zmVlgu?8jSE%{bPQflmIq4IxiB&;&tmjO`mj+_pL}Y{LuCeaW*hD)qOpef7UV`lr7D z&-PzH`B%S&@`L{l<;Q;m56=7+9$b7DzP<7S{N;LW_|x?|;J#cNZl0+HpB}0S^Y$U^ zhw8(kqm3ZtSQAJ+(Tst9(gbuZd}p91anO?x^m*vflPYp$2*>j7(!5T--n*a+3$mwZXyDC6JltfXsaMPIPtw-^(gc>}uMqO$d<* zC5OI$?S&kaUS`ban4N>6zL~sI9i9$%ZUrF}bX@avRv}ZkV~9Fg1#T3#6$rVhvX#83 ztJ^}P^SKIwm1&YEufZO@ z7jEM~yq4vJ^LI<&(4}ISyr(a&(W}D@1f9S>OY`E~lM~2A*nX6S>ng#>;D4^w*4D;cK;u6?)@)t9C{X<$Daewnd;y>R}=gf>w^DMBk*5o1^%lY z!GG-!P=4bN@ZIeWP=2!+Tsc=4mL04GNfh?Rkb1l+q@Ltno&Mk?djh{egzg5=S?E6h zd^?zPu_?^I*bPqKD?o5PaEGkZ3!e=1v$vd(ya_>{!aRDc{PhWXbQ$*E({1qSZY!i` zJLqehx3hKK;kq40cTDPsYI7%q!u9=w%d^6qca|hWnVTy_-7FJ3&)>>&Qw5hX+byjQ ze}z|RXD;!&uVl-V#BDdFy&BMY)ZrSse2p1xUcHNwCy$E z+~>am*O&heC13p>O7=Yu&ZD)!bFwaY&(;V3g~kYZ3-DiV3xTUILEw64D7)1Y%5F!Y zhCtwUf6Tv!z;^`OwMMZ1Xl+<<7-2t-p8Yrp;hS-<-dcJB-sS+fiBi$J*L?pW_~f8zUG9R+5CO- z>|ou_!F`S~ui0`W0Hk_`a$bkF&(Yhf(vFd1tQT}n%K2zAd5``^mU!>{36v3RyO|-q z!=7PY=Z8zYo37igbLloOm(n)NtCd}s+NmOSPh4@qs1)*}Bz6Y+LIO0C2;)`I$5#dD zmrX!tkn5nQ7Z^c5bK44sFWX@Hp7Ahz&vP)He0@f}dK;z_1aRG(Pe0NUrs4WL;ZRc+ zw(n~Q6TWT$iC@-)TigE~O27CG6zzHjA+H9G!!^KtybgFyHAK*xf$u_F^yDw1Cw~qgz|LM-SObRJpjJB^%{7uH-$~d>q63z2I$psy^f$K<9a7+J(pHTO>feVw^*{LZPeSz{Sc*LeI|#Y-C|kdGif#_t)I3@I>#+~n%L*9 zD~0~ktk5-{eC=k3!3*s4Eja&OaX`|(6d1bu zd6;^v1;X8yd-662IO-Sy9X=mg6kNrzfUy+&)JsXz0eVSmtH~8J7c)s6#_TgAfWSyaVq2jbn<7a-Q$btyY4Rz&WBEe@}XlCYG58!hXF#lRJuKv z*-4)7sjWXr>t!7V8ry5_WMQ55xNqM-mrB^%_vd!CKDV_WsF$@LkdONU>`SN+&l43@ zq-zk71v;QQ3Jn(NV(2uOh~+yG4VKFlMX@%ztyt@?lc8=gt81bTX8n@$<7FMBV|A!N zT05eFMJV1!R1wSb&;Ry#D-4`xrw?I=BonW0r{TK*UH0k}^hM~=tM+?zpV6b6fKEbL z0{Ut6=*O-&Vdar+Fl1M4n0%y3FzA{`=b)1(?FXB{lzok0Jg&_TZu>1*xBef<-}Vex zc0LETJVZcNv`zT}I_YXB17N-X1Nd3%G>6fYv8^d$iPtNb@pH zqw}TuavNQpM=5QUa;?oMuF-|?_86ifrZ^%CrY-onimBcv`>{-Kb7}TCE84BhritXO zw47>ev7XlY<8`FIy2J(7lhtL6T*u0#+C#J(BjqJq7m>%$tl99hlWXwq_+sdhPyz$y z*y)2f9dx!%Cx6jKq&3!*&GyKw}uYw;`r@MHpGDBmzYg9@?}6`1FZAjIz<*;H!af!PcV{8&X;7BA5r+RnW>1D%C#Z|#9}rgt5&Ajc$>a6jCq5kx4LATLDNP5dY#@}!Tnm% zUIM*mlt7=EHvBB8Swy8l>O*B-rk6{$*;3g|+|M+rBef&Pr!wn%CYRbyvXgUTeF&RP zuQN-LRIfLth5GQ%-!HKg1|Z;32>2i#wv$OdS_9p|LAPrU<)Vd0UsZ*F)RJxzy3@g} zf$pQfhjul~1!wQr;K<4Rr<7ho_9d8D%(;dNm?hW+n zUBP>$ANZ~fMhyku^%3B|6^C$7gFyN`gnl-K-+z4|_^!SO{>vSq^kRKjdZZ4_N3TxS z=}G9-lTNip$jN_+;X1<}#LY!bJJSpjPIQBVH*)ZEy5VLn`4t`Z*~xX#uZ<2meOZQw z?gaGncL?YXNdA<7&e!N^#_vjnHz#G}9cc0wY~)qRzO%_+yjh{=G^QTY^fb*UFdJ1u zF)L3XDptzazB{$^vIN=A)I&OsuxtG!u=Y&GzP0vJTGZ<^vjjbs4Z~BMyylnEflUWD z(EvzShRd*6MwcwxazERlH2i%WbFgvgw!}v4Bko{pTR$^GbCO zmgLa2;IEY0kDRAzJC%SmWPL?JlYz;^A^Hw#qe3lB9PGGu?E&171uSGI>vOhuaM1@!ZG9dP8D1rA@f!&P0rkV&kdi1TohoWu21Irh`E-gEvHD7(-RGSAefPvDc#qqG0- z)|z^9_75f6@gK8n3$t+D9(S}gtULE5{Wr(g5cJ!5UJTtyL?f<+Iq2yEbQ-#Qs7GJ$ zX)(M%89_&nt%5#WJY`K`9wBC-jlNr5Q0xIqiI>SHr7NK#)n?-=k@h8u&BodVwN?5w zEw>r_75$JGPd?dWr{OAj=)?v$8|*`flDXt`vSJry3xmstCNnTpJ3WSK;}U(Ubp|Kv z=Vds*1*5dOgjY|MKu_hMudKq*U3=hi_BK=mbmGw`lRskFRSzz2s0P^^ z>canJ?md9xII=a}ySwkji`|Xgh<$f=Z|uy-QkLFIA|;aYjv^(B-h$qW6usy@Kr6~p zG@|za=sf|#lLQFwUBk8a07o-(oo002Icci0s;fazd7D z&l-R*zl-^|P;a8%fZ(nE7|-{^^4B4dNy75X?yxhdJ*-LYffgMhXFmh=it_CF-moUU z4=ldf3l?4<2^Vv0kWJ4AL${q?Z;1jr1G}L)0(N@(Yl*En5_GialNHdp%kJf%i;WT# zyX`sc1c%EDb@l+l64K>VQi9SM(k0r^qlBdzOloXnUhN{1u12G95V8OMX znnl+^N2`wIb1!#;4JV(6lHJci#g84KYX4JEeef}`9sWJk9s3=^{(BayHzqs=O{bp( z`?+Vpaj`wZ-W_4@4eq4==*GW|*8Lrf+uugL4!(4Z-w{+lT4R6uOQ>E#=l(?j?AiXdIIh9_F&x71;XA_-xAIy+z zEAGuEi_TqliqWTRlCC=fE`_j9+3aOAcnn&-OJWNwZIg`p=wS0>gtf;I2QA7h+6c)< z9@kht9=R=w_Go1;+Cod7$v4Mc@aZy_{$W?(WR^=^gp%&-<~B?OW^ERVHep1W1gyLT zgE!HN44y(9cg645M?aqgUcF8oc6O_c#p)dNiCY3N_fc4M0=-&*ULM7ws|#`kH34*O zy^vZ!ae5QR=}mC>W)Vz{9|Y6ScYrUFq*X`A33PP5mtF4#vo3Xq9mm^4#jYMuyr&bC z?|l*~_x}NE4*d>nM}G%(2zvdAKR`qL;|Tjx&~)Y*Xgc=-*e`Se=jC4Dy7n@-Z}dS| zzBgLvpL~I!Z}LW1*~yzC zL6`Y9!`+%kpn3svk}*#>Q9;*1jBfE2xRr?^>bM5!_s^}w-wU@PMxXnrEIJ20)H>)C zr`tl}7Ml+;irjD`*8!KZ8{lG=8#bKZ4dWBK!sl1fRZrHf`qCRO!;)(+!Q6}8VE&0t zkg@wMsQ%#%sQRH3RPAmDHT#}`+JjG^Wq$%KJL<%fP{@aVTzvh*CVeU3^-RXnv6%cq0KuXvR zWt$`GtlG6|#Vz31L3bO&f>zyl1$eUupt|D9dV&tQd7^Mfk<}!oZ=jhZ7vsKtgd1jB z1-(vegSF9uTnKWj0{DRzae7V@T)f=~$8KV*9v=gf&vu1H*U6gqW-be8=m^vHbbuY-^?~?r`@>aK+IRio*7toOcUNC1+S3ope(Z~GeP5_K&<|=4^@qB{ zuS5Oe{!o8}g!v)XEApZ>_c5=fh^@AV4WL_Da~1SL z0eS`l-N8YRbFs}2Qx(uPi;n+Ty6-x0o*lkEL5~#nLsE7CZsc$!vD6PYvi&TdMEM+% z&kl&xujeh497RcN9KS`KUy-?-r#CUZnN6a+XnV)cj<06;VCAcoot5uzH0zRxLS4NWjt;Lx`bD=>{ej6GI5w>T!A-&K5+|L^hXIgEyk&k zM=Z#Rm3JPe2QW^T?z-f4hynGX2s@+BC5sz1!U*b80dS70f+@n2kj2^L=I37?(o z22+lAf|2{4hmXE{5(e#f50-Rh&Adn;43;~!I*U}m?|v#lr2WlKb1CE z4E+M#e6;HC&1!XZ~-G6f! zGk&A%uama@3Fdy&yyp>s9zcu!FC6qJ)?Bsd{C;{6^3Z+H!dNUh-wD@pFjl|Q1n09F z;KWTEe4e-%#wENAb1wCPg;!sK&oO46j`91XW1V5bkvmpWm{7Y_IoE%m2MoULoIqSne#v<|?embEgbRo!4^+`-E6 zU{N*%HEbDe^>o8Hf;?7t+YMG!f@=CutBZ1K{B3Eyqs8cLvFN7wJYwPQSAyH>?X@VH zAi@K6)m{rRP@~toex9`T&#>r+(3(dEI&GL~9rUmUI)Ok|J-fok-1qCbPPmG&U$~7f ze3l&!CYK`EQy?a>H_X2HDtvZcfPTCSOhnMfAM6NY_jQ0#dtOA#`y2zF={q3-{*Z5; zfguFG(5FH}lyt~9LfD7K7{2Q{7`68~oKRkb8K*nL!pq%ZDc$0uI{-IdhDA5}!VI+J z)6a~9@2}j&Yj#0ukqcw<0KTRWi_PUCoM9o(;?|l9dYJ${r#uL0`53e2`d~4}ssqry zrA;vupUYcnleg#}YzYGW(`n-cSwR9t(*|8*NwQ3>U(d_U()y`o>!Y+^CuC|j&eYe? zR!D8DZw-wCx`nJPxuN|-fNdBnird^~(4)li*73da`lEvGW{R-(n`ry2>zCoHy!ij~ z1-G4Ue&P{;&Rusa(92DrOZUCRrdV}al*^~R?@qXau%Exx0B18Cu;*GXOgR;UZhRk% zlV3y7d%|P{eZtYs5OWA!_=BBb99s6#dtZc6yI)`ye#Fk_&>9PU&t;eZP(!~Jd957V zVEYj`VT{=Q9E|?)1sH#*Jxo2-3Fcntj&6G|jL%)Hpp<7or4}$ZmTt0TXPE+o_<;OZg~hTdH`-B=tr)4;NyjM7`mL_Pv+L#E2My~ z%XqEm>xeJMxA&SCdBuJNhf<^ zoZgkW?=govbJ!1bMBvH7w}&x%+hhEW(4$7|M(_##AD&06kJ>3ECV`#2j@pdGiGn7K zG5g!Y_`@Aw%E`_!`)oH@aHSWz?JuDf?+u?{djlq)?+;TGV_^IFEQn8a!IisqblH7; z0Zu?(BHZ>?UG^wey|^|ExfLPEEDk`@T|ZpAN|A;xjWTeXi>wt|{I_>+_vT?dxG z7v}e%)kU_=o{09XT5;i?Yk+QgaA;ebBwE{c+bYzmOp^jloWobTe*Sc23yfSHtXT7d z_kTYk&^@|EZ-@ll%Bq*hd+Nff-zxFK&3qSHM;FHH9QJc)+0SG+Vc(51n3J#+MjY=4 z<4*R42`74^Rqu|VcR|ZbunXW7=o$EE?HTxF@%M0X>o1NmKl(?k#|eVk#$Y%w@kl51 zB09s&)7{v*0Id%!xb`Z{y8H&joaqO%66eEL7xLivO$S`O(*zkMUhcBv>nOB^qQvG= zw!T`p?!~pu_6VOjPtmV48EVr^y2 zNK0%1bsIou-dn8amvI~1zl>Vr{_Btx?!SJz^3O1IWw36+cY)`K(KTz}KmG<5J*>I! z#RB#mjMdYN$c0DPMZ8Y1U%1@}XEW_^G`SvDoc$g~9)BN!e+|Z;=m#;!UV@k-UD1sf zz*Bm#lcsSR{9*!N((}}YLV%dVotTF(=~x$-da?`5NbCl)&-a8m7hi$d7yHBHbNyj_ z;s98DdI$V)sS1uHH{m4I2x)k|+4R6ZblD4QL)y30N==}fAy*$bVTPUVrRTF-Y(YrP z=T`mlZ6BOT^TN`dZWy@Gjn*Ag1pd<%ICHP|z{oX<)>7&DU;#_8}R$kv~)9bN#jU!fbja;qgRcZe_*+%4tuX6uY6?%Gq8?w?1LskS}@XDWH z(6Z)VhOYEy%>6p>Eb%#PSi*mLL>9eu(2ZYi(P1x9U@xc+pbJk6bL7JF#kp&D=}RvT zwwdNkW)qxBalwwuH_?^<42B)+i_pIY;W^*z5>(F^@B-g`@z_RH(+YQOxSq#3hci^6HWtzJO!`wP6c<_ z3uRocSaTVhTUqjGpqJO{yW{9du<3;XNXZMZ%`TU3`7o66!k+UUn76|XLzf}!i#+h| z=N@=xE~ayN{@uB4*E@5SzN9%y{_{w^7a=daKhFan%)@j($;0#k=0Bixo|KoRA7a^n z`8<_*P4l8?F3Al8@O&SAPN|z6er-v`oMA@q7E9YmVL(~q%?#E!`;68c!?sm)xM z){cplxkVixXCR(?kdT@mG>?uwFc7bI;C!x+L^^N**C5hDp8trn(2J8ciRUe~NC@)- zP#-Mt!iS6eFm&}_VCdR^gduDG5k5r?UiD`fv^4Oq1D6KepR5R_j*I)_M+ph=pB~zh zTZ3-B>fV}Fm!LD)YxyRcTcuw13obWuT`XQF%g$g&H~CCf10<$7;Yd;gtUZ4iUHEY@ z^k_dAe(Y5kgKqtJOvfL63DpDR?5^Ckr#Sv_XB~QR97BK~#aRDnH<)m|JI4Mm!IXqo zVe)CT-UTxp>RZEPMP-4;;SYf!$|4u<5V|R`2z|s=Z!V ziCVE+%A@CZd13i3rEU*TscgAC-X*k~ml@g%t;BY#_VCnPCbe?6kSyD+*R7V?EAyVn z6t8;?JLY+*H8Q`;&9p{H&6C#dHi^oAaG`j*8nu?Ri`T6~t;crjWLq)j>Ro#OwKBhl zUk8cuYxiLL-EOUHjktC${u)>9=C5T9zGf-;9%#o*K3M&u&|XD9`kB@p@c;77=@v9L ze+*Cky7}`_Tf@`G?YK8%>{rb*$8K+#Fnw2ZmxV{*zpeoRHo$-QyGH?eB~x>~wjIu8HNxr4Mo7R9{Qm1zu%X7^oeh0Uu9vK?}C zKRuP*YD3tCWj~kUgTz!XB&2Y~-}J(%WG|dZ^1^Y_4OJdEhAGo^uXSE2J1S&ocilYZ z{dGb~Pqb1`*LMPSoX)}IiIiw_LL8q^bo{z?`HAapWB!^VJU)5Dt&OR-cN_Bj{B9;$ z7w!Bf#Pw6kUXS*g1)=k`HxigNC7v4o<*QL3H0F4W%mKy z2z!`)$wh)r_tnXLC#z1|V>63A%#Ej*om~0r3h4yXq$mOjx?e!Qy4@ZT&HP9vOg)&wbR$an= zJ;w*v1n{IQw`sx7By{sHJ)kaTab1%76=P`1Qqm}6UcRMY=N08xmk;~kq$YI9Bw0@F zE@wRoc@4)`grc@LU8}jw@IFL&-H~kq_?ZjvROm7a|Hr>%mHmVsZv*%Pl)C(y@iQ9L1&2wzCDY(;4-U znBD;KX?C>qE;x0QTv<09L3j_{Xu?ULk?GL&CM8w^4kwLz zID?_V1q>6eqBlW{Zkgy^(7pa#D@$$*Te|G3MK=R(cHbjzvx)7nB(m&g*pu%180<{h z9D2InPPgK&GWitwBSaI!6;u9-x!fef7`IJQ+ljI(Leb8z_PwfJ_ibHQNVkM;8|z5d zZj0A_+o-Fzy+S;HjY+S&ruL`&Eh+v}&sR-qQ@objd_s%*KVd?s z?*y=nr}BNp|Lrfg%l`<)^*{Z#pjZD2&`V5PVvFcDl>&M;f{tMUq!+s3CR){GVcD5= zH&}SC%M5x4gOtEOlZoIX{0Rhqgz6d8WVH$Gv*?~vzsq+VY~MXuak_nW3(ucJR=g@` z;jV`auO|}pNUPrJ>bv1V6uS5(njpKko`%4uT41{jFB|-Fgs}aNTCFEnun-JeZ1vBFg;6a+#-cOm7RR{q(Y+IJUlS^XoCc zpH^jt_lf?8C2AS{9$)a6!rGspq~SLO-6t$MkI|z6u0l?+xeB|q=wvm?dJ<3WMFv+;|oC8+SSE68LMv(zATT1mFTB#Wr%&@09r=hc?2nd*neD zQZUF3E_?LY-12EMt?Y_3-%Bqu!)|L9i zsd-vA;3{a7_*nEsod{L)H3&^L{I;T@>=B3_pH1S&A)~57k!97P2OD3$#wc}a8>8g= zV1B=q_ZsU9YP9$Am&&F;LzVqEjnREtjNbOxJRAvnEw`KmdLDsJR=w26R^ZbS!Zcyk zr6lk-?n*f|;8jWB`LT;h!cEqj7TU6keQZ*poo=}pHt1Gdd{M;|mz!UUHRSSEqY3UP zn`Nv(kFe|lblNIQE`5=d0)1OlP@}-50cft%RUl*ut%Zt|v5TTAEMz{`U(W-VRSRkP zkdRsz;u2sNsbY0uV|xW&?R~B`ozvo))Ha2Ny0*WM`uiFFrP}dlusQ$y+ku{?f?n5} zyB;a&x^wqEC~mO@8Emxjo{iR(_QBJlTpB`|Dy+I0b_slvfH=uC2_y-(pZbz#Ks)d< zioI+Sq40phgu4v#fcAtKGvp;!mfY&zxoXYZ_=T1T$gM1Uo&LzF5)Jw=2VYouUClya z3pGEqivNF6xb3PDG9OzibRSvtF`vVHKJ~m7*C+oM{Mh(9+xC8kf2naI=&s+=q8AhB z{|qIy0(1)*@1KXFfX=Ntfld~k;`AIXPWLdYPJpK5DX`~q*rk#zluT{&Ip8!|(4Kk< z2X2+{#XkCqX^ynyRs8%iCRbf{d7TlEOQ}2JES@IQ7SMkU>>BX$gCya%_)rxq9>GHc ztDfIte3JP(rAMNsCE8dz2qj9mLS-dF@->#UNg*Ni7*m9qsWxQDv;VV}m*)vtjvehf z%;lE-Sl_Zvyl`|8_BYmIiw8=lfZ3?fd9*)!i00fL<&XMnmny9{iY5pSxR>pvXI8w7dkc5V z`A$57T#L(V6iaS)+f~qQCeR~*H!aGw33B6Pp~mXgpzDitYFcb4*IoQb;EWT(uY$GC zbZoPph)N$wVN+h0VFFMl0-m>qyER3f6l@CU=JP4nQfj)M63c7+74NU%e;w9A|IK1_ z0^QLH=r-xDhqRq=W)<5Muxk0D2#eRN$b}E+v3eno(^K+XOq5rZRv-Y!cGOlvPJInl zT#d;Ia$(Jj6qh}!MVJ3XE30k+`~56;xeB({U;mX=?je~Wm+!4=5sh#gCxB=$w^n!m z`pE106|#v*%nXt`p`yx!jO{`Om8r)M2)rfe7UM@=LtCW3zWaGL>U+bzxfV))LCF6d zf*u8EOUPBg~u{6a0a)BS#V~>#e!Q@$mxNO)!d6H zGRNkYR$VU2wGyveSax#^A8EZ!iu%16?^7NPbfc9neMrEqJQKal zdW}bgT*6kSSu8~gSm*qpGCLH1mL$Y4kve? zL~eSv5LkR*E@N};9;XVq0;0_4%Uf__v5u_u9opg9Q6y}5Gaf*XT8zyPO^ zpg=CZS%EHOzE0~2EYg)XTllCh{zJlT6}$dhNwY%t`LI4X;40{C1>Ou>P?rH{3&3lH z?)y7%ZH3(kcI%SwQ8@DTn-_5#S~N+}e^b{zt~n!qeF4XQFKU#gNTPm^EE z=d*j{dRyJ1w;lM1xZMPQG;6OyY6)0|@q}^V#y2q>bzu&#-sK7rO zSDl00Y@x70TH6S~Ieg`{QYN?=#6GTSA$IK5%Vl1xSK(L2v)#wKx5=8Dptrge+hBw| z0`%X?qNn5|=#BqG;QSmF;OhH;U86%C0eDp_a9e=RWCGt%W(HoFL<-fIJ<2r~DHB&z z=%a$)nj}o7W9dcMl-p*On>F-}9>(2TA!WywdaY_%IQp^0aiVbU**v!2hI8$fiD-XyaZmtUT%UtBJ{Aj-Ku?U`QJ6@zAeS||3skuOn?w9g+dY5 z(-K-gx4czCl-J-52pM5!qNlJb@%P;d9+&5q`<1xd$3*)^D>g08#9I^+Q(MWhwZlMpgUt;H7B%6OVX5_wfQWun}a8p`B2LWc3p=dCbZzvdZ4 zdIW0tpnC`Wn|K8#6`Ixq3M^D8+beBYYB63kSeCj;mf*1VDH-yC!rjGhfm51=#ao2#||54E{=$Ga`B`kx@X#P>7Z%DT&> z1Ev92s)MK9`YPqhX7Xa*%hGJEOsIt9<+sp;ZVTOsqT9uyzBqatUB>gN*DCY;weS^v z%|oCqv`l^_HF*x2SJIk-CaLA-G-%P6=W{g$xwPxEQjklwFIU=&acJy(ZDNpKfC+ZR zrPpu4S;wRiF?v+cO|E*a0(niq5PvfO(E^t+%N>N0G7nVbWot6fC)jik0v7q)}2!@~Y z@J-2!u*hCxin9R5Ksmo97lGromViE|)T5<$P0EofF)CZFQ`?BVaUA`e+I5xlG*4Wk zd`(jM6RbfgE;@4Uz`zw=5ex(uu)I`Saa#h|k zK5vsnk6d)qSJeHwt6t@0)|LP-LcmMW5?5y)frcy7z;WSqa9`|!03*;>`+)OmUvOSl z)eoGPP*?h+-oQ3*g6sO*;JWcHxNp1#o*R9^d%Z8XlLkXm+DfR(O@iW57Zl?Ex1^ka zM+?su@90|i;vY>wQ9;)r51U+d9rDTs33ZDOzI5Fs=#OgEU0QI;)5GAmr~ULlmmU47 z{epeIx8@%RfB5T&IN8{7FiaOp^7OKbfSbCzUqZu`(t*Z?ZV=P4hK+@bw6#df<#E zFZ)pi(pgeE*EuHs40a}wKQAQ9&3V1v&-o(Ej|HHPiT=3Q=k~$>K2?8Tvh2i=Q~&@V z07*naRHg_wEu0nOHI$Y#pi6!L8ZQn5=lLE8a5sdvH|kYzT(<=Lic8QX?3InW>rNKE?onBE){#9Q`tSa3-Y);E(|5SfpnjUM!}~8Y zw!2{V4iC)w(#^#3J9s)1>t<}V!^~|Cls!^gg~Tznm7+egwhMjfWST8frX5@}zZBZ; zgc+I~Fb(@p-{$1nirUUKZJQ!2pSs1twH5npb!f-aSZaqUn=#$YkC|}X8H(tReA$HxBS=1o?Dlp)T67 zQwpIsh=JdQ^>g%813dzlg=~WZBEml`j{!Q2Xprj+LKPlI>Th$$uIL*ZkmZ)fYWxkX^?X(O7U`OX%pCzH=#vF%Y6ai zy!;Zn>o0-*Tz9aa>B{6dV}d-f6IVhfa3*vFXCkSSE(X4Yy(^PLK<~WJ6W#m%;7%C; z{Ip?6LjAC~e_b^1vUM_CE5$qKVbZgiv?*qDO-MQ=jmxr_Hvcs|yzJHjs z*_|5`*8&q`9e5LEu9houohui~>EO8!f3wJ1M(M`U~BIAUx%-*$H^ z?TqJRQqJ+2Drq^*$7V&X^BOegYt&a<<~oCRDE+nT@iNU}R$R8VK96=j)43>57JbPN zKAZ@A=xOlrP9^(UtWLk@P7gTLHs#p#FTz-F6bVO(&y9<3Wi>&u(1l=E^LV@%CzrB< zVraNL1p({;4z%Kqi@gx=9$-h;+kRF;-bJ_GiJckT4usng-vONQ?S(L(&;eXb9Sy*< ziQ$ZN@wr>?K(E0;z+Zn8ylEe!g&zqGw{}8FDXkNDHQ33GuRz!a_1XlaPf|0tsppkt9>Zj%PgKgpBqj#KvD6OJaWt9R zu~5isSvH%=Y8nuhIy+!G*U) z+tY5o*DS2L2DzUvbXED-?XBV}ge3PiG@kt!;d>qd?+#5EQ#YMKz?l$o1e+<5Bmj>` zh)*HZr`q%MB&H{x2iJ+`z;*HkaGmN1E`;8N@H60PLLkepy80r9r-_8Q^t4Kk*4>vn z9GcQ&p|rRTExV81!zVYMgN`y-^$=7d=#?hOD;4WrVFta?1p33?UYitaUp{tyGmKqt z|JSJuUJu5u9+nz`_b_lZZIQydEwbKYsxwar9!u~I6MzMTkx+_>LGv8Upu5>*Atwyo z>xd3|jdo<5QO9ewWCv%Of?q%g!OkNg($QLj4}X_B_}xpoP^S@2V?NK%USU#UXbP z*remnf%EVmz;*cd;5za&xQ;%H>63W;e=z?zg8w2y-<|>Qq{$({2s;~}EV~5$Voz`< zzXQIsq2S0^2c;$Tc&%vB*#e#40D2{Zyfx5OsP)*~0J`fT7vq*5cK!XR6-|w!*0^EP zCfDDlY<9!c%?LWBTigtI34Lp_YQy`xE$Yn^fXVWUvgzA|TALUIgtEN~rdrmPF=j+* zYY0_jemnO%W*98Km{?S=;!BUo%P@HyGGzJEqOG~CHL%Tnth7CH;)xtP5^NQEY27J5 zG0p>rF8kP{jR|)7SmV|~w}{VeVLdJvke8x0r+e1SUC%Fo#xnyEwr3G?0uHS?0!N@X zA%IP%QHfZdphIpyB_Kb6I`Ra<{5*KikApyREQD_zhvuB~5YE~U!Q_?TJ@XN`4&fwl ztQ~{hDPU(FL1Gs!1$IprdVo9WEwt=|!Je@ZN=u#Wn#(cNs36!0bd&};1KkXJ3s04p zyuuW>KN8Sm);7%Ws@7GAmk(l_+~|0lynQVaf3c7=#o$yCki(|Zncb{ zcSYA$A*W!i0)t)gLbjRvo1{Uj zkIh07G4aeaPc&Acj@6`Mn3TL+UmB%?P8z=vt@=(6+$}@*UA5}9&G!M__}%hy^`Q|2 zx`4c-3e(~ms6R6TUGjDaRu=@ky8v8BK;DEfHX-Cq@d!D}aS~(rNDw`%&r=G=u)ZWe?KZb5TVHo|@v?v>`jy^2DF9igwTgOXOs55%l>!NrUKgPdUJzfht--q`%iIV0%CM?jS#6x?NZ zLveKrRHYq*#*;5X)43PH&SLWJ9PkLxr8P&LL@EOSW3cB5cHPHVz^gR4)-XntbuTL0>AE{x%7r zm9hk0sMR(mxXs=H0X`{?gFbGZ6J~C)!=Z~VNXhX)TCNAubG?wB=Yx!VA7mDAWfl0j z3Wdb+EmEOgcT4DYQ2?bM%l0%@MxIgWd0u`_O+LI1FE2N=^XbR=LYU9Y_ldFnSca*P zcFufWm&uL;hU?FgW%MI|g#mt?FWc$5rKSa3x0K^sN}EijJX4M%@|lIEaf^byT(rBA z<%bOiy$p7;+A~N9_Dmsyo-`eSpSslt6VRfMUPZeM{S5THO8#471iE}?x%vRhs1}_) zjFBKGYwkst9o_eWa;T4g8(~IkevV@D9vG)fcU>sa1o|lg9U(`T-G2C4a9-Gn;AMa( z1!2!jfxw+~2uawBa-g{+7n)1+p{0T#FGctf{L%{WUtR#tLr>sD(Ft963I#fI*b^0t zF0X;EhrA5hpmV7wc&_(>ru6ktUWtI$c#ZCRU2C9Q-$#Fhpf~0YU#Wl|r-K{~X1(4G zQN4f&>DHV;pBU?gnDq|0obG@|hZh60!?9-9c1{ryf#BQBapR2revh z$-Ecqy}X?R%QU%30Vcay;+(urwlzr|N93ImGF_ur&(n3eykTC(gn3UGuRF}jd40%~ z59zN*%ZG*3dUc#Idp~45^H}P5UVj+>4`EpIqYq)1u{gKjGlV54anRACW1BIn5%lXm zc8iVT^g;!6tLMEl&?BsQNVx1|&Am`u*$mZ}*FwXI#}S~8D89l@pf{ej06hT}--Us0 zM>y?A+o9_|7@SvDo|FsWVuZdB^MwTvx_uU{`g3U2 zF~+CyXxw;V)fwyx+MPp@LcN;wYk@z9Nz~9yDb1!_*$zFaw$vKT?Ji<*Xi49 z1o}fgN=gHLqXK%I5%|dp)RPQ(4lT3LvRz#3@XPk2@B^~sTRY^J(MAX_RM>Flt0M(8 zRY}!HS9L=)1%HexEo^C2N)xs{A{A!B_L zDa6WcGHncrcFJ*+Xsh(MF@;2bF^Ca(b92U7_2 zSPuH}>pr$|hTUcpzm8g5WBu%M<5N==x1FpxL5`k5Y4#ncJMj`UCbnbNyzxwT4!HoG zt1H$M?A;8YH=RHjk35BO`a-Z@$^hrJ>li;Lf#)W|o{F$%q=Nr;1_W|$K_K@I1aogA z_$ZdYgK<16CktH1-@zFFX#^bsKS|y~7k(Z#xmbhFV5fNfYG-hy%tot@u6wl)s)SXq zs?%Y&w(QC+Hs!uL`(nK+>XifR(&h9G5G{?A5I0ftn9zzeI3$y6#9P!+H&?XpR+2yrKH{N-<3&Q>~*z&GH1x|QXwFo;| zb$tJ;9&q)YN&POc$-s)H>FR0WXykJn2eunmRTw(0b>qAW1Ig~bfyHW3x5R3h8?MuQ{mk_yixYx<=ln2coesHK(`YenD|hcluX4k&t3I~x{cd>} z@>S4ltwCq7v)?oe@yVD#ukx{b=Eb?CP<#9>XiRvL-%2|xExM2d9YJeMAR%}NU?YK! z*0?z<%LfuRQS4uiUpN`OHAoQq=Oz>uAqHCXp zq6r`uTnW>maUX(y9N|7mlZXfr=zIy{{HIM4pwqp6_vIJBp0*e&@cpQ&A*(LkcdIzP z*>Epih5V7-M<2RGfF3JAH@oj9P1Imj!8ZY~BkW3aV|*u{ zcEUe!`Qiuc3#xfO;<%dUtt6j_Vp*?@qqdJWR;0p~=Q5sC|2=Ic?f0@n`fre1j3xW& zX-JG=b)InKHPl45El|&|{BE~dY`iL-znT?*sR;1+SOgkjCabPm_UY_cx9A$^WgK+2 zASYb+)d*?(UNx%3vepr7NEyV(7QqdTJ!otouKynC!luk zQn1CRL&LdbwCZTtucjgJ>EOJf%axP?u4L5B3~=AfMEEnolac|R)GV+c9s-R&J^@X~ zxrSwbp#we)+)t)zn|-_!Y*C+hX);9 z_wfk&L<7(kpvQ7h33gSHuDnYJ+th|F!XfBm2=qCP@WHGGn7`ElaX-3X(*ZYZ+V6(V zB$1EP4hm<&}whdL1(aU(_x>wO@O|VK=*4FU4mZJCeXPxFG0|0b4)?8 z2P#jFh58eJK+p-A9tz+J=!rV$4G3R@u;}$iJA-XsC#d@BF{u1@64V?|f!g>as6U?$ zjh8Z^@p1+=nc%#54(fJxg!+BYLE{k&1t=UiNfSyp zu7qyZpewN3FLXky{v6b2ABOUppAdAf0raW|09|w4A0Bi+jNiyXZ&fPjbk9{B8-R`# zb#daptk%v26G#Yo%mx>XUF(9uiyGm*nf1_jVm-Vzp6k_d_0R|P>Uf^^8P}lcRYk0B zY(4ZIE9-gt-m*QG_m=fz^)aZALCW|>)r&EVqPpH%fAiSJVv#{hQ$P;zQ8whf= zy0*iepn7jdDBsZzN;Ye_mzJ3hq4|IeE1ib;RdIN!eN&#JS-xV)ISxX?R?z;FC*i#n>_ubzn&|7^9>_dUR z_*Z}~VOF(~Ql}6vn?Pk7otQdVUTXY$7mQoyf|1J|FzE9J_-Jke446|713qhD`cP;9 zy7uJWe>j^&ZAhXlLJeAefJGS}L+15!7}}_9O=UDDotvHCRIinr+NtH#XMj@wq4{;p zj%;_oYcjkh)CZ*5#`+Je`hC`f*TD7R96NmUxg9=Px8@4y4G2?1q7Yg01cJOPgOEV4MYp|b zcY7%P@fO2IWF$eSMY&7QqKEJvRF&33CAseur?Xvh z(HG+?tSov%%cF7KhY{$pZfnqEJz88%QXwXQCkm-~20N8);ELJcz|oEw+dDAtfZ$vR7xzus(*w)V5tWet<$JVb&7i+)5iEW&b*R|Yut)!7Fotj3kris^$kkkLy z3zIer(6?})r&(x<0DY7R^t{Su26~|cJ;HrgEjo|S>CsHNWi3#AHV*2JklWtH8uUaH z=m=ar!dH)=*CC9x2RlLKt`1PL{RJr4_$=IA_Ba%5iG!j&nNYYZ35xb6L&^SBC_RuS zl+M!PeJN0~FBMAmq(R~Okx&}V|C_C3`JAP2OWZ7t?Y}Cpo7_~~39Y&H?;s<&K!P@Vyvl(f_&R@TH* zQ~fZJ4qg!M^19qLPPSmeZCLx4;)GFG7jQ`WM6jD(bhM=n!JsRk2G0w+8KWYG- z7WTMBFRHcJ3Tv|H6ra=W)tmw^l%AM@P(9A#^M=zs46%8G1U$UFy$N@|Ooi+nHzDV%WXML{`6>l&??{8&U*3k> zn=eE9f}xPT_#dEj`?FBJy93msMYkR90(Cex!Cr^wq4TMrHz<%doK|7)&i3cKE6dBfvC;HA{Bj@M&ap$;;UNg^Q_Pw-kW|P?0%I>r?(0T%7bSoS(f3&dxglXXc-SGYcHoh^`H3OcbjnC>!L5lX-|Z0R4lsdQLMVJpcq|(?q$+Ir!Oub z>?3jJpR>&l$#>|vT^<%!(L?&^vA66|KZf6|q6ggbM*tPG?-UDF8dX&3<*M*-$>U!o zA4`ixDpf3`wktNsYfP)uGM`>X->4FjW6E+_$I@z}ip}LpzEnuI<7IwK{f05v7d=d6 zk#$^JzREAorPpbXCZ;c1)YImTAiJ+iqFr&>B|%v7y%)x=^Jt)Ju$w^VF}e>uGYNW_ zgI;L?x*7IbeKD?xesza_@BVfzlpTBzt@JYj^zKaDWfzj5Gi#2}o#OD>j(3LIBj~pO z*bz#(gNG zCP42Bt_zPrWBM8>tGXw?Ly-827MSV85{E(wACfj6OktF0FbD zYTSA^j9ue|E9nlXsdwXS_ zLsmuwlplNp0e)7C&oxWVAnz_LId|EaWhLNfwH@8+8jPhY_F{bg4O;U!gnZ32kg*Iw zU--WvW6pnrD--?~9QfpUSoc<6SkU)9nEUDnu;lgkVe|Wa;mDBZ;QHkMfieBxL*bTZ zpyb<*P`;}pRPOBv)%!a`4O;b@BM3Wzew@xJt-6p3dZJh~#Or2XbUFVR*i#omX$5_C zmA>; z`Psg8L%GV-tUN=WNhZ!Fj9Ey^B5)#`CWq^eDM zqe4Q_@~x>2W5_-AqFnB=H`mpOx@solxU^Mw!M8pbyOBfAVBgB6y73J3SPr_h=-H?| z{6OcEMOSvmMY!)K&~u9YkeOBrUTJzt-ttJ02oSoGh){R*OV?I6&FMm)D&%E!1$363-$-3jzq{*5F}cpQTox!QwqssmE*x}X5# zsiG?WFn_L~P#}teQ4~OTl5dvK`y1P^`Wlg%%C&q=bkQ%G8pe6#5<9zUt;$u2ZJy#- zwlkIo#gT8XnZK*|-A(;0yg1*6zkaJDZq%Y1%i#}q7 z2aa9~u!Xp6Y0(+zEl^b3A|P)ufzDwsq1}7se#kEJLwX8=zMnvU9$ofG&po_YZJ&aUWPdaW4!SQI-R9L;wIF07*naR12>Ry9ZrH zhN08=0Cb!ZfG)Fw&|_{0dd&~P%L~Ks>Y_iwTTA{KK3)1RFmGiI9F5xorC;O3u@mF< zJzX#)pz+CTp!0QOu-gRe8t4|VbI_lJ#^m`>QjU`-v*^-wZ&qCQD0|!=?W%hdT67Nj z1QX~n0`$>qJurBo1J0#-*iZZ9l!nBXM@3~8Wf2N8(H9_8$-2n0koZZ@7GRw4Xw5{k7Yhj^z+f{q@Py0 znG=GT4Fqu%(3$Iw`K^9t(MPQGpz9tG79Byakf1jU&|5UnOHJ;3F>Pr^&~F#|AT_lT zO838u@F<{bF1rqTop9R;v|4ndYmabiUbP>=-17odeur`Qk_9kwoDKSox(Bbuc;S^P zZs(q zfbQg=vl!jNqHpAjGw*%ofT+iN=PKweCeWLix0P2$4-oOf%`_X7>>q?N@C(A4 z_h8WIkaveVVa;tPIcNl2&0&Q6Kqsi&*B)y3wu2wO_#WOLeGmGMMZhPzp!;+`be|K1 zp7X=-%HlA*wloZ{FAu|;E1Ti%HO=tBh87qU*8;<~wZPaNEii6-GmPF8gkkIc5vF7P zwJ&Eu^{%I&?8mNno-R<$thxaGM0f68&~?QtpflKeaEpHKDX2@`1jQA9WT00d=oRW> zTz#}1arZPa&>wcyeaK=v13ktBy0qpJ^iLMM;LYhy7&PAnGdB5P7S8UoHv3>Eei&wI zDGKXmpi4Jnlb>lOOO3}fMV@K1UOr13L(j`p>o3nG&NDrZr!$$nnCF@q=YbiqZkVyr z4Kpc?b;0zFPMER53DbpUY&2@7dMxT^#!~7M^)4kZ+HBDKQCpsO7{}7ar*G`Jlron| z`gO?jQhWVc^)}Ntx+2D>`k741^~B0D7t7Q8K%naf%Ba3@e&VP zO`o`lKu6$3oGzuVz%$offS#>_&KBcZbc=3f)d}>fkO18S$r*MiI4}VrdQkygNCDk; zQn>5{`4P0V6r1ns2)2Ds!FONmg*Qh01ii;Pq5A|6bee{4`e*2-&qGVTIK&}e5r((W zg1@sCAz$AN1LK-u`1Tf<^nDA={qY{m-**qDVSfC!5DZ^`4<@epGhEp*2Ws{_g`q`v zwCZ%;ZcuZKJPHE6JG1I_@pPU1db#UPpwsiPX?HVwTn$Qrn zebn)&++s|#`cC9xdAz>9t&IO_v};z{sgiy4W4@PNeLv)T)DQK>GzUWNX8&srx{rgt z*{4`_eNk?T0{W4wfe6rxEJ1HEfL=tP)2+39HzeQkLhg|z=!U>-z zt!su4H#Wn^o0?(dm(4JJR|_mVd=J*2xChIR+=J;m@4@ITAsDjek1%a@2(rE%3ROQo z3zY;rTJ@TvbRDRZTy>`e=m|Z9`%a*D2K!l@i0)j0!pfi6?M<@gOm*T17YTGr*cFTZ zNMiIa5cHJ+1lq$ukBQY6;l^*|qJRFFbzT^{+|4ZeCyOz~55?fcTh+(C<9SV@u1U{7XqiF$oP(^|tLL^F*Q%|>IrQ=6x$NRK;_-YTmUrNLgm5o( zz^99y?D+tr*YW@Ngjj3PCrkI8-FD-y`-qiZwCD=xY%#8-70_FB(CH_g$fD=FAo&i4 z7zsPs?zXywo=|UL(QPMtXt8+>y3bVy5%>e`AbrO$_;idHUK;6v4x>Hr>^L7hi=elk zj-aF4-fKRBz9^_!^tTc8_Yw2~8=BE=Z-${;n_<#-EwJd|J=k!P!#;oiJs5+o{NN2i z7_jmmVdc6!sMys7%75&P=j{g7Xw_?vb!YCo4I!^fP(c@)ea>`*rn7yaG&c{5@O>$( z4hYbjji9#zxq2V{;hq93Kp(f!t%0t(?Gkj-*!3Lv(QCczL&4?aTI=KGOuTH25U=xT z&(-j5iw zf7Jp5V_V?E)j=4v^k3n`mN=-{`y^Bx=z&(9+;;-KM|99nw}*xcBcZ6!4kcAVD6a{! zAFE)HM+NuCWN-IMN0m%S%ZxwXzLd<2FRL9lPN^ z?KUV{Z^}!tNkU9OYe)$CDmM&5EA2B3u|eKfBD)u?Fz9uHu7(S{v2 zh{_cvvQ@~0MpnX&6j=k^YXD9#I=yupk9l9zNn(tGvC-pJ(nSm>A?BM z{&YSn8?>+qy&*e#M`+QPk`R8J9BG5p1h(H@fgJ%SO%{uB+=cgJI~DY1wqYg@t$6`L z&SLbMXrOc0i>m1^MG$Tmcp){%3pbO?pybDaEcPY$T?L(DVB0BfL2EHSt~!iuj!&;#8a5p?P+y{@3^uZGZ`&d6bGrRfV!X}1ymi`2DR@6b!53fPxflloFwJPZG zy4x;S-WwC!L-qAdkY9EWO6Z3jYC;V3at3-!6t~?9^hdVpP8Qt)^o=^`s%7VrP^x)r zjW-=jXf4}sY<(<)w8;fQ7v99kRpi<`Vf7DA*nidq2hK@3nGOmaP;~ITC_8IWexBzK zo!8sR@gc3l3xdBNyFp z^s)y|T=l}K>s~l{ji>aKm_^^Z5nQ)ekmc_C#LXlDx+ZSjCv5WLDF8Wy$1t}0INcaYCHHMteblQ zx_){O+6{BVW5ay#hv9yBY@{EaK&$@Lct1Ql5n-Q-mVH(by3_5o1tEAHUHA{seIFdl zK_7&c{X=x+$({djJ$L76CH{Scy#K0Zcx`zzytxdm`jUTvi(f8)x`R(a<)L0IPOqhv z_fvSi@jba!Pn0n_eY5RlD9yM8`4xZUpx4sRPl?}!SL5?~Yrr4rs=Ku4DOPW1?x#&08-!J-`~6?I;HzV9sHyj{M@Kg~ z16-!ZM@vO3r^h_oT|w~(=%7LBW1p?c+9XeFkBR1TxTDuaf2?#U>XZ3U6;KZYY-c!3~ z`mVg~>}bf(tB1nM5R_K)4M}CfqLMOt(P^f;day3Yu@CZ93C!3egd zSW{}w3($^ZMI%MLOQ5DDw>tm%j5fR zd#zTsxJGVojV65?tK5F7ZclBCSMj2;n*{9A$AV*9o7ub4D-V8hxi%jzgIvftN!FTKeUSp!1I#>&~bVY zddvwz@A)C)nuo@m^t7fNe7^Gd+%3KB`%J z#IusBk7w2uQXZikiYoc|V#6bs>r8#>^gR2`Y#SFVm&bKcWa<;OU7e|2TiS~DHE7Xq zW(P4GqT8+9H7ASCv?&ty7|nGL@)#XK&sSXcVqwXd>Llzs@bs;=!m2RbEe*0?yh+P; z!S&l=$VxZ}Rr}unTYMi4bQSg*dglA_=V9j;d!gH>e}Sildf<1TDxi-*3qL9VkB<(Z zRS&?^;{)*AqyV&^5`eBVgV1wMi0zQ;y^s{f*d5`X7lzJr!_Z+)7}_&6Yw9=`p`Ray z-iw-H*y12$?Hmraqa6_Rm(a_=YfI?GAy4491?f6%@dF_*GY|60n)xr!2y0#zVa*BT z=#c9c{U0A5^r0(^pql}=()b8?y#^3tEZ{T%Z)M@za9({Jzv$;@BG5;!LD-kN@xwxo zkCu;Y7LPxcPk>eOg_e&=R@zosl(Da2T8ycVD`d`_>kCa~1s1YwE6!)G<7t?|V>ND} zs8c1|(6ioXw^sa(Akc$ICd37F&{Y>+Ta*)^ui>uyT>(0G-R~jj_jJ(fqJz#CYj9Pt3>Z`iDs_X9isFq{_>bvVgQn%DnfBSv!$b9)Kv#MH> z0mtTx_(#5ccUI-^ec#K>%DQUN5PW*^5U$gQ;4kkOhQC}k4F64Dfk&(UKkpuazxnnE zeBrwz@VDO|g}=QAb?+#A5yAgF>T~yu!C#}r|17%rpZ)F_e1`NroFGttgJu8M4{(kD zKoY+3&}nG;`5iE@=L_hz&qbgG=x<7kJ{JalIS<-@`vf!v@iXomVbAn;;ISI(a{+p% zfLzK1Ti+*(eu^H0pyaa7%j}?tf+!mTW}GpCHir)&O0-AZJ)~0-gT6A;A>r;gCoAx$Hp~ ziY3^aXlRmYiH@@Wva9o*gz9DlfB);ywc~5h|Hj|LvHf&muGp~ZWYK$ee+j(XZ-)Es z55SzeQt&@koPoc%V;cT!$ywAS{P~ho@X0$qfKM$;qf+pnS0v%nsQ7G+?;|~(>(~=#~v-3-A`9RiuV6Pk- z2R-(yYoPB}E1-YBb0h=m}fUGhO#f1^wZ7n{Qu_?po=|3wLd^ z0eg#$CB8^-o!szz+F5M@UD-0=xya?b<>5gF`-YdspzL5Ac2&gLmc=!dIf&{=l?m-q z+fdSWS1M%>TI=i<753Nm{^%g5wA4cm3c3` z6^HNOXSnDw`YcEB^A(`~c*Kyj=n{BZqc7h$0(+_j=-o-2IFb;Opxe6bR?z8TnlMhP zK62kfBkcOh;g&(DsyzXr-4Ekh7+v^%^8`%A%!2mqDT2x$x$OJK?84 zS_|v$e*x~fcR#H7UJcy#oo2Y{+d;VgTW#>a@9u(mclE*C)%{SsI))m6qB}`3w*O_! zyXLNL_{!a#@YR2ez=D5lg(csuhi~0?0Dky`*P!J7XW+#j-47Kdw?OxcpNF1Ze`mPu z{O$k;ot7H?uips4^4DAw@rN~-6wvQ19f5B?HU#tUAB5}f9fTY28-g3}9fIq>kGe+_ zrBU9!!?-`3nNR6bluu>v8CIm!SIcFzCF>7c`@*_6h_oB*+EDf_`Fb6#{0%ZsNx$wM zl5(t;d_K-=?-_)f9~^>JThO~B&^5^KR;;=d{gjm^*S8ubz=xpw1?Z7J4tX>ijmExuX>9km?SjP&U2Ef1Z9`40?Qw1D&=#fO*{;EBCJ#Emp9eZfOw z-$s`5qK@33|A4jJ{0D^|u*rMCIX?eEoA$JJ)%5vVyV)e`-SW>vuy`#!X~>sArZrdG zcjY!4K~DS2vHZ7j0;uuRFW{2QZD;Fq;kHMeTy~39Pcqo0`%Zu1On+Tn+j0^rJY(QN z7rt}HEzrB?dS*RiZxl1oI(|_E;hz_Qe|sS`|D+gdw-iIo=3=PYPz06h3!!pd0aUCl zgo?-JK*gFlaBxils!(j_2x0uu0wt{g%4NB=1=vmjYp;4^A=GUxgw}s4zEz(DmA#&~P{c4Z(2;qBW=6hxF55@>~dVvgjRIK+nBKzXXfEV*SYC zMURfd?d#s3p$lqGAX?I#E}U&MVYPF`^SPRCT51jQts3OptZ58%u~w%?W9f-4`njdl z64H9UWoa9S*+nNVjIYP-dXctK(FT#u>W%=tq=SpMXZFF%F41K4FY6fTBW7Qse^!R& zTgR)n$H&3jRQp}J-a3Y*s@9wNOSSgsb{auT)|}jSa>?(qv*u5jSK(LVWUzSsD6GXL zQgeHPfiB&40zDc_A>=6&^rI=syE62)gi<4a4C3 z)icmtHXmWXfdSUDyAax6DTK(+$*L281bYEAAdIyog>dBY0yw<60BSa(HWV^dBd}HL zNrg<6>rBZsscO`rP1MF5Y;O+KZJ7hjPtAew^K+nUS0Rq082aC!M|DY8vq`Au)!V^y zpc;<&#&K;v%r10FYc8J~;GidSy6tRxJSDbl|I#fwg+*&78Wyil!t%|7=d)SdjCX!O;v7?{P>GgSBHT}wKWfn`A+x;5D;dpfH>18ynyjbf z$vy}$`?^{?B|=7?-u@`)$Kj+^Mm_O4Y~dc!YVGsA`w1)TB$@=4m(WGKF?h9#yX~zE z^b~@gLTjEvYp#Nx;-E7n*~#9az)tYfeRp~(MssA0TXk~beZz35c^E2d--W=QQiOd0 zbiZ~3bnhyL_LmDF@rJQNMK#G(9;7`zT_``;ja8G3(t15P}Ppylm1p{8k^J2tVZSV{JB4NIXw*wR;ul2?OSD?Fr51twe+{r*jFZYWXdr zmT~hm4*FfY)*6@Y8yI2xP7jU>j)3e=-OB&(fq)2%Tlc(EEBZ1HJE; z^U#vth?e}D(ERqVpt2DsDE|=n+s7b6)?BsZv5Np*vFcd%a)8b&EZrD?deMd{gnjt@ z^3B8N*|X>x%y+6!qh$l1wCy4Q*Ijd)^wl<2XZ1FFtIkx)l?`N8M)L*?+2pBZ?o`UH zD$T4b(^&njbQ^P2>2EZ1yjzqyTg^JFY|0tOwMDeMMV1xiw~mVX`mu~!``&7bf6fB* zACDNK&zRa;j+4j2b>nE^$KjWU>Fqw~ws)r>s6ZZdfV_h#6LKkfl8#<3*&H2bR-M!k z9A!Uvscss9gNNS({~J$1$Bu>2_KTY!`qDfGU>IQ!{){X;y7A8<@Mzt=2z<*^1brcR zoGuLR9`TS@eG;DlOeK@$BMF z=V0Ob)Xd^_Ll^GYJUqR;Wcb3$(xI7^B`C37p=c#d09&;aoN3s)zg0bX?aG^FRH-MS zrJPe6(t;^6_Di!!t&^>sR!8rPtldgIjbPkr0%&eWjQx!MSsIrtZ|*B~w6Unx+_3yc zpQF}zY365dOfK7$B@mV+SN)qC#$dskafE&Xc2>sWP%r__!kROeT|h2DZ_lvinO0rD zFh}p2qjwKBp$qQ`2{#@sJBNK3%8v{}^Zr+%ea8xP-*1A*E7u{2S2L>~_-P@#I7jj^ z;EOo)sFtUT82HUXGy#w#)TEZD3)oeB-_v};2x5ET7mCn(C_-zFpuaW`dR`}2eLl3k z_D@h-?qQJE`3Auo8D$p~nakc6H-EgtAWvE#&jdY{6?Ou>|5BffGp#yYv2WkLEAK2# z-m!Q?vVGykNm#sjdS>B<)39(u5*BSpz+$!)+KBrblQ=0%z^!XXx#$-@D01t#xQlly z>9JA1H8iS}Gi8*0Ozva3b(!TTjhD5_Q~FWM+qIE3UC+n(LLr&Aa6Ok^&PjUx+t51l zcE-(i)P9YA#+CBp4sDNH$Cfenaih#ao3SjEW!9VVTTu%h8;AL8CSd9233%isf_wtX zy>Y0EB*EXqAy=(=)YfG;Ay=itPWRpEopauH0eg6iS@rq=S@vP5MmPQ-!c|+|2;o=% z8Q0CXLiCldL-@t7K=Apw4E6wm-nv~vkL&km5%_;8Vy->k7O@L>JYI~GLJe;^veV~hker~_#=vKDuX{=wk>tnl9E%e-?kyuaNCAt-=d8l4BWOcZD~S;B@=7N}d_uIPwRXy}~mb(b=P|^|Gv=B2PxT?#)!G-Ov|K*(I zjE93~#bcI-BJ?N2Y$tW=y^d+^pQYQdZ{sc=CaOE_Zzl3~ppXJOpHh5v$y}21e4lT% zvCM`#uogG_##g^ck=Uc&81rA^5v~+^^N9OMaeY}rvr~w8D|bG!Fr7)0aSv>tKMCaZ zZ;YYXhcX}DGFf_La!I)XD|YtET;$|ydD*8O(w+0+H{^-7LxyaNp0ZF2s_VJ|9o>~I zV}0G{07UBZe^}p>%F|a`pX5l+Exxl0JkKkC+^?t+^sl@X^6*x#lc13W!(d6aVv9)7 zkW1i+x8r}eolOM}Lf+R?qV?329sJ4`EbCC#r<2aC(e9KRPt#LNuRxY_MqX$k+-HsgWYe~eto}SaF8!vv&K!Ss zJ@L$Q=Nx@aLe6#T^?6Vr!%{$#r&#w1j~P#iz?tYLc}ET(jn?->DnnwVAj8?6*U|g8 z&16WOx}!`#?{n7RV`Np8n~*xB?-)H81pOz(%YX1JpalG4>0&+)_>zR- zDBRrC(#7vVfAZ!y$6^n5H=+*M#j#TL$mN1pjjGaK-a_~L1JlrAZXUIq&_#E1K=NV# zYw#hJmJ_I0Et&-uJD{XWeQ-WP(pXAE)NVLbG>Wpdj$BOT z?NLF1|2}h%Indf6MR9E|s-?!lV;QHTb69C!qOU-tFnsS!#K}f<FsLO0L^d!VkK4x&5M7<`0@< zjYKLA-1W)z3XnR@lfjjUrR<9Qwzi{$8kD!cF4d<0<=*4fWxRt1%vc;g`PL|xaoJh| zUS)tmZC-^?Yq(CC>fcp&C#wwjJm` zPg6qod5JgC&UNr|kljI|UTEY$Rx@`Yw6>&;#e_bhn4bHn>rSf;OC9N_o`orQ_EZTj zR`jvO1RG-!wS*%PavDpdB=?Yr_-y!!Z6)RDybp#RZ!D&@epq5=O}-nm*WXJN1PU%s zSj63Y{+nI5oF9KTrnBG=1}RAMEO-Hv!=~PXJ*S$*tINH&Qu1)A3;gx6ZB`Zf#Ufgw z)YL@Cu=VR^YGAksmxW7jjru{c0aP&`XH$F+nW$>Hzb_$xWsyBDdBU(M$yPKhVtJ86Y564co_8b2m8SsZ{rJVLM-#IZN^E5mim}q;>=9N;- zjYj`)Of>y|bVYx zR|Xef{buw)zp-#(JU?-=ny-1skh|yKzU|31pL(m=eg7#Xneg|`#M6@*3gWdD-Dxo2 zsV3CO`mp!A6ys~glY6|89@};la2=$O_;&iE`!gpB`6diLRkEhbTdtj`Vr40O5JXb4r|P=IS{-sw1@~~(DVxy z`*@>5_JNKV8_UU+jYn|B(SJeLeb&QTiC=0+Q?wi!G<5Li3ktPk*6N zU-it$@BN$t&$K?jF&H4$>^?2u%~B>FvIikuZih$SM5u(o!tOxGz~g4#ziS!S34A|a zemJcRdsJ+23^{nV1rAEB9{)gXwCS|x<2+u9+fGM z0;c2K76hhBA1*+XAB3uJ1jTD*zHIa0mPSm#AC8&aDeQrJTp)Y3;}9HQ`C%O+ak&CJ zsVA8Y2*AyweiQeOkf`+sV~!?*@=biPZaTiP)j;MvPI5}3$kd?#%bO9s(RbXEY{vkt z=VLWDLfWue;hw>Wm`k$y%khy5Gl$(ld33dR;k*y5@)vW9dh>93ohV@p({Sv(>v9cA z+sC78*77X2BGU+BA}8KvJytB&S0{y-@S96m^?>ZB1oDq1J)Q>e1ZJc6sLI~Nh{SbC zMN2C&9qLxv`j0@e@)BFylyoS_-i<)8ne~_A0aG0QAef!aGZ@6 zR>obuB3>adO}I&qLH%jefmhA4H2mdJo(r{oc5@o^(oX%@@fE6V5PFe3_|=fs$B5Wt zQhv9PWt7EAPb4W`P+%RCT^L|jWA{^%T<0k12`h=A-jfAd_vpuH#IL5^MP#IQk+^G4 z6m97dC_??3mb!ssFEhX^bIKUL-95_UT+eIcXQviWZ04;Y%^%<{e-#Dg#G|Wl+lTD7 zWoLx(FkqEW&=J^5ShufUbQwzR z9-W9%I&25Dh50aW%wb=){`R_5Pq|%8Lzet%dRbFFj zF6syZTNpo+8_T`74f!;E(PC=937fMW!Mg)2dg?JxSQ3k7b)S4u)G+a$U`9k|UN;gkpD5n6an2pojmPH9n*%Cf zPI4_w#a%@44kqI zVEg6t35#q*E#OpfJY-QQ9B>|CKJ`@}L1HY3a+4FOU(8q)cxB8BP-Y#WAEz%(z0u+t zVW|Bn5~9O8Z~+GZPu2*5W;2<_sx>FAhK4e@RAYU~Qnv+77Nzh3HdCv@{_NlW2@&z- zB!5ORVz>WOEBWzErk(i6f4Wd(T|!ivP+pMON5v=v_{E+*?FB5@n#iNGGg&$Na!Ajt zxW?R=Y4=>_s}tl81LD{!PGkR`KqKK~#v>~lS!e*T>=(uO*A`^sNxcsNz^)uLJVN0>((Dx?3aLqYRj zu1tLYrLQ7$jjPX9Tv8J%HC~W!>0sY;jOI9bLN}M7@Kp=CqhLT@g&F25BNln)t&FDAh>7EU#eIXdvkUc>*4+2DSkk>L@vQ4x;r zV_QwYI+x|x%Xz*$iwdyaNJ-ipg~E_oRrDglqfohM7R?x5pB1n4ede}o+3Q03@Yzep zvDmGPT^Pl9Xf4-(vZ12GOr3NbE@UBD!6eD0te5j6@TJeHn(GfY9GLL3>AarbQ*&w5%VRMkJv~KegYSiS? zDX37Tp>&feQa*I!l%&uJAL=HlEZ`IrrzNzsp9D`A!E&&Kt%kZS z@@K}}huU+GC;1W7P|7EAW9C+Wce{!juPqgIz|t&+|1yQfk5w0+{2m3N8cNmRR~7)R6{lXlv9vRz5vjb*<#E$Hh9xYYsNa`hG@1l78a=VfsmOR5 zEB$y-ivn7R3vzpi8_61kh-wo!PA+}R`Zeephq4*Y5G6MV%E4}eJ(Gg7A5l%^Tgg_cN@Tq2e;b03zivFo9z_-#9oL&URT9Lm zTct`ry6W*%BHzuJcjIYtpdk=yGh%G0X>#sSl3hFO_<43L42+Km=rEw4G^g5XZ5z4h34FkNkpxvg zTBQg~@{LbWm5y#an+?kkSWt@!t*p9vS5t%ly0K)g^r{D2)1UqAoXjXI+k3i~A+_q- zpr?i91+t&lmmCp7uQ!kC7tlsvei33*qB!}b$_MNn(}HYdc#!AZJnu~~6 zf%ghJAuz{c{H3I9$a@@E5=0zStTBJ2sWvjC#h4EMxILZrRHHYq%UYH;f)n!}u%fA? z_s?@}K$Nwd<+7T|ng z9Z4{y#gH~Ls8(jGh6cl3(}N!kVvu1zn-Q|OJR3`rN{p$;u2dB_E#T`VkCl%!30dv# zWpilDkXG@&9&~pd-o@vI_g-uQ?THmqw~(+2D+}`I2~E6RZ0qrfM8hT}QTp(QcOB_Q z>jsHMCGs&toN1drEdjk0#!URA@MC`uLTk^dI2U6YXgq%kUT0Bh=-~AAPY{}0`oEP8 d_P@{R+gPudvpaZRC>-hNj1A26tM#1X{|CVR?0o for anti-flash. +// 2. On DOMContentLoaded: read odoo.__session_info__ (server-injected), +// sync to localStorage, then apply the definitive layout. +// 3. MutationObserver re-applies layout on SPA navigations. +// 4. No RPC calls needed -- preferences come from session_info. + +(function () { + 'use strict'; + + var STORAGE_KEY_WIDTH = 'fce_chatter_width'; + var STORAGE_KEY_HIDDEN = 'fce_chatter_hidden'; + var STORAGE_KEY_POSITION = 'fce_chatter_position'; + var MIN_CHATTER_PCT = 15; + var MAX_CHATTER_PCT = 50; + var DEFAULT_CHATTER_PCT = 20; + var STYLE_TAG_ID = 'fce-width-override'; + + var TOOLTIPS = { + '.o-mail-Chatter-sendMessage': 'Send Message', + '.o-mail-Chatter-logNote': 'Log Note', + 'button[data-hotkey="shift+w"]': 'WhatsApp', + '.o-mail-Chatter-activity': 'Schedule Activity', + }; + + var _enhanceTimer = null; + var _sessionSynced = false; + + // ========================================================================= + // EARLY + + +
+ In Stock + Booked + Incoming (PO) + Out of Stock + Remote +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProductSKUCategoryLocalAvailRemoteTotalBookedIncom.PriceMarginAction
+ + + + + + + + + + + + 0 + + + + + + + + + + + + $ + + + % + + +
+ + +
+ -- +
+ Remote + + 00 + + + + + + --$- + +
+
+ + +
+ +
+
+
+
+
+ +
+ + + | + +
+
+
$
+ + % + +
+
+
+
+
+
Local
+
+
+
+ +
+
Avail
+
+
+
+ +
+
Remote
+
+
+
+
Booked
+
+
+
+
Incoming
+
+
+
+
+ + +
+
+
+
+
+
+ + + + +
+ Showing of products + | Auto-refreshes every 30 seconds +
+ + + + + + + + + +
+ + + diff --git a/fusion_inventory/views/product_attribute_views.xml b/fusion_inventory/views/product_attribute_views.xml new file mode 100644 index 00000000..ad1efee0 --- /dev/null +++ b/fusion_inventory/views/product_attribute_views.xml @@ -0,0 +1,38 @@ + + + + + + product.template.attribute.value.list.fi + product.template.attribute.value + + + + + + + + + + + + product.template.attribute.value.form.fi + product.template.attribute.value + + + + + + + + + + diff --git a/fusion_inventory/views/product_brand_views.xml b/fusion_inventory/views/product_brand_views.xml new file mode 100644 index 00000000..792c2ca4 --- /dev/null +++ b/fusion_inventory/views/product_brand_views.xml @@ -0,0 +1,175 @@ + + + + + + product.brand.form + product.brand + +
+ + + +
+ + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + product.brand.list + product.brand + + + + + + + + + + + + + + + + + product.brand.search + product.brand + + + + + + + + + + + + + + + + + + + + + Brands / Vendors + product.brand + list,form + +

+ Create your first brand +

+

+ Brands link products to manufacturers and define tiered pricing + structures. Use pricing rules for category-specific or + product-specific overrides. +

+
+
+ +
diff --git a/fusion_inventory/views/product_template_views.xml b/fusion_inventory/views/product_template_views.xml new file mode 100644 index 00000000..c3c465bf --- /dev/null +++ b/fusion_inventory/views/product_template_views.xml @@ -0,0 +1,174 @@ + + + + + + + product.template.form.fusion.inventory + product.template + + 50 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + + + + + + + + + + + + + + product.template.form.fusion.inventory.taxes + product.template + + + + 1 + + + 1 + + + + + diff --git a/fusion_inventory/views/product_views.xml b/fusion_inventory/views/product_views.xml new file mode 100644 index 00000000..4a171d8d --- /dev/null +++ b/fusion_inventory/views/product_views.xml @@ -0,0 +1,81 @@ + + + + + + product.template.list.sync + product.template + + + + + + + + + + + + + + product.template.search.fusion.inventory + product.template + + + + + + + + + + + + + + + + product.product.form.fusion.inventory + product.product + + + + + + 1 + + + + + + + + diff --git a/fusion_inventory/views/res_config_settings_views.xml b/fusion_inventory/views/res_config_settings_views.xml new file mode 100644 index 00000000..1ebe0859 --- /dev/null +++ b/fusion_inventory/views/res_config_settings_views.xml @@ -0,0 +1,117 @@ + + + + + res.config.settings.view.form.fusion.inventory + res.config.settings + + + + + + +

General

+
+ +
+
+ +
+
+
+
+ +
+
+ Default Margin (%) +
+ Default margin percentage applied to newly created products. +
+
+ % +
+
+
+ +
+
+ Booking Hold Duration +
+ How many hours a product booking holds in the inventory sheet + before automatically expiring. +
+
+ hours +
+
+
+ +
+ + +

Product Name Case Conversion

+
+ +
+
+ Global Case Conversion +
+ Automatically convert ALL product names to the selected case. + This overrides individual product settings and applies to new products. + Set to "No Conversion" to let individual products control their own case. +
+
+ +
+
+
+
+
+ +
+ + +

AI Configuration

+
+ +
+
+ OpenAI API Key +
+ Used for discrepancy analysis and notes parsing. + If empty, falls back to the Fusion Digitize API key. +
+
+ +
+
+
+ +
+ +
+
+
+
+ +
diff --git a/fusion_inventory/views/res_partner_views.xml b/fusion_inventory/views/res_partner_views.xml new file mode 100644 index 00000000..b709b535 --- /dev/null +++ b/fusion_inventory/views/res_partner_views.xml @@ -0,0 +1,24 @@ + + + + + + res.partner.form.fusion.inventory.brand + res.partner + + + + + + + + + + + + +
+ SO Status: + + Invoice: + +
+
+ PO Status: + + Bill: + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + fusion.inter.company.transfer.list + fusion.inter.company.transfer + + + + + + + + + + + + + + + Inter-Company Transfers + fusion.inter.company.transfer + list,form + + + + + fusion.warehouse.inventory.list + fusion.warehouse.inventory + + + + + + + + + + + + + + Shared Warehouse Inventory + fusion.warehouse.inventory + list + + + + + fusion.inventory.discrepancy.list + fusion.inventory.discrepancy + + + + + + + + + + + + + + + + + fusion.inventory.discrepancy.form + fusion.inventory.discrepancy + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + Discrepancies + fusion.inventory.discrepancy + list,form + {'search_default_state': 'detected'} + + +
diff --git a/fusion_inventory/wizard/__init__.py b/fusion_inventory/wizard/__init__.py new file mode 100644 index 00000000..3507a92e --- /dev/null +++ b/fusion_inventory/wizard/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Nexa Systems Inc. +# License OPL-1 (Odoo Proprietary License v1.0) + +from . import serial_scan_wizard diff --git a/fusion_inventory/wizard/serial_scan_wizard.py b/fusion_inventory/wizard/serial_scan_wizard.py new file mode 100644 index 00000000..1588e6c2 --- /dev/null +++ b/fusion_inventory/wizard/serial_scan_wizard.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Nexa Systems Inc. +# License OPL-1 (Odoo Proprietary License v1.0) + +import re +import logging +from odoo import models, fields, api + +_logger = logging.getLogger(__name__) + +SKIP_WORDS = frozenset({ + 'total', 'price', 'quantity', 'subtotal', 'discount', 'amount', + 'invoice', 'order', 'product', 'delivery', 'shipping', 'tracking', + 'payment', 'customer', 'vendor', 'notes', 'description', 'reference', + 'number', 'date', 'name', 'address', 'phone', 'email', 'unit', + 'piece', 'each', 'item', 'line', 'from', 'with', 'that', 'this', + 'have', 'will', 'been', 'were', 'would', 'could', 'should', +}) + +SERIAL_PATTERN = re.compile(r'(?]+>', ' ', text or '') + candidates = SERIAL_PATTERN.findall(clean) + + for candidate in candidates: + if len(candidate) < 5: + continue + key = candidate.upper() + if key in seen or candidate.lower() in SKIP_WORDS: + continue + seen.add(key) + + if not re.search(r'\d', candidate): + continue + + lots = self.env['stock.lot'].search([ + ('name', '=ilike', candidate), + ], limit=5) + + matched_product = lots.filtered( + lambda l: l.product_id.id in product_ids) + + results.append({ + 'wizard_id': self.id, + 'serial_text': candidate, + 'source': source_label, + 'found_in_system': bool(lots), + 'matched_product': bool(matched_product), + 'lot_id': matched_product[:1].id if matched_product else ( + lots[:1].id if lots else False), + 'product_id': (matched_product[:1].product_id.id if matched_product + else (lots[:1].product_id.id if lots else False)), + 'lot_product_name': (matched_product[:1].product_id.name if matched_product + else (lots[:1].product_id.name if lots else '')), + }) + + if results: + self.env['fusion.serial.scan.line'].create(results) + + found = sum(1 for r in results if r['found_in_system']) + matched = sum(1 for r in results if r['matched_product']) + self.scan_summary = ( + f'Scanned {len(text_sources)} text sources. ' + f'Found {len(results)} potential serial numbers: ' + f'{found} exist in system, {matched} match products in this transfer.' + ) + + def _collect_text_sources(self, so): + """Gather all text from SO lines, notes, and related invoices.""" + sources = [] + + for line in so.order_line: + if line.name: + sources.append((f'SO Line: {line.product_id.name}', line.name)) + + if so.note: + sources.append(('SO Notes', so.note)) + if so.internal_note if hasattr(so, 'internal_note') else False: + sources.append(('SO Internal Note', so.internal_note)) + + for inv in so.invoice_ids.filtered(lambda m: m.state == 'posted'): + for line in inv.invoice_line_ids: + if line.name: + sources.append(( + f'Invoice {inv.name}: {line.product_id.name if line.product_id else ""}', + line.name)) + if inv.narration: + sources.append((f'Invoice {inv.name} Notes', inv.narration)) + + return sources + + +class FusionSerialScanLine(models.TransientModel): + _name = 'fusion.serial.scan.line' + _description = 'Serial Scan Result Line' + + wizard_id = fields.Many2one( + 'fusion.serial.scan.wizard', ondelete='cascade', required=True) + serial_text = fields.Char(string='Serial Number', readonly=True) + source = fields.Char(string='Found In', readonly=True) + found_in_system = fields.Boolean(string='Exists in System', readonly=True) + matched_product = fields.Boolean( + string='Matches Transfer Product', readonly=True) + lot_id = fields.Many2one('stock.lot', string='Matched Lot', readonly=True) + product_id = fields.Many2one( + 'product.product', string='Lot Product', readonly=True) + lot_product_name = fields.Char(string='Lot Product Name', readonly=True) diff --git a/fusion_inventory/wizard/serial_scan_wizard_views.xml b/fusion_inventory/wizard/serial_scan_wizard_views.xml new file mode 100644 index 00000000..c516eefe --- /dev/null +++ b/fusion_inventory/wizard/serial_scan_wizard_views.xml @@ -0,0 +1,34 @@ + + + + + fusion.serial.scan.wizard.form + fusion.serial.scan.wizard + +
+ + + + + + + + + + + + + + +
+
+
+
+
+ +
diff --git a/fusion_inventory_sync/__manifest__.py b/fusion_inventory_sync/__manifest__.py deleted file mode 100644 index dea1b26f..00000000 --- a/fusion_inventory_sync/__manifest__.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -{ - 'name': 'Fusion Inventory Sync', - 'version': '19.0.1.0.0', - 'category': 'Inventory', - 'summary': 'Sync inventory between Westin Healthcare and Mobility Specialties via XML-RPC', - 'description': """ - Cross-database inventory sync between two Odoo instances. - - - Connects to a remote Odoo instance via XML-RPC - - Syncs product catalog with mapping table - - Shows remote stock levels on local products - - Cron-based periodic sync (configurable interval) - """, - 'author': 'Nexa Systems Inc.', - 'website': 'https://www.nexasystems.ca', - 'license': 'OPL-1', - 'depends': [ - 'base', - 'stock', - 'product', - ], - 'data': [ - 'security/ir.model.access.csv', - 'data/ir_cron_data.xml', - 'views/sync_config_views.xml', - 'views/product_views.xml', - ], - 'installable': True, - 'auto_install': False, - 'application': False, -} diff --git a/fusion_inventory_sync/data/ir_cron_data.xml b/fusion_inventory_sync/data/ir_cron_data.xml deleted file mode 100644 index 6a024861..00000000 --- a/fusion_inventory_sync/data/ir_cron_data.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Fusion: Sync Remote Inventory - - code - model._cron_sync_inventory() - 30 - minutes - True - - - diff --git a/fusion_inventory_sync/models/__init__.py b/fusion_inventory_sync/models/__init__.py deleted file mode 100644 index 93dbbe19..00000000 --- a/fusion_inventory_sync/models/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -from . import sync_config -from . import product_sync_mapping -from . import product_template -from . import stock_move -from . import sync_log diff --git a/fusion_inventory_sync/models/product_template.py b/fusion_inventory_sync/models/product_template.py deleted file mode 100644 index b256b97b..00000000 --- a/fusion_inventory_sync/models/product_template.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -from odoo import models, fields, api - - -class ProductTemplate(models.Model): - """Extend product template with remote inventory visibility.""" - _inherit = 'product.template' - - sync_mapping_ids = fields.One2many('fusion.product.sync.mapping', 'local_product_id', - string='Remote Inventory Links') - remote_qty_available = fields.Float( - string='Remote On Hand', - compute='_compute_remote_stock', - store=False, - help='Total on-hand quantity at remote locations (Mobility Specialties)') - remote_qty_forecast = fields.Float( - string='Remote Forecast', - compute='_compute_remote_stock', - store=False, - help='Total forecasted quantity at remote locations') - has_remote_mapping = fields.Boolean( - string='Has Remote Link', - compute='_compute_remote_stock', - store=False) - - @api.depends('sync_mapping_ids', 'sync_mapping_ids.remote_qty_available', - 'sync_mapping_ids.remote_qty_forecast') - def _compute_remote_stock(self): - for product in self: - mappings = product.sync_mapping_ids - product.remote_qty_available = sum(mappings.mapped('remote_qty_available')) - product.remote_qty_forecast = sum(mappings.mapped('remote_qty_forecast')) - product.has_remote_mapping = bool(mappings) diff --git a/fusion_inventory_sync/models/stock_move.py b/fusion_inventory_sync/models/stock_move.py deleted file mode 100644 index a4b873c8..00000000 --- a/fusion_inventory_sync/models/stock_move.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- coding: utf-8 -*- -import logging -from odoo import models, fields - -_logger = logging.getLogger(__name__) - - -class StockMove(models.Model): - """Extend stock moves to push changes to remote Odoo instance.""" - _inherit = 'stock.move' - - def _action_done(self, cancel_backorder=False): - """Override to trigger remote sync after stock moves complete.""" - res = super()._action_done(cancel_backorder=cancel_backorder) - - # After moves are done, queue a remote stock push for affected products - try: - self._push_stock_to_remote() - except Exception as e: - # Never block local operations due to sync failure - _logger.warning(f'Remote stock push failed (non-blocking): {e}') - - return res - - def _push_stock_to_remote(self): - """Push stock level changes to the remote Odoo instance. - - Only pushes for products that have a sync mapping. - Runs async-safe: failures don't block local operations. - """ - if not self: - return - - # Get unique product templates from completed moves - product_tmpls = self.mapped('product_id.product_tmpl_id') - if not product_tmpls: - return - - # Find sync mappings for these products - Mapping = self.env['fusion.product.sync.mapping'] - mappings = Mapping.search([ - ('local_product_id', 'in', product_tmpls.ids), - ('config_id.active', '=', True), - ('config_id.state', '=', 'connected'), - ('remote_product_id', '!=', 0), - ]) - - if not mappings: - return - - # Group by config for efficient batch push - configs = {} - for mapping in mappings: - config = mapping.config_id - if config.id not in configs: - configs[config.id] = { - 'config': config, - 'mappings': self.env['fusion.product.sync.mapping'], - } - configs[config.id]['mappings'] |= mapping - - for config_data in configs.values(): - config = config_data['config'] - config_mappings = config_data['mappings'] - try: - self._push_stock_levels(config, config_mappings) - except Exception as e: - _logger.warning( - f'Failed to push stock to {config.name}: {e}' - ) - - def _push_stock_levels(self, config, mappings): - """Push current local stock levels to the remote instance. - - This updates the remote side with our current on-hand qty - so the remote instance knows what we have available. - """ - uid, models_proxy = config._get_xmlrpc_connection() - - for mapping in mappings: - local_product = mapping.local_product_id - if not local_product: - continue - - # Get current local stock for this product - local_qty = local_product.qty_available - local_forecast = local_product.virtual_available - - # Update the mapping record with current local stock - mapping.write({ - 'last_stock_sync': fields.Datetime.now(), - }) - - # Log the push for debugging - _logger.info( - f'Stock push: {local_product.name} -> {config.name} ' - f'(local_qty={local_qty}, remote_id={mapping.remote_product_id})' - ) - - # Optionally update a custom field on the remote side - # This writes to a field on the remote product to track - # what the partner store has available - try: - models_proxy.execute_kw( - config.db_name, uid, config.api_key, - 'product.template', 'write', - [[mapping.remote_product_id], { - 'x_partner_qty_available': local_qty, - }] - ) - except Exception as e: - # If the remote field doesn't exist yet, just log it - _logger.debug( - f'Could not update remote field x_partner_qty_available: {e}. ' - f'Create this field on the remote instance for full bi-directional sync.' - ) diff --git a/fusion_inventory_sync/models/sync_config.py b/fusion_inventory_sync/models/sync_config.py deleted file mode 100644 index 8924bfef..00000000 --- a/fusion_inventory_sync/models/sync_config.py +++ /dev/null @@ -1,257 +0,0 @@ -# -*- coding: utf-8 -*- -import logging -import xmlrpc.client -from odoo import models, fields, api -from odoo.exceptions import UserError - -_logger = logging.getLogger(__name__) - - -class FusionSyncConfig(models.Model): - """Configuration for remote Odoo instance connection.""" - _name = 'fusion.sync.config' - _description = 'Inventory Sync Configuration' - _rec_name = 'name' - - name = fields.Char(string='Connection Name', required=True) - url = fields.Char(string='Remote URL', required=True, - help='Full URL of the remote Odoo instance (e.g., https://erp.mobilityspecialties.com)') - db_name = fields.Char(string='Database Name', required=True, - help='Name of the remote database') - username = fields.Char(string='Username', required=True, - help='Login username for the remote instance') - api_key = fields.Char(string='API Key / Password', required=True, - help='API key or password for authentication') - active = fields.Boolean(default=True) - state = fields.Selection([ - ('draft', 'Not Connected'), - ('connected', 'Connected'), - ('error', 'Connection Error'), - ], string='Status', default='draft', readonly=True) - last_sync = fields.Datetime(string='Last Sync', readonly=True) - last_sync_status = fields.Text(string='Last Sync Result', readonly=True) - sync_interval = fields.Integer(string='Sync Interval (minutes)', default=30, - help='How often to run the automatic sync') - remote_uid = fields.Integer(string='Remote User ID', readonly=True) - company_id = fields.Many2one('res.company', string='Company', - default=lambda self: self.env.company) - - # Sync scope - sync_products = fields.Boolean(string='Sync Products', default=True) - sync_stock = fields.Boolean(string='Sync Stock Levels', default=True) - remote_warehouse_name = fields.Char(string='Remote Warehouse Name', - help='Name of the warehouse on the remote instance to read stock from. Leave empty for all.') - - def _get_xmlrpc_connection(self): - """Establish XML-RPC connection to the remote Odoo instance.""" - self.ensure_one() - url = self.url.rstrip('/') - try: - common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common', allow_none=True) - uid = common.authenticate(self.db_name, self.username, self.api_key, {}) - if not uid: - raise UserError('Authentication failed. Check username/API key.') - models_proxy = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object', allow_none=True) - return uid, models_proxy - except xmlrpc.client.Fault as e: - raise UserError(f'XML-RPC error: {e.faultString}') - except Exception as e: - raise UserError(f'Connection error: {str(e)}') - - def action_test_connection(self): - """Test the connection to the remote Odoo instance.""" - self.ensure_one() - try: - uid, models_proxy = self._get_xmlrpc_connection() - # Test by reading the server version - version_info = xmlrpc.client.ServerProxy( - f'{self.url.rstrip("/")}/xmlrpc/2/common', allow_none=True - ).version() - self.write({ - 'state': 'connected', - 'remote_uid': uid, - 'last_sync_status': f'Connection successful. Remote server: {version_info.get("server_serie", "unknown")}', - }) - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Connection Successful', - 'message': f'Connected to {self.url} as user ID {uid}', - 'type': 'success', - 'sticky': False, - }, - } - except Exception as e: - self.write({ - 'state': 'error', - 'last_sync_status': f'Connection failed: {str(e)}', - }) - raise - - def action_sync_now(self): - """Manually trigger a full sync.""" - self.ensure_one() - self._run_sync() - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': 'Sync Complete', - 'message': self.last_sync_status, - 'type': 'success', - 'sticky': False, - }, - } - - def _run_sync(self): - """Execute the sync process.""" - self.ensure_one() - try: - uid, models_proxy = self._get_xmlrpc_connection() - results = [] - - if self.sync_products: - count = self._sync_products(uid, models_proxy) - results.append(f'{count} products synced') - - if self.sync_stock: - count = self._sync_stock_levels(uid, models_proxy) - results.append(f'{count} stock levels updated') - - status = ' | '.join(results) if results else 'Nothing to sync' - self.write({ - 'state': 'connected', - 'last_sync': fields.Datetime.now(), - 'last_sync_status': status, - }) - - # Log the sync operation - self.env['fusion.sync.log'].create({ - 'config_id': self.id, - 'direction': 'pull', - 'sync_type': 'full', - 'status': 'success', - 'summary': status, - 'product_count': sum(1 for r in results if 'product' in r.lower()), - }) - _logger.info(f'Inventory sync complete: {status}') - - except Exception as e: - error_msg = f'Sync failed: {str(e)}' - self.write({ - 'state': 'error', - 'last_sync': fields.Datetime.now(), - 'last_sync_status': error_msg, - }) - _logger.error(error_msg) - - def _sync_products(self, uid, models_proxy): - """Sync product catalog from remote instance.""" - self.ensure_one() - Mapping = self.env['fusion.product.sync.mapping'] - - # Read remote products (only storable/consumable, with internal reference) - remote_products = models_proxy.execute_kw( - self.db_name, uid, self.api_key, - 'product.template', 'search_read', - [[('type', 'in', ['consu', 'product'])]], - {'fields': ['id', 'name', 'default_code', 'list_price', 'type', 'categ_id'], - 'limit': 5000} - ) - - synced = 0 - for rp in remote_products: - # Try to find existing mapping - mapping = Mapping.search([ - ('config_id', '=', self.id), - ('remote_product_id', '=', rp['id']), - ], limit=1) - - vals = { - 'config_id': self.id, - 'remote_product_id': rp['id'], - 'remote_product_name': rp.get('name', ''), - 'remote_default_code': rp.get('default_code', '') or '', - 'remote_list_price': rp.get('list_price', 0), - 'remote_category': rp.get('categ_id', [False, ''])[1] if rp.get('categ_id') else '', - } - - if mapping: - mapping.write(vals) - else: - # Try auto-match by internal reference (SKU) - local_product = False - if rp.get('default_code'): - local_product = self.env['product.template'].search([ - ('default_code', '=', rp['default_code']) - ], limit=1) - # Fallback: try match by exact name - if not local_product and rp.get('name'): - local_product = self.env['product.template'].search([ - ('name', 'ilike', rp['name']) - ], limit=1) - - vals['local_product_id'] = local_product.id if local_product else False - vals['auto_matched'] = bool(local_product) - Mapping.create(vals) - - synced += 1 - - return synced - - def _sync_stock_levels(self, uid, models_proxy): - """Sync stock quantities from remote instance.""" - self.ensure_one() - Mapping = self.env['fusion.product.sync.mapping'] - - # Get all mappings with remote product IDs - mappings = Mapping.search([ - ('config_id', '=', self.id), - ('remote_product_id', '!=', 0), - ]) - - if not mappings: - return 0 - - # Build list of remote product template IDs - remote_tmpl_ids = mappings.mapped('remote_product_id') - - # Get remote product.product IDs for these templates - remote_products = models_proxy.execute_kw( - self.db_name, uid, self.api_key, - 'product.product', 'search_read', - [[('product_tmpl_id', 'in', remote_tmpl_ids)]], - {'fields': ['id', 'product_tmpl_id', 'qty_available', 'virtual_available']} - ) - - # Build dict: template_id -> stock info - stock_by_tmpl = {} - for rp in remote_products: - tmpl_id = rp['product_tmpl_id'][0] if isinstance(rp['product_tmpl_id'], list) else rp['product_tmpl_id'] - if tmpl_id not in stock_by_tmpl: - stock_by_tmpl[tmpl_id] = {'qty_available': 0, 'virtual_available': 0} - stock_by_tmpl[tmpl_id]['qty_available'] += rp.get('qty_available', 0) - stock_by_tmpl[tmpl_id]['virtual_available'] += rp.get('virtual_available', 0) - - updated = 0 - for mapping in mappings: - stock = stock_by_tmpl.get(mapping.remote_product_id, {}) - mapping.write({ - 'remote_qty_available': stock.get('qty_available', 0), - 'remote_qty_forecast': stock.get('virtual_available', 0), - 'last_stock_sync': fields.Datetime.now(), - }) - updated += 1 - - return updated - - @api.model - def _cron_sync_inventory(self): - """Cron job: run sync for all active configurations.""" - configs = self.search([('active', '=', True), ('state', '!=', 'draft')]) - for config in configs: - try: - config._run_sync() - except Exception as e: - _logger.error(f'Cron sync failed for {config.name}: {e}') diff --git a/fusion_inventory_sync/security/ir.model.access.csv b/fusion_inventory_sync/security/ir.model.access.csv deleted file mode 100644 index 2b5321d8..00000000 --- a/fusion_inventory_sync/security/ir.model.access.csv +++ /dev/null @@ -1,7 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_sync_config_manager,fusion.sync.config.manager,model_fusion_sync_config,stock.group_stock_manager,1,1,1,1 -access_sync_config_user,fusion.sync.config.user,model_fusion_sync_config,stock.group_stock_user,1,0,0,0 -access_sync_mapping_manager,fusion.product.sync.mapping.manager,model_fusion_product_sync_mapping,stock.group_stock_manager,1,1,1,1 -access_sync_mapping_user,fusion.product.sync.mapping.user,model_fusion_product_sync_mapping,stock.group_stock_user,1,0,0,0 -access_sync_log_manager,fusion.sync.log.manager,model_fusion_sync_log,stock.group_stock_manager,1,1,1,1 -access_sync_log_user,fusion.sync.log.user,model_fusion_sync_log,stock.group_stock_user,1,0,0,0 diff --git a/fusion_inventory_sync/static/description/icon.png b/fusion_inventory_sync/static/description/icon.png deleted file mode 100644 index adb75fa9630b10a7644394e33b22760d8072e507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46059 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 diff --git a/fusion_inventory_sync/views/product_views.xml b/fusion_inventory_sync/views/product_views.xml deleted file mode 100644 index 00d3a916..00000000 --- a/fusion_inventory_sync/views/product_views.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - product.template.list.sync - product.template - - - - - - - - - - - - product.template.form.sync - product.template - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fusion_inventory_sync/views/sync_config_views.xml b/fusion_inventory_sync/views/sync_config_views.xml deleted file mode 100644 index 34fa6db9..00000000 --- a/fusion_inventory_sync/views/sync_config_views.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - fusion.sync.config.form - fusion.sync.config - -

-
-
- -
-

-
- - - - - - - - - - - - - - - - - - - - - - - -

- Connect and sync to see product mappings here. -

-
-
-
-
- - - - - - fusion.sync.config.list - fusion.sync.config - - - - - - - - - - - - - - fusion.product.sync.mapping.list - fusion.product.sync.mapping - - - - - - - - - - - - - - - - - fusion.product.sync.mapping.search - fusion.product.sync.mapping - - - - - - - - - - - - - - - - - - Sync Configurations - fusion.sync.config - list,form - - - - - Product Mappings - fusion.product.sync.mapping - list - {'search_default_mapped': 1} - - - - - - fusion.sync.log.list - fusion.sync.log - - - - - - - - - - - - - - - Sync Log - fusion.sync.log - list - - - -