From 3b8d48c16f90de943d9f3ebed54c8cc1edf6fbdd Mon Sep 17 00:00:00 2001 From: ignacio Date: Fri, 20 Mar 2020 12:44:08 +0100 Subject: [PATCH 1/2] Initial commit Amazon Integration --- amazon_integration/__init__.py | 2 + amazon_integration/__manifest__.py | 30 + amazon_integration/data/ir_cron.xml | 17 + amazon_integration/data/product_data.xml | 23 + amazon_integration/i18n/es.po | 556 ++++++++++++++++++ amazon_integration/models/__init__.py | 4 + .../models/amazon_marketplace.py | 59 ++ amazon_integration/models/amazon_seller.py | 438 ++++++++++++++ .../models/res_config_settings.py | 28 + amazon_integration/models/sale_order.py | 24 + amazon_integration/readme/CONTRIBUTORS.rst | 3 + amazon_integration/readme/DESCRIPTION.rst | 1 + amazon_integration/readme/USAGE.rst | 6 + .../security/ir.model.access.csv | 3 + .../static/description/icon.png | Bin 0 -> 43665 bytes .../views/amazon_marketplace.xml | 123 ++++ amazon_integration/views/amazon_menuitems.xml | 56 ++ amazon_integration/views/amazon_seller.xml | 71 +++ .../views/res_config_settings.xml | 38 ++ amazon_integration/views/sale_order.xml | 39 ++ amazon_integration/wizard/__init__.py | 0 requirements.txt | 1 + 22 files changed, 1522 insertions(+) create mode 100644 amazon_integration/__init__.py create mode 100644 amazon_integration/__manifest__.py create mode 100644 amazon_integration/data/ir_cron.xml create mode 100644 amazon_integration/data/product_data.xml create mode 100644 amazon_integration/i18n/es.po create mode 100644 amazon_integration/models/__init__.py create mode 100644 amazon_integration/models/amazon_marketplace.py create mode 100644 amazon_integration/models/amazon_seller.py create mode 100644 amazon_integration/models/res_config_settings.py create mode 100644 amazon_integration/models/sale_order.py create mode 100644 amazon_integration/readme/CONTRIBUTORS.rst create mode 100644 amazon_integration/readme/DESCRIPTION.rst create mode 100644 amazon_integration/readme/USAGE.rst create mode 100644 amazon_integration/security/ir.model.access.csv create mode 100644 amazon_integration/static/description/icon.png create mode 100644 amazon_integration/views/amazon_marketplace.xml create mode 100644 amazon_integration/views/amazon_menuitems.xml create mode 100644 amazon_integration/views/amazon_seller.xml create mode 100644 amazon_integration/views/res_config_settings.xml create mode 100644 amazon_integration/views/sale_order.xml create mode 100644 amazon_integration/wizard/__init__.py create mode 100644 requirements.txt diff --git a/amazon_integration/__init__.py b/amazon_integration/__init__.py new file mode 100644 index 00000000..9b429614 --- /dev/null +++ b/amazon_integration/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/amazon_integration/__manifest__.py b/amazon_integration/__manifest__.py new file mode 100644 index 00000000..b5b1eb79 --- /dev/null +++ b/amazon_integration/__manifest__.py @@ -0,0 +1,30 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Amazon Integration', + 'summary': """ + Amazon Integration""", + 'version': '12.0.1.0.0', + 'license': 'AGPL-3', + 'website': 'https://github.com/OCA/connector-ecommerce', + 'depends': ['sale_management', 'stock'], + 'category': 'Sales', + 'author': 'Domatix, ' + 'Odoo Community Association (OCA)', + 'external_dependencies': { + 'python': [ + 'mws', + ], + }, + 'data': ['security/ir.model.access.csv', + 'data/ir_cron.xml', + 'data/product_data.xml', + 'views/amazon_marketplace.xml', + 'views/amazon_seller.xml', + 'views/res_config_settings.xml', + 'views/amazon_menuitems.xml', + 'views/sale_order.xml', + ], + 'development_status': 'Alpha', + 'installable': True, +} diff --git a/amazon_integration/data/ir_cron.xml b/amazon_integration/data/ir_cron.xml new file mode 100644 index 00000000..ec86a4cd --- /dev/null +++ b/amazon_integration/data/ir_cron.xml @@ -0,0 +1,17 @@ + + + + + Amazon: import orders + + code + model.import_orders() + + 1 + hours + -1 + + + 1000 + + diff --git a/amazon_integration/data/product_data.xml b/amazon_integration/data/product_data.xml new file mode 100644 index 00000000..a6e3ee5a --- /dev/null +++ b/amazon_integration/data/product_data.xml @@ -0,0 +1,23 @@ + + + + + Amazon Shipping Costs + SHIP AMAZON + service + 0.0 + + + Amazon Gift Costs + GIFT AMAZON + service + 0.0 + + + Amazon Product Not Found + Amazon Not Found + product + 0.0 + + + diff --git a/amazon_integration/i18n/es.po b/amazon_integration/i18n/es.po new file mode 100644 index 00000000..cb6f5939 --- /dev/null +++ b/amazon_integration/i18n/es.po @@ -0,0 +1,556 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * amazon_integration +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-11-07 13:26+0000\n" +"PO-Revision-Date: 2019-11-07 13:26+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_res_config_settings_form +msgid "Amazon User\n" +" " +msgstr "" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_kanban +msgid "Import Market Orders" +msgstr "Importar pedidos" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__access_key +msgid "Access Key" +msgstr "Clave de acceso" + +#. module: amazon_integration +#: model:ir.model,name:amazon_integration.model_amazon_seller +msgid "Account for Amazon MWS" +msgstr "Cuenta para Amazon MWS" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_needaction +msgid "Action Needed" +msgstr "Acción Necesaria" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__activity_ids +msgid "Activities" +msgstr "Actividades" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__activity_state +msgid "Activity State" +msgstr "Estado de la actividad" + +#. module: amazon_integration +#: model:ir.ui.menu,name:amazon_integration.amazon_menu +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_res_config_settings_form +msgid "Amazon" +msgstr "" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_sale_order__amazon_fulfillment +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_sale_order_search +msgid "Amazon Fulfillment" +msgstr "" + +#. module: amazon_integration +#: model:product.product,name:amazon_integration.amazon_gift_product +#: model:product.template,name:amazon_integration.amazon_gift_product_product_template +msgid "Amazon Gift Costs" +msgstr "Costes de regalo de Amazon" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_sale_ref_form +msgid "Amazon Info" +msgstr "Información de Amazon" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_sale_order__amazon_marketplace_id +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_form +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_sale_order_search +msgid "Amazon Marketplace" +msgstr "" + +#. module: amazon_integration +#: model:ir.model,name:amazon_integration.model_amazon_marketplace +msgid "Amazon Markets from a seller" +msgstr "Amazon martketplaces de un vendedor" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_sale_order_line__amazon_order_item_id +msgid "Amazon Order Item Id" +msgstr "" + +#. module: amazon_integration +#: model:product.product,name:amazon_integration.amazon_not_found_product +#: model:product.template,name:amazon_integration.amazon_not_found_product_product_template +msgid "Amazon Product Not Found" +msgstr "Amazon producto no encontrado" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_sale_order__amazon_reference +msgid "Amazon Reference" +msgstr "Amazon referencia" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_form +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_search +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_tree +msgid "Amazon Seller" +msgstr "Amazon Vendedor" + +#. module: amazon_integration +#: model:product.product,name:amazon_integration.amazon_shipping_product +#: model:product.template,name:amazon_integration.amazon_shipping_product_product_template +msgid "Amazon Shipping Costs" +msgstr "Costes de envío de Amazon" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_search +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_tree +msgid "Amazon marketplace" +msgstr "Amazon marketplace" + +#. module: amazon_integration +#: model:ir.actions.server,name:amazon_integration.ir_cron_import_amazon_orders_ir_actions_server +#: model:ir.cron,cron_name:amazon_integration.ir_cron_import_amazon_orders +#: model:ir.cron,name:amazon_integration.ir_cron_import_amazon_orders +msgid "Amazon: import orders" +msgstr "Amazon: importar órdenes" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_attachment_count +msgid "Attachment Count" +msgstr "Conteo de archivos adjuntos" + +#. module: amazon_integration +#: model_terms:ir.actions.act_window,help:amazon_integration.amazon_seller_action +msgid "Click to create a new Seller." +msgstr "Pulsa para crear un nuevo vendedor" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__color +msgid "Color Index" +msgstr "Índice de Colores" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_res_config_settings__amazon_user_id +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_res_config_settings_form +msgid "Commercial" +msgstr "Comercial" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__company_id +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__company_id +msgid "Company" +msgstr "Compañía" + +#. module: amazon_integration +#: model:ir.model,name:amazon_integration.model_res_config_settings +msgid "Config Settings" +msgstr "Ajustes de configuración" + +#. module: amazon_integration +#: model:ir.ui.menu,name:amazon_integration.amazon_config_menu +msgid "Configuration" +msgstr "Configuración" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__country_id +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__country_id +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_kanban +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_search +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_search +msgid "Country" +msgstr "País" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__create_uid +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__create_date +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: amazon_integration +#: model:ir.actions.act_window,name:amazon_integration.amazon_marketplace_dashboard_action +#: model:ir.ui.menu,name:amazon_integration.amazon_dashboard_menu +msgid "Dashboard" +msgstr "Tablero" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_seller__last_import_date_seller +msgid "Date from the last order synced" +msgstr "Fecha del último pedido sincronizado" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_res_config_settings_form +msgid "Default products" +msgstr "Productos por defecto" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_res_config_settings_form +msgid "Default user for sales" +msgstr "Comercial por defecto en ventas" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_kanban +msgid "Delete" +msgstr "Suprimir" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__display_name +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_kanban +msgid "Dropdown menu" +msgstr "Menú desplegable" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_kanban +msgid "Edit" +msgstr "Editar" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_sale_order_search +#: selection:sale.order,amazon_fulfillment:0 +msgid "FBA" +msgstr "" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_sale_order_search +#: selection:sale.order,amazon_fulfillment:0 +msgid "FBM" +msgstr "" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__fiscal_position_id +msgid "Fiscal Position" +msgstr "Posición fiscal" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_follower_ids +msgid "Followers" +msgstr "Seguidores" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_channel_ids +msgid "Followers (Channels)" +msgstr "Seguidores (Canales)" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_partner_ids +msgid "Followers (Partners)" +msgstr "Seguidores (Empresas)" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_search +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_search +msgid "Group By" +msgstr "Agrupar por" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__id +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__id +msgid "ID" +msgstr "" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__message_unread +msgid "If checked new messages require your attention." +msgstr "Si está marcado, hay nuevos mensajes que requieren su atención" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__message_needaction +msgid "If checked, new messages require your attention." +msgstr "Si está marcado, hay nuevos mensajes que requieren su atención." + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__message_has_error +msgid "If checked, some messages have a delivery error." +msgstr "Si se encuentra marcado, algunos mensajes tienen error de envío." + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_form +msgid "Import Market Orders" +msgstr "Importar pedidos" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_form +msgid "Import Marketplaces" +msgstr "Importar Marketplaces" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_form +msgid "Import Orders" +msgstr "Importar pedidos" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_form +msgid "Invoice Info" +msgstr "Facturación" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_is_follower +msgid "Is Follower" +msgstr "Es un seguidor" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__lang_id +msgid "Language" +msgstr "Idioma" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__last_import_date +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__last_import_date_seller +msgid "Last Import Date" +msgstr "Fecha de sincronización" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace____last_update +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__write_uid +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__write_date +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_main_attachment_id +msgid "Main Attachment" +msgstr "Adjuntos principales" + +#. module: amazon_integration +#: model:ir.actions.act_window,name:amazon_integration.amazon_marketplace_action +#: model:ir.ui.menu,name:amazon_integration.amazon_marketplace_menu +msgid "Marketplace" +msgstr "Marketplace" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__market_code +msgid "Marketplace ID" +msgstr "" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_form +msgid "Marketplace Settings" +msgstr "Ajustes del Marketplace" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__marketplace_ids +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_form +msgid "Marketplaces" +msgstr "Marketplaces" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__merchant_id +msgid "Merchant ID" +msgstr "" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_has_error +msgid "Message Delivery error" +msgstr "Error de Envío de Mensaje" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_ids +msgid "Messages" +msgstr "Mensajes" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__name +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__name +msgid "Name" +msgstr "Nombre" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "Siguiente plazo de actividad" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__activity_summary +msgid "Next Activity Summary" +msgstr "Resumen de la siguiente actividad" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__activity_type_id +msgid "Next Activity Type" +msgstr "Siguiente tipo de actividad" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_needaction_counter +msgid "Number of Actions" +msgstr "Número de acciones" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_has_error_counter +msgid "Number of error" +msgstr "Número de error" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "Número de mensajes que requieren una acción" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "Número de mensajes con error de envío" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__message_unread_counter +msgid "Number of unread messages" +msgstr "Número de mensajes no leidos" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_marketplace_form +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_res_config_settings_form +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_sale_ref_form +msgid "Order Info" +msgstr "Ventas" + +#. module: amazon_integration +#: selection:amazon.marketplace,activity_state:0 +msgid "Overdue" +msgstr "Atrasado" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__payment_term_id +msgid "Payment Term" +msgstr "Plazo de pago" + +#. module: amazon_integration +#: selection:amazon.marketplace,activity_state:0 +msgid "Planned" +msgstr "Planeado" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__pricelist_id +msgid "Pricelist" +msgstr "Tarifa" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__activity_user_id +msgid "Responsible User" +msgstr "Usuario responsable" + +#. module: amazon_integration +#: model:ir.model,name:amazon_integration.model_sale_order +msgid "Sale Order" +msgstr "Pedido de venta" + +#. module: amazon_integration +#: model:ir.model,name:amazon_integration.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea de pedido de venta" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_seller__secret_key +msgid "Secret Key" +msgstr "Clave secreta" + +#. module: amazon_integration +#: model:ir.actions.act_window,name:amazon_integration.amazon_seller_action +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__seller_id +#: model:ir.ui.menu,name:amazon_integration.amazon_seller_menu +msgid "Seller" +msgstr "Vendedor" + +#. module: amazon_integration +#: model:ir.actions.act_window,name:amazon_integration.amazon_res_config_settings_action +#: model:ir.ui.menu,name:amazon_integration.amazon_res_config_settings_menu +msgid "Settings" +msgstr "Configuración" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__activity_state +msgid "Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "Estado basado en actividades\n" +"Vencida: la fecha tope ya ha pasado\n" +"Hoy: La fecha tope es hoy\n" +"Planificada: futuras actividades." + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__tax_id +msgid "Tax" +msgstr "Impuesto" + +#. module: amazon_integration +#: selection:amazon.marketplace,activity_state:0 +msgid "Today" +msgstr "Hoy" + +#. module: amazon_integration +#: model:product.product,uom_name:amazon_integration.amazon_gift_product +#: model:product.product,uom_name:amazon_integration.amazon_not_found_product +#: model:product.product,uom_name:amazon_integration.amazon_shipping_product +#: model:product.template,uom_name:amazon_integration.amazon_gift_product_product_template +#: model:product.template,uom_name:amazon_integration.amazon_not_found_product_product_template +#: model:product.template,uom_name:amazon_integration.amazon_shipping_product_product_template +msgid "Unit(s)" +msgstr "Unidad(es)" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_unread +msgid "Unread Messages" +msgstr "Mensajes por leer" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__message_unread_counter +msgid "Unread Messages Counter" +msgstr "Contador de mensajes sin leer" + +#. module: amazon_integration +#: model:ir.model.fields,field_description:amazon_integration.field_amazon_marketplace__website_message_ids +msgid "Website Messages" +msgstr "Mensajes del sitio web" + +#. module: amazon_integration +#: model:ir.model.fields,help:amazon_integration.field_amazon_marketplace__website_message_ids +msgid "Website communication history" +msgstr "Historial de comunicaciones del sitio web" + +#. module: amazon_integration +#: model_terms:ir.ui.view,arch_db:amazon_integration.view_amazon_seller_form +msgid "e.g Spanish Seller" +msgstr "ej. Vendedor S.L." + +#. module: amazon_integration +#: model:product.product,weight_uom_name:amazon_integration.amazon_gift_product +#: model:product.product,weight_uom_name:amazon_integration.amazon_not_found_product +#: model:product.product,weight_uom_name:amazon_integration.amazon_shipping_product +#: model:product.template,weight_uom_name:amazon_integration.amazon_gift_product_product_template +#: model:product.template,weight_uom_name:amazon_integration.amazon_not_found_product_product_template +#: model:product.template,weight_uom_name:amazon_integration.amazon_shipping_product_product_template +msgid "kg" +msgstr "" diff --git a/amazon_integration/models/__init__.py b/amazon_integration/models/__init__.py new file mode 100644 index 00000000..e80b8490 --- /dev/null +++ b/amazon_integration/models/__init__.py @@ -0,0 +1,4 @@ +from . import amazon_seller +from . import amazon_marketplace +from . import res_config_settings +from . import sale_order diff --git a/amazon_integration/models/amazon_marketplace.py b/amazon_integration/models/amazon_marketplace.py new file mode 100644 index 00000000..649acbb0 --- /dev/null +++ b/amazon_integration/models/amazon_marketplace.py @@ -0,0 +1,59 @@ +from odoo import models, fields +from datetime import datetime + + +class AmazonMarketplace(models.Model): + _name = 'amazon.marketplace' + _description = 'Amazon Markets from a seller' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char( + string='Name', + track_visibility='onchange') + + market_code = fields.Char( + string='Marketplace ID', + track_visibility='onchange') + + color = fields.Integer( + string='Color Index') + + country_id = fields.Many2one( + comodel_name='res.country', + string='Country') + + lang_id = fields.Many2one( + comodel_name='res.lang', + string='Language') + + seller_id = fields.Many2one( + comodel_name='amazon.seller', + string='Seller') + + pricelist_id = fields.Many2one( + comodel_name='product.pricelist', + string='Pricelist') + + company_id = fields.Many2one( + comodel_name='res.company', + string='Company') + + last_import_date = fields.Datetime( + string='Last Import Date', + default=datetime.now()) + + fiscal_position_id = fields.Many2one( + comodel_name='account.fiscal.position', + string='Fiscal Position') + + payment_term_id = fields.Many2one( + comodel_name='account.payment.term', + string='Payment Term') + + # Import FBM and FBA orders + + def import_market_orders(self): + self.seller_id.import_orders(marketplaces=self, + seller=self.seller_id, + last_import_date=self.last_import_date, + single_market=True) diff --git a/amazon_integration/models/amazon_seller.py b/amazon_integration/models/amazon_seller.py new file mode 100644 index 00000000..ca5c21a7 --- /dev/null +++ b/amazon_integration/models/amazon_seller.py @@ -0,0 +1,438 @@ +from odoo import models, fields +from mws import Sellers, Orders +from dateutil.parser import parse +from datetime import datetime +import time +from dateutil import parser +import pytz +utc = pytz.utc + + +class AmazonSeller(models.Model): + _name = 'amazon.seller' + _description = 'Account for Amazon MWS' + + name = fields.Char( + string='Name', + required=True) + + company_id = fields.Many2one( + comodel_name='res.company', + string='Company', + default=lambda self: self.env['res.company']._company_default_get( + 'amazon.seller')) + + access_key = fields.Char( + string='Access Key') + + secret_key = fields.Char( + string='Secret Key') + + merchant_id = fields.Char( + string='Merchant ID') + + country_id = fields.Many2one( + comodel_name='res.country', + string='Country', + required=True) + + marketplace_ids = fields.One2many( + comodel_name='amazon.marketplace', + inverse_name='seller_id', + string='Marketplaces') + + last_import_date_seller = fields.Datetime( + string='Last Import Date', + default=datetime.now(), + help='Date from the last order synced') + + def get_marketplaces(self): + mws_connection = Sellers(access_key=str(self.access_key), + secret_key=str(self.secret_key), + account_id=str(self.merchant_id), + region=self.country_id.code, + ) + marketplace_obj = self.env['amazon.marketplace'] + pricelist_obj = self.env['product.pricelist'] + lang_obj = self.env['res.lang'] + country_obj = self.env['res.country'] + list_result = [] + try: + result = mws_connection.list_marketplace_participations() + result.parsed.get('ListParticipations', {}) + except Exception as e: + raise Warning('Given Credentials is incorrect, \ + please provide correct Credentials.' + str(e)) + + list_result.append(result) + next_token = result.parsed.get('NextToken', {}).get('value') + while next_token: + try: + result = mws_connection.\ + list_marketplace_participations_by_next_token(next_token) + except Exception as e: + raise Warning(str(e)) + next_token = result.parsed.get('NextToken', {}).get('value') + list_result.append(result) + + for element in list_result: + element = element.parsed + list_marketplaces = element.get('ListMarketplaces', {}) + marketplaces = list_marketplaces.get('Marketplace', []) + if not isinstance(marketplaces, list): + marketplaces = [marketplaces] + + for marketplace in marketplaces: + marketplace_id = marketplace.get( + 'MarketplaceId', {}).get('value', '') + country_code = marketplace.get('DefaultCountryCode', {}).get( + 'value') + name = marketplace.get('Name', {}).get('value', '') + lang_code = marketplace.get( + 'DefaultLanguageCode', {}).get('value', '') + currency_code = marketplace.get( + 'DefaultCurrencyCode', {}).get('value', '') + pricelist_id = pricelist_obj.search([( + 'name', '=', currency_code)]) + lang_id = lang_obj.search([('code', '=', lang_code)]) + country_id = country_obj.search([('code', '=', country_code)]) + + vals = { + 'seller_id': self.id, + 'name': name, + 'market_code': marketplace_id, + 'pricelist_id': pricelist_id and pricelist_id[0].id or + False, + 'lang_id': lang_id and lang_id[0].id or False, + 'country_id': country_id and country_id[0].id or + self.country_id and self.country_id.id or False, + 'company_id': self.company_id.id, + } + marketplace_rec = marketplace_obj.search( + [('seller_id', '=', self.id), + ('market_code', '=', marketplace_id)]) + if marketplace_rec: + marketplace_rec.write(vals) + else: + marketplace_obj.create(vals) + return True + + # Create FBM and FBA orders + def action_import_orders(self): + self.import_orders() + + def import_orders(self, marketplaces=False, seller=False, + last_import_date=False, single_market=False): + if not seller: + seller = self.env['amazon.seller'].search([], limit=1) + if not marketplaces: + marketplaces = seller.marketplace_ids + if not last_import_date: + last_import_date = seller.last_import_date_seller.isoformat( + sep='T') + else: + last_import_date = last_import_date.isoformat(sep='T') + + mws_obj = Orders(access_key=str(seller.access_key), + secret_key=str(seller.secret_key), + account_id=str(seller.merchant_id), + region=seller.country_id.code + ) + + has_next = True + next_token = None + orders_data = [] + market_obj = self.env['amazon.marketplace'] + marketplaceids = marketplaces.mapped('market_code') + orderstatus = ('Unshipped', 'PartiallyShipped', 'Shipped') + while has_next: + time.sleep(1) + order_data = mws_obj.list_orders( + marketplaceids=marketplaceids, + created_after=last_import_date, + orderstatus=orderstatus, + next_token=next_token, + ) + orders = order_data.parsed.get('Orders', {}).get('Order', []) + if orders and isinstance(orders, dict): + orders_data.append(orders) + elif orders and isinstance(orders, list): + orders_data += orders + for order in orders_data: + market_code = order.get( + 'MarketplaceId', {}).get( + 'value', False) + marketplace = market_obj.search([ + ('market_code', '=', market_code)]) + sale_channel = order.get( + 'SalesChannel', {}).get( + 'value', 'sale') + if sale_channel == 'Non-Amazon': + continue + seller._create_sale_order(order, marketplace, mws_obj) + # Date to synchronize every time an order is imported + last_purchase_date = order.get('PurchaseDate').get('value') + last_purchase_date = parse( + last_purchase_date).replace(tzinfo=None) + if single_market: + marketplace.last_import_date = last_purchase_date + else: + seller.last_import_date_seller = last_purchase_date + marketplace.last_import_date = last_purchase_date + # commit a batch of 100 orders due to request throttled from Amazon + self.env.cr.commit() + next_token = order_data.parsed.get('NextToken', {}).get('value') + has_next = bool(next_token) + + def _create_sale_order(self, order, marketplace, mws_obj): + IrDefault = self.env['ir.default'].sudo() + amazon_user = IrDefault.get('res.config.settings', 'amazon_user_id') + sale_obj = self.env['sale.order'] + amazon_order_ref = order.get('AmazonOrderId').get('value') + fulfillment_channel = order.get('FulfillmentChannel').get('value') + amazon_fulfillment = 'fba' if fulfillment_channel == 'AFN' else 'fbm' + date_order = parser.parse( + order.get('PurchaseDate').get('value')).astimezone(utc) + pricelist = marketplace.pricelist_id + invoice_partner, delivery_partner = self._get_partner(order) + order_found = sale_obj.search([ + ('amazon_reference', '=', amazon_order_ref)]) + if not order_found: + ord_lines = self._create_sale_order_lines( + amazon_order_ref, marketplace, mws_obj) + order = sale_obj.create({ + 'origin': amazon_order_ref, + 'date_order': date_order, + 'partner_id': invoice_partner.id, + 'partner_shipping_id': delivery_partner.id, + 'pricelist_id': pricelist.id, + 'order_line': [(0, 0, order_line) for order_line in ord_lines], + 'fiscal_position_id': marketplace.fiscal_position_id.id, + 'amazon_reference': amazon_order_ref, + 'amazon_fulfillment': amazon_fulfillment, + 'company_id': self.company_id.id, + 'user_id': amazon_user, + 'amazon_marketplace_id': marketplace.id, + 'payment_term_id': marketplace.payment_term_id.id, + }) + + def _get_partner(self, order): + partner_obj = self.env['res.partner'] + country_obj = self.env['res.country'] + lang_obj = self.env['res.lang'] + state_obj = self.env['res.country.state'] + shipping_address = order.get('ShippingAddress', {}) + country_code = shipping_address.get('CountryCode', {}).get('value') + country = country_obj.search([('code', '=', country_code)], limit=1) + lang = False + if country_code: + country_code_lower = country_code.lower() + lang = lang_obj.search([('iso_code', '=', country_code_lower)]) + state_code = shipping_address.get( + 'StateOrRegion', {}).get('value', False) + state = state_obj.search([ + ('country_id', '=', country.id), '|', + ('code', '=', state_code), + ('name', '=', state_code)], + limit=1) + if not state and country and state_code: + state = state_obj.create({ + 'country_id': country.id, + 'name': state_code, + 'code': state_code + }) + street = shipping_address.get('AddressLine1', {}).get('value', False) + street2 = shipping_address.get('AddressLine2', {}).get('value', False) + postalcode = shipping_address.get('PostalCode', {}).get('value', False) + deliv_name = shipping_address.get('Name', {}).get('value', False) + phone = shipping_address.get('Phone', {}).get('value', False) + city = shipping_address.get('City', {}).get('value', False) + email = order.get('BuyerEmail', {}).get('value', False) + invoice_name = order.get('BuyerName', {}).get('value', False) + domain = [] + street and domain.append(('street', '=', street)) + street2 and domain.append(('street2', '=', street2)) + email and domain.append(('email', '=', email)) + phone and domain.append(('phone', '=', phone)) + city and domain.append(('city', '=', city)) + postalcode and domain.append(('zip', '=', postalcode)) + state and domain.append(('state_id', '=', state.id)) + country and domain.append(('country_id', '=', country.id)) + deliv_name and domain.append(('name', '=', deliv_name)) + domain.append(('type', '=', 'delivery')) + delivery_vals = { + 'name': deliv_name, + 'is_company': False, + 'customer': True, + 'street': street, + 'street2': street2, + 'city': city, + 'country_id': country.id, + 'type': 'delivery', + 'phone': phone, + 'zip': postalcode, + 'state_id': state.id, + 'email': email, + 'lang': lang.code, + 'company_id': self.company_id.id + } + delivery_partner = partner_obj.search(domain, limit=1) + if not delivery_partner: + delivery_partner = partner_obj.create(delivery_vals) + domain.remove(('name', '=', deliv_name)) + domain.append(('name', '=', invoice_name)) + domain.remove(('type', '=', 'delivery')) + domain.append(('type', '=', 'invoice')) + invoice_partner = partner_obj.search(domain, limit=1) + if not invoice_partner: + if email: + invoice_partner = partner_obj.search([ + ('email', '=', email), + ('type', '=', 'invoice')], + limit=1) + if phone and not invoice_partner: + invoice_partner = partner_obj.search([ + ('phone', '=', phone), + ('type', '=', 'invoice')], + limit=1) + if not invoice_partner: + invoice_partner_vals = { + 'name': invoice_name, + 'is_company': False, + 'customer': True, + 'street': street, + 'street2': street2, + 'city': city, + 'country_id': country.id, + 'type': 'invoice', + 'phone': phone, + 'zip': postalcode, + 'state_id': state.id, + 'email': email, + 'lang': lang.code, + 'company_id': self.env.user.company_id.id + } + invoice_partner = partner_obj.create(invoice_partner_vals) + delivery_partner.parent_id = invoice_partner.id + return invoice_partner, delivery_partner + + def _create_sale_order_lines(self, amazon_order_ref, marketplace, + mws_obj): + product_obj = self.env['product.product'] + shipment_product_id = product_obj.search( + [('default_code', '=', 'SHIP AMAZON')], limit=1) + gift_product_id = product_obj.search( + [('default_code', '=', 'GIFT AMAZON')], limit=1) + not_found_product_id = product_obj.search( + [('default_code', '=', 'Amazon Not Found')], limit=1) + has_next = True + next_token = None + while has_next: + time.sleep(1) + order_items_data = mws_obj.list_order_items( + amazon_order_id=amazon_order_ref, + next_token=next_token, + ) + order_line_vals = [] + order_items_parsed = order_items_data.parsed + order_items = order_items_parsed.get('OrderItems').get('OrderItem') + lines = [] + if isinstance(order_items, dict): + lines.append(order_items) + elif isinstance(order_items, list): + lines += order_items + for item in lines: + sku = item.get('SellerSKU').get('value') + product = self.get_product(sku) + if not product: + product = not_found_product_id + # Order Lines + order_line_vals = self.get_item_values( + item, product, order_line_vals, marketplace) + shipping = item.get('ShippingPrice') + gift = item.get('GiftWrapPrice') + if shipping: + order_line_vals = self.get_shipping_values( + item, shipment_product_id, order_line_vals, + marketplace) + if gift: + order_line_vals = self.get_gift_values( + item, gift_product_id, order_line_vals, + marketplace) + next_token = order_items_parsed.get('NextToken', {}).get('value') + has_next = bool(next_token) + return order_line_vals + + def get_product(self, sku): + return self.env['product.product'].search([('default_code', '=', sku)], + limit=1) + + def get_item_values(self, item, product, order_line_vals, marketplace): + quantity = float(item.get('QuantityOrdered').get('value')) + item_price = float(item.get('ItemPrice').get('Amount').get('value')) + description = item.get('Title').get('value') + fiscal_position = marketplace.fiscal_position_id + product_tax = product.taxes_id.filtered( + lambda x: x.company_id.id == self.company_id.id) + tax = fiscal_position.map_tax(product_tax) + tax_reduce = tax.amount / 100 + 1 + item_price = item_price / tax_reduce + promotion_discount = float( + item.get('PromotionDiscount').get('Amount').get('value')) + if promotion_discount: + promotion_discount = promotion_discount / tax_reduce + amazon_order_item_id = item.get('OrderItemId').get('value') + item_vals = { + 'product_id': product.id, + 'product_uom_qty': quantity, + 'name': description, + 'tax_id': [(6, 0, tax.ids)], + 'price_unit': item_price, + 'discount': (promotion_discount / item_price) * 100, + 'amazon_order_item_id': amazon_order_item_id, + } + order_line_vals.append(item_vals) + return order_line_vals + + def get_shipping_values(self, item, shipment_product_id, + order_line_vals, marketplace): + fiscal_position = marketplace.fiscal_position_id + product_tax = shipment_product_id.taxes_id.filtered( + lambda x: x.company_id.id == self.company_id.id) + tax = fiscal_position.map_tax(product_tax) + tax_reduce = tax.amount / 100 + 1 + shipping_price = float( + item.get('ShippingPrice').get('Amount').get('value')) + shipping_price = shipping_price / tax_reduce + shipping_discount = float( + item.get('ShippingDiscount').get('Amount').get('value')) + if shipping_discount: + shipping_discount = shipping_discount / tax_reduce + item_shipping_vals = { + 'product_id': shipment_product_id.id, + 'product_uom_qty': 1, + 'tax_id': [(6, 0, tax.ids)], + 'price_unit': shipping_price, + 'discount': (shipping_discount / shipping_price) * 100, + } + order_line_vals.append(item_shipping_vals) + return order_line_vals + + def get_gift_values(self, item, gift_product_id, + order_line_vals, marketplace): + fiscal_position = marketplace.fiscal_position_id + product_tax = gift_product_id.taxes_id.filtered( + lambda x: x.company_id.id == self.company_id.id) + tax = fiscal_position.map_tax(product_tax) + tax_reduce = tax.amount / 100 + 1 + gift_wrap_price = float( + item.get('GiftWrapPrice').get('Amount').get('value')) + gift_wrap_price = gift_wrap_price / tax_reduce + item_gift_vals = { + 'product_id': gift_product_id.id, + 'product_uom_qty': 1, + 'tax_id': [(6, 0, tax.ids)], + 'price_unit': gift_wrap_price, + } + order_line_vals.append(item_gift_vals) + return order_line_vals diff --git a/amazon_integration/models/res_config_settings.py b/amazon_integration/models/res_config_settings.py new file mode 100644 index 00000000..4051ef18 --- /dev/null +++ b/amazon_integration/models/res_config_settings.py @@ -0,0 +1,28 @@ +from odoo import api, fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + amazon_user_id = fields.Many2one( + comodel_name='res.users', + string='Commercial') + + def set_values(self): + super(ResConfigSettings, self).set_values() + IrDefault = self.env['ir.default'].sudo() + IrDefault.set('res.config.settings', 'amazon_user_id', + self.amazon_user_id.id) + return True + + @api.model + def get_values(self): + res = super(ResConfigSettings, self).get_values() + IrDefault = self.env['ir.default'].sudo() + res.update( + { + 'amazon_user_id': IrDefault.get( + 'res.config.settings', 'amazon_user_id'), + } + ) + return res diff --git a/amazon_integration/models/sale_order.py b/amazon_integration/models/sale_order.py new file mode 100644 index 00000000..fb406626 --- /dev/null +++ b/amazon_integration/models/sale_order.py @@ -0,0 +1,24 @@ +from odoo import models, fields + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + amazon_reference = fields.Char( + string='Amazon Reference') + + amazon_fulfillment = fields.Selection( + [('fbm', 'FBM'), + ('fba', 'FBA')], + string='Amazon Fulfillment') + + amazon_marketplace_id = fields.Many2one( + comodel_name='amazon.marketplace', + string='Amazon Marketplace') + + +class SaleOrderLine(models.Model): + _inherit = 'sale.order.line' + + amazon_order_item_id = fields.Char( + string='Amazon Order Item Id') diff --git a/amazon_integration/readme/CONTRIBUTORS.rst b/amazon_integration/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..afcd98d8 --- /dev/null +++ b/amazon_integration/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Domatix `_: + + * Nacho Serra diff --git a/amazon_integration/readme/DESCRIPTION.rst b/amazon_integration/readme/DESCRIPTION.rst new file mode 100644 index 00000000..2f10d5eb --- /dev/null +++ b/amazon_integration/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module adds functionality to import FBA/FBM orders from Amazon in Odoo. diff --git a/amazon_integration/readme/USAGE.rst b/amazon_integration/readme/USAGE.rst new file mode 100644 index 00000000..00869bf6 --- /dev/null +++ b/amazon_integration/readme/USAGE.rst @@ -0,0 +1,6 @@ +#. Go to *Amazon* > Settings > Seller > Create and configure your credentials. +#. Click the button 'Import Marketplaces'. +#. Click the button 'Import orders' to import orders from every marketplace. +#. You can go to Amazon > Dashboard to see all your marketplaces and import orders from each one of them. +#. From Amazon > Settings > Marketplaces you can change their settings. +#. There is also a cron that will import orders every hour. diff --git a/amazon_integration/security/ir.model.access.csv b/amazon_integration/security/ir.model.access.csv new file mode 100644 index 00000000..b219d9da --- /dev/null +++ b/amazon_integration/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_amazon_seller,access_amazon_seller,model_amazon_seller,base.group_user,1,1,1,1 +access_amazon_marketplace,access_amazon_marketplace,model_amazon_marketplace,base.group_user,1,1,1,1 diff --git a/amazon_integration/static/description/icon.png b/amazon_integration/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..abaf2c5ec4f25fc2b7a1966b949d8672d35d2b77 GIT binary patch literal 43665 zcmdqJRa{kT)Hgcm4i%IXP*kKrN;(8Y0R;tAT0l~|bI}M0h|-cOog&>Ks7NUx(%mK9 zXUzS6-^IB*=i)mT$BjQXu-05pjAx90j5%LDR8=G+rXxlWgiPt~9d!i3hX2Jz2=U>c zZP&g-_y_;_eZ@P-8TwyZUDjLp36bsHrw#~0VTk_4%9hG9haVC+Dyhg5jNzRlAZDMa z*Uv`~W<=?Z%wyNTE2A#1RQ+QF8|y!FMdl-d-@PQWR^>&*2L{&LdRvGS1FI#3UqYI##~9xwdsWS-)kdzS^(ivIJ1dT6b#9 z{rJ4X*@%Y~&Du0LcnJ&3mym?SzsX>N3HkN=_nVlQr~l3}*sid#(KIzRT_b|`5VE9D zU|$TQJvhMo*4^!&X@2eO;>C+W+1X~2SZUeWgg0+qGAtcpRyu!ta&nH2E+{IB^6(-I zH0qw_!-p6St-?ktZodpRUK-Mnh{E8sw6uQ&m@i)hbgH7sR$G&60afmmU%k!L5xLgtKsQkqr$!rIbJS=1mzTEv=Gb9Qt~D ztwQ6g5)zELxmN@PsCs*Mte@C57$SF7RAe+YFFJ}!EDaV#Ha1F&X24|bQX7`U+f6p( z{jm}X2n@V>{rcQ47BgJ<>C*&Cc_KSIJ6^iij;us5e0GIcllLNTaOKq~VY&+o?t>>a zuB&HM)YOwdVyr?kLJoJ9A5A`hnLbu?ue-dnER11Q`qtSgFC%l>i6d=cK@59gY+NwB zdzlqJImCs8kWe~V)G3XPSY2HmDQ+OZ+>hgbsG}2(!5~W;is*$d7#dDyt9`&{ASZy= z6j30bIj`Qjb-}&v)TWydUO=f{)}Qm}5`5h4+gb({!>6Rk(9n=UcvE*b)AhHnBB;=p zyry}rfQu`lxNTx$B8G#>H0MnUD-^mA@JsCqj3YOFV}qBs&7dScJ(vB?V6Hdpwn%*D z-Zk`hSAEWqg&lXQOPA!-j6*JlIcPLYOc;oYqAMq;`9XnAKt;~b@Z6o!A<{OQ{!?_B zEVx-&X~Oy9JLM@02A(6B)Kn%$S_qntbhi>bSwgRbhJ~^GU3Fe?6uldLM==O?EN5=p z9S3H3M?-@p^zr@$c(Dt%l6@Bz8-E*fC^q9c_`wW0Gocm^!ia|aOvKI8`=@uXF!0_g z95sX)M#F}{H!K0z2pZM@$G@RM(6yKSZv-s=$G;&);IjzR5oz>8|BruzhoB4j@V`|h z{6GH9|3@44e+!KN#~YS=rHw{FVOY z@trT&Lb2u5-V-Qg`Lik!Qcx(a{w-6>Qe_md9-(53))tk#eTlHMT(CD>6V2MoAKQ+WMu*b7aw1i zD$nO+KY|EJ%#_j4`1t9Q;b^tfpGv!{(b3Uq=5)9+m22~wWx1A?T8WwIGXD4r!xcPJ z)6>1hhH@bpPjW6LS~7KH?SX}KIxAgJ!^6LGdNU^>6n?SeP(YMzu zzi)c7Iy3jY3?=(&d{u;&sw(;J+GrRK0lC51>4}KbQlHb&eDw{p#Gs80+b=fbml;JJ zrGv>Cdx{NP?wydvIGshC(0c5xeXVv{w%wSJfu)vHd$+u%pTU*^^A8CNlUpCFtDB;m z^gg{T?uuD-6#Zh>`}x`RJ4u~EQm6YkKF6B`r^JFfnv)~#_a=;?M_{B_Oh?-!!Q#YL0*7*WPVp_ifi`>qR)72W>Y71m$7 zrOv{+w9A>Lq?kmL$swm_nm_$50KxP$R;|KXSNwRRWnsKQYHDg~uYHVtGDC=fJpRXNmFZ!oQcx0IW&eU@|O%bufCL$vGQ|~3_ygo+u zH1@vahnhhSqx_i~BB(oiYoon&9xmGpy*P%3hSX!{_h#etrCYRW{?2E8`7J2L}hAB#UT`2;p-F3w3)lRg%=}<|3s|8+jUz{a(`xPyLAD zxHj9^8IiD@GHEL^vA!O8S;BoHJ@~S$r>AGk%M%k)5xXly&NT(@1ek8gBT^2{d}(iQ z$rb0LmzMkD)`a1FP~z^$%NtI$z6yzq+}of3@~nV{-Q#GtHS6^)BUKJ+4yTMO zqV9)KjcSq**$0K!|MvH8*^G&M?v1*@=?rd}oUni3&|iIWa?)GvWT^}$+huGc)tf zoIZ|6zwPY<$yZwXUevI=*8*c}j<%MI8Zsd8A>uqfr8L~UdDC?+!F1!>)yRqc&1p7n z?p;^gx?R`GXPWf~bM%hO17t};Fa1WX_ZE(>U%SR~;|4)A>&dE}j>f)WxZ!xc*JTe+ zfRV-4qoQ9d2g#Ydw$BynR6(At9R016+OiX}2=UndQR!_|Lc&v)`Qt=EOTfoJyv{y9 zD|k}xd7x6!U^&Q*CIJF+1~!-3*}q1g%;~sws{6#wZp!UY}FX$hyH#_v7yMd-~*gaj~&gPBwHV z3X(j^RG!qs+1c6o`sS)4@AK9W^>H)jl|R1ea>38H<~m1`w0GPksN|a-J&*{bklasG z?@FMMI;OsZkFC-vXr<_3I^;Y z8tRitE^!;cVU34#kgu87&U6ckg1)}~@xKlpG)G9D9XmuaNtF(*>{hKU6`yE9wz`_) zzLXQ4D7Nm=hHjqsv1??oF)>n6;(1_C${<2{w71@{cx&PZ6d^;QBtFwFhT6?G`pY@j zHgfTf`#sj{g0J0=b#xiI2mrJ5@o6mntg1%>M~aA z_NU4rt9{G}@B@vQGpD`1eQo_#601`2kQI%Tw`YQ4V$^3hI8?llN{VjZa1>?a)~Upt zyQ-ig+}e|*k}6pzn>0&?j{^tUPv83>5L;TF`V?l`7R#lb+gGWq6ur^G(_jFX*Q<#% zYLDPrG}L(`d9wXG`jrSWPYF>n$IQWzr~b_4j#?`mk<~XBli+2Bf4`Vp@7yg6kH!4_ zsVshWy!H5=2PQYy^<-zT#BN%ls3xmQw1fPzIL!^!_Zv&o`>Pe>&!Hewdv^oLLtka{ zH#HO+QM4S$Z#q8M%A47eQ;Oz&`Bwl~uE%KoOQ?}>2J_#^-jtF$t4{aLQcZ4#lEASl z23z7>lkAbzI5qWLIa##qo;Y!}+Dluwxa-ksMNaFSRd0s;lal9wS_HCBWBJe+cP4gH zw6I_wb6@7#KRD3%aU{k-&Z%47ca>50CZZD)8yf_9`tcBL07DEojFD7{d zGkNc)4@&)@!o`Z?)@|OHY^k$9lRRAbaBn<#-214Y`H*AO4of=Lq;~t)eGTuF7fR7l z@$n0S$+=KEpo*1S4XNkgy=7H;QtfyXt?!SrRNdsi)wph6=}M94FwsWOG5{p~YlrzG zp+i<}fE#p7EJVlj(%rT?h4X&?vs->AButT*X_rUK-``T1GJw!2DBUBLXOO`+HaBIgtT;0=GAPfV_d7oJ{Fs$B4M?*13Foy( zhFez%u~k#VUpdToRn-;BY3S?7Q{sLB;G|O!4LG(XS0k^oQ1d%YjkOBt;Jd-koca|L zWRV8qUWblWe~Q!9i!=tU!r{$3p+|A5SuKzkHYbCb)R75uh|Ifp@1lqxF0A!M=_HC_ zpqTXnFzU-zo6Z!hP)QOpJoq;&;=Dpr@m84)fyy#qHF;|KcsXh9I#JoYwJT~!UXc; z$i*9cbg%cfe?RCg(5@KPBNVjgLks4{Mhk_}QeTcv@FMUd1_^g6K=A3&109xbN=iy* zu*Ow-KL2Kv7{r{zJ394ZO-Sj5NQ)Xy-E*#snvd5@{H?HwtoJ&aDrvtwE%Y`6)_ATn z$)+mgu{kat-XtK6HngC^P$EZK@nkR{S6#L*(Byd0_5Rhy#s+_bbCVz5$g^r1BeTIm z#<{NKF!(9Gb*X&VMKrym(1qy2brhFaH&hfA@zfu!iHXCB&DJW?`=pyX_Bmv*Y_JW$ zG#j!JosjSfl3#!3WWBSojc`0TTtH!AXQ9BqTuby8(H%v+nlO=#Tb$D;gTqu$;C>3YKNh z`0QuyR=Dd|01}i7Ca;@aGB+VpxWug^?T=4Zdw9C}gQI8yDvQpM{vAcdI1kDH5+1M_ z>tI=x-#q}aIiD1#{VY0JDedNkOT8C&`?YH6a&oxidU`N_j)7rCW4tDV4OmP&l)cwL zaace)1YnYzn~|1=z-qPBx^3A4WGPH`kXLK1a+pUWG3?dEq}c$g1zX$OBM zBz{4`{ydz<&n6wkP>KtMU1cays0aKyW_c&o`|xHQFQ6^|?{9C!EtdjTpZtC!wY4wj z(P*KL36LRB1Zae;;;2SA^Yhq@`Mkio~A-L>{FnMlZq2RJGnNXMO3%yF{0u!}mX7uBfV#Kz7!wTr{jNgZ#<q zpx|!x=Oa{C0wzyP1r){dOOGK%dLM5pZm$fz9eyYxLka50leLYdHE%*cjA2WV-R*fg zVe9bXVqWf+2fDv;Jn}BwP=)xGoOrgcU7(3Z-r4cIRL9QYXpPG>z<2B5M{P8T!Zs0b zYT`WT>)dzPwaxeN_EwZ0AJA4E!TX7fDQ|Y zYozc5IBJr%$|t3_*GGO$bq;(kgliAO0bCd?N*$i}V+*bHJm8Nz;CD5H5|YsH0Y=2a#uj3UZ0yov z<=sKhA_s%T5=rs}6#|6#Y3=(SC8Tr$A;Xe^0RgriZ7YcmW7^G{fPgm}aVXv$l%a|U z@X^W}2cSfd((-@&S@g0e4Qs7>ncG@$^xwrPpp!g){{HD~_r4!!$2wd>Kvse?Ph#CJ z$ju#be>sGi5NfEN+xU~u#zb(a+jdIcK?Z&CGhS_NBlYdu7Lx)pt*jBqoz*7^m)&O0 zakHRl1JYQGe)g*?DS%)3gE>*^GJbZ#RN+y=*`ep4-;luGOCU`pFMhOAYSx>9N6sLE zSy{0%HZcLFK@Z6Rbo4-GLXi4_$wq&SmI})t)X+FbMb&z8@b0^@tf680urSS_N+10k zHfUyOC8>&3gtf7oY9+Gn9#gsgsA`V@ao<~e?X)~#XP&@jgP4t03tr^W3x7FW&T{P< zo>rj_>JRYWx`i?@;9b!UyG8Sb%!FV(G`_p}sIt6p!yOlC+xtd!3T-JlswiphrAEUy}x{z1k zV`sfN`Q5k8ekKZr4cEIKDJN)TUPx;)koNQxhcj#A$_JVq3jjOd($~)F01xu>^MlXv z>R@Z$fycn#&(HSYpNaLfYn_aa&U-zwih{%vh- zj(M!xG2&(9vO|WL9(Yd>&c`6>NkbmovWm%PBZejIT-|b78=;jtJ1!kQib+k41g$0Z z%O6dFy#CPn6pzAVybRS~w3c?<`w3CjJ>EUB;>(@+?7 zZUn==p!{N#{9G^v)118*E&+i`l0 zmY?eSSe9XJh9*V|kA&mNNLyLu58v>H4Fd{wb^}5#5dM>am-Hr{ z@v?{dp$TK=+Z$_}Wq`2|RI{J;VKsE5Oi`@)hRBb30swxD`i6O;=30X2*)zk5sy_^P z7>gfezcih0tFbD{-n|<#Je&h=QpMi@vFbv*v zw@kJKSE)uk8WOVlgGu!{O|VqduhWZ!G!!{}*AKSNj^qtGPwkI@CIB{6et8Ji5re2> zwhjktwa54*-yuk`EoK7M60a!mFzk&MWmiB@#lyp6V`rDu)4Pnin2Cv@U%q^arhlQQ zH|Eq*dPj}(DNU9r9&-7D;YPJ#XvQ~_MN_>%zluN!4UPLjll?9t#;V^ zH`@_qa!}0@B$^zdjio*$T-De2SRABm9TFc6joz#WOod^Npe10mkqJB95r78ZenJX+ zIEmG0%x`y_8;~Kszi$VpHx*JF&e`#&)RY25+1DQwBhj%!qTo&HM48Ej=Y)Q?qZHk= z8MQIYggVw4wU=L4YVPK(T{3)%s&_Rm>uqbJHFh8@$9K*}Zw*?M#peHXS$*I{UtrG# z;0vuoWK)n`0K&M=C%aUxSwc>W(`1#QtQ0RgvrN}Y{PgL5O#vWyVyR28q7~f_8U6V1 z5D`;^6Y?CO>=OIgd#u;5>j_W(c%A68_Slcv_TX4NHrQ#kJK3IPEF^=icz6|MFK{{o zp_Btwq>W}Bwf#Q5)TdPP<#ey%%J-|g$xJ+V78WVcWW_F)+ zB(3RFAwMQTheYM+a+~o8e*y|wH7XiX{G#}m-AS93i<{3VLk96?a_~aMKNS~KYL{Cz z0rPni6@^L=3p?ck? zha30?#E6gG;kJ40zaJbTE^7=c&K^qh1!7e%^m_xji>UWqNB`vABf)TX#7lSxp>zO* z*64KiT1$_9U(ODw%%l|q*9YCs0|*1=U^}j#g4Osa(D(hN-~YQ8fN^~`n#27be2|MR zf(Eu}s#lOnM{JWZe+<>-{+Ia<8WS(^3M&YZu&;iQ{3i=4#$+`$HI-DtyGD~dmJ2HG z4IqX^s>ab=!0JSo|p`&Wp{J=<)p=h-596u{mN}?j)jLO z(&D~e<8b0g-N8BVnA!C_H|1A`DJGkl`p<&62?gk9+2Z*4IMW#fio`SD2}VTx+-J86q%!F71q-Z++{#KCxgb)R zXU`JbEl(0Nb@!&LH)xCi>EvkM!io+pG3&j8irbf^TxgAa#9VZNJ!w`^WBHsOm|Bh3 zCokKTJ}cOtOR|AF>DHbaM}@EVHJE?5@c`Nr?d_2l7z5UY$G2R6r+q z2$l<&X3a1*$T#SYgH6VU8>N17Wce05F?e1HB`_GAV2yxgfXV8aYfsM)oNz6&rH|?y2|T;tlJ? zA!B~Sq0c60QP&>MK&0=Xe}Bj5`cbl&YPed^sF{FmthJe63OA@4epvSVCM{n;B zv|v>4-$XY41A7wpXpI(rXHonuf7xNu;M%>elA8*fVNX&71Z`v>n}?Hg`>%r*$d3ne zNjf;?xw$mruDtkUbdSwb^HALCrv>XeIDNH)zk>Ssv4%XzX1d2z$VeOKZ>}&?$kzexVx%dNbVyXot(T{wxxyo2O=K3oP(AeSFT|5 z)NaUr@-D1ds}9pne+gP0K2kFp0kxHTSe*(lSu7i6{H?0e zcUjWUK+2CxSO$d~JnzVE40!XJ1sRBF7 z?HwGd#{5CnsPM)M%}4|E;MkIeOwmLdX9$Xn@I!gQ}zYss!w2KHa;)0 zy=nGZ;VK}#Z!gCIV%HYpF$)S(qaaAMzlgJAf3V>+5SVN6FRAfSm+{Vmft2LrPC;bD z3JV}9=w6xh($o|E9}sAUad#JuqtDJ@8%a5-vDU2pB`(cjs-Xy?>eOzf68OahO_xO- zL+;CP5MoyZT95ghc>&C@P2PYlrUJ^^3^4h=rmjGOGN_=?$)yNlVqoV2Ej>LbShn2V ze|hxl!$AwTPF{sRnm0*F%g$`Z;prNAnqT-i@Q^)7Iu6V68Rm3Xu3V{H9bWvM1z{;e zX&{ueXq6wth16OMMYGy@oa#d-7Vsv07X8G4MVycRfVd6L%lwJ8)@k8<=u5QU>QLgMm21*QZOsd!SzlS+=h);dTEm&J6{(b*hqI?sZd5T`V%mM# zT98eR$_|WGQTn`u+FJ2Kj=@cL?^=g>)xyXkU_TwBexKNg!AvN)mzuEgw;jjV*O!fx zv-N@0NdRygasV!E;4N+bwJe$hZO6I-*&q}JZUa`w z5E`O?UuA^A>T?f^!faLFi!`k|+=~u?@b4XZ(z#((_e%G-jP=SAfX?{*7R`J+)g7 zzy+nX+=hZzuK3L%X-MPxl^OZ0-z;N>K!7yJCTa0l$WYn>nyqNB_69>o#9@wf z@T(FsUz`sP*>BpXuQznC2S90okFc(|;`;ouCwSEwl&eFf1b~_~toga1GiG@?EIgd_ z_-OpB4TFXAqc4=tdF2UrauNu2rzb~mQd0ERUh34ko&)WB+F6QT(o;ltp9-`hRkp0f)nYKH@E-mK95~e+(Z#xFPu>b zofQ5$YtU6R+$-am385MB>Qx*-NKMcfbZ@5`w(5$IQ0#pU=@&1q3t5jmSsN@u6+2vM zkdhuq>`--v-^0Q%`S|!0mQjOn+d?7r?q~-x+Ow)ur`WmciShAwS<>iUMMTUE1cNtW zHBxyF`1-8-3EDIQsQa}?N6dY&8I&5?xKdhJIm8G-Qv$?U-dB_$?#3VY6}9l7Oo2i$ z%ipjIA&TlXak4caFVft$XVu+?6&Of!m1F|j3bj1o$mq`vlGE}B3_nar+5|(}=j=!y z)#tl@TBLcO9O{^cJ*L8gFyP)=Mp-b3QErZN_hcxeVqyY85RE-7A?Q{+AET1>dlC-n zr$UtqoAH#6pAq1sTa-Nq&|>1A4}ts&{7PG~8*4S|lH45m=ZTSPKuzIPSCOCl2cHUW zEwPuZ78GFieur^C zKkVA0wHnknjZ@Y8wArtvZwSpipAJWtgks8>2|ro0kV2CR{HSVV_>LM_z84iD7+!t+ z_;L93G=fo#*Q|%xy5-(ArRKAf@iUFE0S013FB4TZwd$Uu{gf0akO6bA1dbg2sh+y} z`L;-=NW1B_N#Ntu>iadQDuT8tBq!^+`tyWAYZNr46k-hsnzn)?QVf%#7pfYz68f1c z#RPS=6`ChB((6`ejaq#%H_8AVD2fvpA-0}~4i z3v^(#0SE>JPWqvjP>qU1d}zs06derk{5z1o7dQ)=L3S#6(MeaxsHkhyXxf<=__Xu| z+8TDPvk3Jz!5lIWpiBR~$X@$OmrDLgfu{J@&s!+mUcjxy`_LOgd+UV(YWqAh1K}U6 zO29DBK4(0)wdDn2)Sz?-dJWPCmy43fhekcjz=z(1{)OLhN?b^aT8;BdFaY0Max|6+ ztHTHZD}W3Rf0+6B&Lw67jnc4q8w=f}fSXlJ&8USz$LCJ2vu<^gYXA@kW|Tin1Z~~* z_V$kXTcbyb`yR~Q$DO?{)nKNjx&mvc8XJdkeK*DiBgU6WN=gbCXQ6M80q?}g-gp+z z8*Gee-TqYAWnHcZl(=`JAM>wcgdLU7F`8D z!#uD<-F>ZU{^17&vd9s+J8IkCPLzKOY_E;dqs?w!zEp_#GDN$=?@X0CcP6*%t}4Ho zL$9dhs*yqKQ5rZ-dNn?w8SlbP=f6(crU8^OgHEz!Bs>hd|yr#3TS z0Dpz_(Dw3+U%$my)Br=(b3hnH#oYiGjGqRLS_k)AK=YpOkd=a(TCdX?6d;J1pw1W2 z-?ot`>++}A&~>L@tFFF3fG-GG%Jc8h*Qo#UCAuoaBm`N4GzBZiQ(0)#)dKY#?Hk)( z9;A?P-?q&gO5sBT5%4c1ik3=$cf8xHB_Sbc+3J>x6dw01Z4R1_nbWZxtGz9Gx^Dz5 z>^XcG>=)BWbvfiQ@ag!V>O`&|l|@QyyGvwz_yCPjS3$&J2Am0&F&H-uYg^wwlLASC zL;#1H8PYN2=&zg8?S>V@>1@z@eUk`}+AGyb1_;7&jK6{w6*?1RPm+WA??*1HU|Wme3Q#0_H1b>-ILPV8p~|%vs+5EdY^+wuM}c zED-pwfe>2Tb#xe>m0P`nrG?sY5gNjv6W`%T0($p>{)Yopoq#fk0wgHuet?V6_L;@U zIfMV1&r@ZCdT0`-0BODGwhy(u4Ct4V2QwEU_spS1**Y6CRlJxBH!8s2OTKdlvUC_v zeIwvmuhH>6*eSH(259XM$Cig0)ZnSKL-hdvO3~CrP|#sc`Ms3SWzb9WzIcH>2z0gu zB-bL#*D%DEsjp#nXD54cRTD&{q^(`0bM8E&5kUp}az!RPyiP6|kz zy}243UjRO09IQP+umS??2@N8Dz@k$M^S?n$ieC%TAN1Tqn^2XOxTrnZo_4J(pN48~ z0=ux&Bj^i+769~UPO?b<7C-@Eo@T+J_T>6M@U_w)Q+@I-|3-thaiZJEewt9kTrLxO9nfwsunb2w)b0S=LA{Hmi=5Ecf9{+wSi~`T8x3mr!B2sz4q_+@ z@q)@#sFY~-dM1T8=+*iuF4W%D*8t_fDixtMFo_kHtaNpWKyP+HvQ;kpu#0B7>WFjd8f$vV51NkE_I6GKe;?%g_?& zF5U9Xqt7Wj`*QBn3>{F;eTVC;xO=TBAhGjZL5Xh0;? z{O4b3wLeMmy6(EocLBF)`BF{puRLLJIG;l~i{~@K2g;5W+yY;dnugitbYQGNo6qt< z!RFy|kr9j&x{Nt~JEOh8u8FQ~b{P?sL$wI+yXUblZU{5H#wg4-KTcZwRQMZ@{fD2gaYYHe@V$~k%fuCV0M$}I-ynFH>p0Blu!R}bwc1>uzs&=X3>yb6zZ z#GFJJ;8PpHs|^8((h%Sab$QSo=s0eoaacZt&fJl;ERfhjUcK^dnPeM0trRU#xO0d3 z`t`QFZbN8O!corpoh~01tKn|m1rho&Gjj@#Q4?r5gkfK?>+~p;qOA{qM)B=d@D#$? zqTw|_K!^yV6SSyIW_Pf+-zf4qA%Qj%IKJ1fj)2A+}sol9&KIup|NEHycmv}9|(nRleclv zo0n=vHNCJK^}(Gc1-DGZ?H?=LS5%l}(9$n(frcgoZoTR&(7psc*===uW6LFdH83~0 zwF!`QjaIQ^F~+7qMvqb@KHPtlBBHZ%0S-SKt8T9U#l^{3d6+|71l(>kp^9he9|_42Bh$Xt87Sl zY$3Z*M8;CgZ9p72p-FE}42q`+^4){JVG~XQBLQDMw__ zACk5n)-7P7#Dd&cwAl#eu$KB?cp*Ir?B+JOg!n#eufpJlDPrU!_P4K5T4Xq-bFwCM z0UIxRoZ@jyc1JPBAE)JVnN+Yk#7W({6%7&;k>tp@)l{5(HXK>$mxqOLlh9Pt--ZvA z&(!d7ndU`TIoHK!$hu_-ZHRP_UQt?(st~+-{9$VpdvB5as2&UVA8 z5}S1~nLU>jvhgskqS1?K%bVmguis*AU6Zbz!y5;42R&=7%FV}EQBX*?*k1UGcefD_LSgeCV}JV3mqmZ!W?2Q zM7b{WMdy3Gy6j*|8ax&eeA$N*^O5?j6ZGUw75L0_%!C;ZG!y*;d?RMW4$e-VQjeMh zXgQY&`({AnJa*sl`e9#3NG*o#8$~Q@iRHS(s2*5rNBrg8%dV0x;f(JXW*G~qbLuT) zl*d;WE8pbGJWBgyMR146PoIlWrkDB`fwYniva=wJvEmvfVZ|YB8Iax}N?#9u>_2fb z{|xCXobBIK_B%bLU@oIse8002)QRUVO_{cqKz0z<`*5!dkBWm)Z0h6=V{3d0<%b$M z!k0RRjEK|A)PVZohWkti^TWvpx%1cV1~(2jut+#2UzZzy*~XP3M~pE>IJ*4o9dEAa zkKvefD`Iq%+asgsbv5}U-gA*F*QhuteJI0%NKvo)IMbrwa9jwIzHoC`c$)&c#()^Wk zuhEI?1uAhV$P$M6A1}YfG~T;}k4qHATI^?>9ehzv;tS35mf*Byk)a{hdv~cPpM8!q zVRX1S;4ZaLQ;S@~>;u-H$0#CU-c2TmWwWt9?r|L>_c*InBz0@!8)(dlkZu z$*0u2Z}XVHZU^)&7!tlINPb&HIrXyar1`NK?NQqG0tAxCT}h0qQv|8vIXIMZg9V8C zmf$&$+I0AuWU`i@_O(9n)DT&Ch!aA!(Wy1IWgQikxQ{qQP!ucs?@ z(+!&Hu172iqd0C`eZRrERcR0(+t>MB=PR1xcP4)TCJoUzUBsz-T+=9VjJ; zwe;pw&*w-n%dm6<7Z({2&sMAtaCf|k+i;hVg^YQ?2T^a?C)OSb ze4Ox{X(^$sr>hW)<1YR!{rYNwqQ|GR&VqP;e1z30>pHh?54_yHvM0c-Z7qrWuuNvq zncYhlidW9%R?%bwhAQfRvF5N~*vc|hOe8vSytvY~DGCq*@bzp-m2EgnE_)P9eHsfA zkZe!FJxy*_7X?EK4SWIGzq5C;Z+Jru$lH4F;8cI1RXeh!VYTXpY`)W_ZHg{D($i04 zJX|m53w*v(E-=VTqf45+;89P&WkT@If2)x{(ls-d`yRqt9Paf{-917y4F2z40Ccwe1z5d%%@2>PvrT>cqc^T2y|)A%)U?!x zjjFQJ=iUdoPZ3DZ<1|qcmROsHkX`nBvdn#`o@<|;>cwF3W8L7AkX-2;l6zv&{zzx_ z&Qkk&r!hxsCQkaYIIMH!%Ftx<^?ClG!z8MW=yT8g2}UgwP=K(xW;2GHvna*VUqkV4 zH=&1rS7()VA%{M7!gDI^CZ>gSj?FJ|o3ZbMK31DSh?*|5f{P1x-O_~>2JdT&iyr@S zqxJAgsgYgm;@YjAU(T{BL*!JMI*hql?WvJ5A_VtT0x7BRa!yL4md5o@+x$PSBcm#Z zjgUtS1X};DF4kP9LcTFJKE^o=p2O%$61tuFG^x8_<2Mky8Z`~EaxP(YVy!m6Fq;=b z-1P}h-vHvmmg$YMD7RBpVW3eN*D!f^Fu+j!v!#ch!gn?W@0Px^>W^tQ`|>ry=+ax+ zS!Tq{_oCJ=Q|OK`H@-f&@x+ks$?j%Sgn)tl=4vqIc{HYlWoLAGw{=N(w!0rXciKx< z;N@kzoNd`*J!%U51z)}$uXH^yKq_9=w$EW5DF$r zlbR#@@}h%$8)RH3KkZzM3nVGny6`!=a5*X$th%}-$YNbC=kF8as=1UoDQMN(9ayiv z$2TK}rDiGf!hW6{;aQ&dH#xG(x{VTnyeWDcBHljuf>TeKH$#X=YgJ><*bwrFqn>wP zo5T0CI%OuGjWM5>tg@0Zm-)8XrKRw$%kx3V{NuuO73RP;8N$e#s~*m`wyqV|mi83B z$L@ef^`%^OD?DtiQDt8{x$l6LoP=2~cE+JgVSaY$)?(`}C z<6sB!pk}J#W2)j>2Lm_Lrhhylkzvdy2TxD`;_406jTUuH-PjM3wGg6GUq0LVHf(mO z;&v7?Kznw2s^GJ*?v_yK0^t(XKwTPyK#EwmVwY^d`ms4Hy&024@#$Y;Ea|)_u1_p> zXsN+Z2^?NB_TTRVbB%3-aOxTy6h!NIa0h+JyfKo<29f<~a@WkUSn~G+qYVdD`;U8d zfA6u#P?B}|X@MDwty$ui!=LsS`MPOZFrtS0f(Ka%G}x6jU9gXDdiPwK8~<$>*3i zeWRPA&+i2-+ehpfVQ$h?UtX8C*pF%-SE<>rao9|4kidQ(^;d!nB3*X`B^;kP6tCTV z*(PlvNW8SUo|dAwYGv&rD5#}PDy&Kv-t}rYw)wLIt0E-OY5Xd|*oJ%<#BtrD>`b(j z>vp_JJI9J%#^l-(a~T6sj-8a5R&*MxH+gLNa`*gVfX=EhTbl&7Zdf}r?!fHds`c_W zTsnf8pJBI9nHz!ADVn`PaSUY#D%Wy zefKaKRu2IFoc`&Ua{iC8hrtfB4VGOpO~O<`l3`dzh?f>Rj9NnPb3NmGLQm{2ej!Op zPdT9G+$!GML{wI_>qxx%$rrp>+O{!N^b{r5gFjBX1ZS6s0}8$RkUAn*C~WU9G}OSX zLQMTIHY#^JnF6VVX`YR_nW2SpP1w|5x@_%+ZF|gdmx+%`dQTYxR>`6Pp@PpkjpR-3 zG?NvFa!Fo%nq!0g`8~>G%ici+IIL548RXB+j6x*Fd<)yfdb&=agm-t*E`DwnmQrg7T4mI6WbN2Kh>M1Tz0xhMpV30i~BkWypW z4sq<&zR0dqY_0jDER!d7@7TqX_D`-df87o219gjqOrnM|swUi*m-GpK<{xJK_6^g zCX}*tznmAJhmNxjBFxLMym3HZ*Lt0;} zkKYdDeS|e`dzWmQMbLe}yX5do#ueBO!W`QST$*DR_$s5p%K1vjt9b59ScBaCgV8F- z0ovTB#)sZtQ3FCu zUpCK21uv{2;uop}rN&T)0%N_XIG5SJ)Nc7a?LJi{#nrOhO(f0yLFw7T5+LkPGsf_| zQ_p}L>tQ)qMh&)(2KxlQq+ zp7cLOLo05StMXYysI8jb5BWOZI~UG>H5kzzxj(`ykMCb&G{4jB>>l}6gu8^SZDJz2R&|Qi znc?!8AD)lmJxbDVd+F8q{ha?B z>y0;;4L;J3NFui6+~hT)cI{Ei-D3C;D5STq4{BHSG8vHmG{X<~ExhfT%FH{?JlJq6 z5b@&h>YE8(C03ac+lsXi@n zC`-_NXZK|=;zOOYXKzpBxJ|`GNdjLb=WA>%^hrF8Ek7bCrYMHFM8?)JMJc~%`{=0= zE7b@lFFOV%rlqf+o7s#N;X4jwU^#_nA4G{K_8#{>LBs~sa5|Q8o+$@ zy28;T&`CosZ6cs@_Ajed6Zv8gYmtQoGf8$ZF=&>)dg>|(e% zDNb>o8H+e6S7-E_Z>)|hqZflm4gk!nD4@I7dgM!XJN{I5S$dAKr-^-+bSf4Ey z8Ios(pD`>n2@a+A(ZDaUF#KbqgXH>*I5?fREO%wkW4II#+0cg!5hL$5lu7`wBzD=Qnp|T+&!ZEQd3$!?O$Cmm>{})eh9T4^NeGe}oAzjkat(1~W zN(o3wOG`IMcS=cjrvlR5-5t_hO4mwDJ;VF+{XPGYyYre`=bm$CHXA`ujp4tTg6n9s z+^zHb=X1jTJ9=`$Sj>Xx2oFTmr-GZ3CZXcEy0Z&hek3dCq7;TG3e{V9yW_)L^f5j& zbdg&kggS~m2#82Vh@x-1($2p2uC}=_1j4S5XJ0rKHi9B-0pc_VqJKwyhY@XzNw0{q zj)Cs)JC1enU*wS#+>rUA8qh1IxUq#XI-#eLnvsB4GecY_BcM;E8s=MZ#xFQ6<+EOe?fCnu1Bzw7QX`8J(x;O*! zR(2GjCvD7@{w@28&VL)blg~aF-lIrSgT=oa?glsJD|RGi_ntGHKeY+C4hb9)L!4-E zaaH%8l^ZJ3x?%x=d}tL9xQq+l*THdTnn)axh-wgwGEM#~FzoQ7(V=k+26t*bgY5J@ zneX6DXNOJ#++N;ZlxY8{gbvS&!GEi5l*PR0J+U1Ll!x%%=k58N!=DcN$v1WX=V8Vl z6wtfy2o)d*9mbeQ6H);besC+@W$sVu4s2_WlN*lfMIBjkxcfjnUiLzisQ&!ogqREQ zQ?krXUrrWjY1YT3?@u$BK*ctWjPpSHB}Gahs?P|WRe1U%v*^_{EFtQSkR+SYzRWFz zYZqgvQ0Y-%4_uzEZ)6yf#XGHbjC&et{}1jK=>Oe~rKyZJlANmFH>Li4Gb`a}UU4o0 zA#nrmB!`f`)botB7%veH`aj3xcS6s@`GT8^d{>cM(_PlNro!td9Z;e7)&)c=?p zm=K$J+B>s}nSm^qF~I(KG73}VM(GnO@JW#O>l*|Z;B%4kg@_P7{j)OLtDcnpFX%%S zbK$+B@h$w($Jvml4-h>+%BsRWSq_rRp8@&Z|IFWEJQ#vRUhzQrztuyO9(y>0T6o_; zwqaqu=;)1Cm*;m$F3jyF!uukxR4EmrA4y<3vTW}C$GQ*-!Jp8GgSZo za#@E%eU)Q7xlW^gtRcw?&mjC4!Xf*f81VFcDO8r(jL{vwa!xvqAOG`{P0S>duVV26 z!WjD4M6+{>g22~vAifQ~Bh%p0IZA|=_r4rtdzHB^^P&u2|M%8tXFQZbJ;>W+!)YF%w6KkzJGzFK^^kxc&g^uh9S7 z+WdnR0BpLSu>~#F3sU^x2gYj!8?R# zWwn-Rvp<2fxFU4h_WqLX}JAi#9R+Tc5<4;VIt^eBG`(WaOnw zA@Rq4$EyGKnH^keIzD=92c-ihi7)sQ5;#i2=$i$cXxdaHVBV*1<5|vfVdkn(bbfL! zr2pK975^r*^Ym&`iIb8lP&?b~`8vGuuY>3p1S0=SxFW2y-a`CF;?J_jINwM7mxIBN z-0Vg5YtaA8mcH5=&v65&AlQ6=;J_wDK%&tkzcdKLdtziCgRZ~~(N|labu^-<`9}o% zKI02;XX4XB!VjK*-oXC(iv53!VASL=3A`Z{HGfJxaFE81k)aUZ4>$mVX)7`!`)2bB zl4YrAQclc@{O|X6-=&Z!C)Bah#B%#61EbLp<>0V;5O1jkI)a~e1Gqk6tiCYKXR!|| zSYVZ`ly9GjKp@q>x-0YA(D?oSLV#CGLI$20>Z;+3FOnqxZ=D*S{k?EVe}5Yjg(6~v z!}HP+=Q?h~OOW|S>FzkuyuefnqV=ddjjgZCU>vlQ$z=QVV-A(wRrAjW&FzYBnF@ai zhys+#&x+&*cy}uJ1lOFyIj)Hu!^&oIA-?Hf{(L7YS^a`2G*XSlqqN;nNBKhicW-*7 zke?Dr-ceY&ISwf9YweM;-rx2v-y7gX&ZiAt&rHD+ zSad@P-&ni-RMD0{Y6;Jn;t+^@y}od8Cg8pTCn9GlygEO<&LtaZJhovuv2o=h4>Mch z=$n8Zc3?dy{oEClg@f?@*}u~$S)5*nX(>Y{xb*weM?$I}8tan?@_vtgA+sW%xFh{K z!e^6A5@p&JR~)*wtKlTNT>1`Q3Xbdcy^QC_ndhQg z)(j4j(;<*M-HKxNkpOOXE-ncyif)@RlU^J{L{+{AY;? z**85Fdq21VJFY)UjDh{oYWLr)uqo&M>E?=Z3=SSjbI{eB3VzyUDD;_dn|*G6`cVCqc z`hDL>r;*-9;Uqr&>u;XAcL%p#)naz{J73yPrivP@1VULrPd~Bj3N9 z6(%In?}5sGhSS&!gwzg%BmND$+r52px1l@o9?KVd`HAUhSB@W6s_E` z+Rb%>W`q035_%|Sii0@v&E{wKBAmy2gTKK*)Van)Ns|1Li4P1_#fmni}9A&^n> zHM&M64dsvD-zyeqH977@foT&XqxkJ$_|PUqznsSYuoWqfw;W>qM0V0P=Zp_z-FJtK zheC@8vX3DqtImh=s62AAJyUak%>J!5)lp&wFCp947`}hgzZY*bG8)-4d?i06{&7EL zWIXiUNd>~p=zZ$mh|yRKDPdrJ(x`uwZu5z29IihVyS}Ly&wS|Z{F5QYk<(89<-QZQ z+#P)^{_HRJ9{sF)JAgdeSm?M8Ag}aQ^H9!N^?J9vQb~RE6)|UEA!8MvRio*Rp-_%_ zx9_B-t>BK?!`$#cN#D0%#Z@iTTW;R+_!e6K>>CUR{&SUKkdMx^{^nfy)AptiZ&WPO zsl2^(ztfiGl=|Wd(bdxkf#@9-xXMXmN;p=qaZ~J`URS>73|=tm$Vz%aLp7~%W}Wnc zAY^cm>Ut-0+g{HF1iE}2DIp?7D~r_J6h)e{q|VZMVbsdFR1{AVehwwaJQwGB=Xgf1 zwCj4TW4Y$>_c>J8y;buD-r?GJoytdj#*sgzsje@`<2DQ@+$5Gz!#BXn?e61U$Lq*< z-iM-etWjhJPzndk2{@Ex;YJysO;NIsuU2!2wq5tr5K__4|K_sh;o`$*TZ3Zc;|(M9 z{{w|Gz0Zo1lCO&*7HNBmJU2Xb`+?)0JWsa+%|$`NxrCUThXLsega#88ZTtKB-ocmF zzju$vWlRmc42v|Oez_y|s@|{ESTi>gtgrIY=r`NGeH4uSMr|M2a;;y|*p9Nw8?E)l zo}|si2~#|!SrAz|p05kR3%1|&E)a>Rwd}~mRD8Xl{)7LBUnS=9FMP-iNwaca(4zA$ zBHW#L|8{89h+l{Z#mHDV(NwKD=f3^cG~yxuuZYA|9QM9thY>OjeqnMf?bPGit5|vc z2G7svMX9%T-yMkj(-!5oJ3t`b?O($0BA$4$rNoc~m5CyQ->*2YgmOxKP8MGE)~CM< zUu~{}G6nCMwSr=O)X?-0}2M^-%DOR-BPp6u0HcSJ9a_>|@!SC`<0g6i^cAb+{k z<-@*~_>Gt#t&3PbHq5qgBDFZ4y!{~m+;2B%$Rn3_E3pglRr_0=Gs|wNt%PS&_HMf2 zT47lsvEd6KB^h_VEibOPlFMuqB3yed|3!9bFg=fw36Vm8zyDw<60X7g6TDiw21lOr zt^HUGNI*`*VH+n~_jLC3bckE(^?$kx2_;vY-@=Qu_045>_bqatV=f5_vCZ+B^{>2P z=x`xB>y&Ku9sZlEG&B8e`z4E`KYu^tAm__gYBVgp7&l!VWI|J^oE$@JDgGdpR!p1Z zRNt&s&b^k!5DVv^;2uK%zOC8ChiT4$`E^a4%mT5MQlbT}^KNJorLY z%v+s|ixYD4Awu}13@$*o1LQtcE{YBin6t#8?EB;GQj;0IgY3jJx4M|pl7qeGC~t|! zn(NZyh(kkRokjPaz(2&2OsV+?99L^s&g0p&dFZ@V(wdbZB4ejWc$oQq77!%A4Pk=U zTMxIS7K^7VN%fuCn=OAgE=6B?Rg;Yh&Yta)6xtkjm$F$0fEm5|VT0yChSh~{i-`|s zMMwO|M;ezVd_h+G*3?^hgr~nfZY%!i_q)wFgBVb_H>Mbhax5ls^?q!9-co%(4}LB$ z-S_51eZ7@DB5#rAD?H?HL~g)6w)v$KUA*gQ-W2M*;*?O?Nkw%I+W151UzNcRwULwA zcy`~tP_D{XQDxT#-0UB;+)Ff?n#jbs3yQ4!AvIS^6?VoEi*vfc&My4w~rXt7vVSAsEP=|P|>kj-f#X;bzUdFR( z4L(kZr-(Zn;_I1rDnij?p|1x)no~5LfmJ$THb-6RFYJGrCp%u~i{r?ybwR{>bmQSi zw$k-F#`=V0cTZ8L-xFcYAVY>#w({qK2F}`xrr|(gX%c#9rzKB-(4DLLW8QtBSqeVr zh`Q}D$%}V>@nqJs=J7`M>l`v%?g(tyXKr23Bennh3P7K=0Vy`hH?t+7UU28|z;7p` z;5|Q@cZ%5_!5fa0TIM>zcT){RUX(J6DPL8nXI_aVik4_pqjB!o=qaoUZ}x=MJLmjs za6y9eQbSHGWs;JOnmMxG$(!5w*?!oakFZLNI8TO~SibUAuJ*`A0SV)DX3O-kq_4?Z zs{3EF-lhi^%;@o*GE9`= zzx`;dCCvzMF6UqCZw|KKVOg56baJJ=71KvYP-6fqC3k>hR5*B9we@e!R#G`>#?XV1 zH=XmPhH_+S-n_W1Y>*YTjM|C#1xzT4KH%YB-lw~Q+?nFVNQZU8$D+=E`*rrUMI)m2FA5>v=Azv!P>nZLyHR5E>gU zHG6cKN|{}{7IeEdAKHmi&|iFdL+s@0xMEXMZgZA8_ULhPBq3o~-XGNq+HjAP<4!0v z5)=+Tabn<#@Fxi`Nv{e~XW%GJy=azZCL*?VSp-_em$u{C*`WL3md-r0bsH&&5-w1F=WzGH4wH z?&qF+s+sc@DB%GlZhDcyWN#N1+aG1vL$#rQ(82RiuOroTI*{cORs1=75l%&G4JEOh zNlL1n8xP@N5y`ImgvVfj-lFX2P@Z^r?pQoRQXTp2m4^KpMSZr*d`{zjR5-%0+DT6k ziFG6*dL%DweyMqKf}^nUD3cG_`|e8S&e}B31p26VS4={oUXy+nf(M$0>M>x0V)3 zHePbS3o<_9dXay_ROHE4*b9N1u~od=P%*q_qRdMJk@0BqG|U=9Nq63N_g-%uY%I0@ zRo;zeRD7%IXA#QW+rp-^DzfhW{aaDoywFV6qa6dQMKh@G0Y|Pbe3$Vxn!fWo9|%SJ>-rLcN8~*1lJT&;Hu06>!Ma_FbGE-L8&7|av{TG-m`j;q z-Svw7MN1Qg7md6b-ytE9Sk_EvZ?Q~&3%<&0as=+>yDoaNlS&KkHRJ-utr(}~3NZXe zA89(VEk0Pp8O3lHv45nYf4#+kd|Lm-Ivmjs^X@lA!gX$6uEw4z=mQsQ;rrP6`0$sz z(cp=F{cwQowFlp&VbvJIn4NGR(qqw;K0fT!okxNs#98CUi}IA1t=Vk+XvJV-dhw0S z)(pdBQDtYI84y`u>k?)_6fmti$Bw8nH6IqwZA>~fpGwsB=2@H8eskSlX)Ux?5{i!F z3l>vpTdx;oSWjtJTR*av5?FKwnJA!Leckp?L>N*AKw@L7FwVJuhoiORBpMhU`hX-t z3_5AAS4h~xp^KzgPRGiCOxI#EHgT195V;4FgCri5vWJ6$YWL{a0a8?ADXa320jwP| z7kmbQ^{}``?~!14yh-8+bP4tnp70pDph75ZN>7oCbS$>LJo5 z0s+P#z#SFxtM(p1+AF= z&W6o35h6ZqqYr-v(~#@m6+s5vhxpgSa&Qph8NA=XA60q2600IJv%hu1*f_I5vy%S< zWk*^sTfkHNV$aVy_zfh3lhEK+|201j^aY7{9!CRjn;NZpDr+-}o+CD!uPZ-2BM?&@ z@Czi?)z>ooWf}U`HRiA*Yp|I9c@P=e$&h8K*5xt^!pGPwx3`wsBD%D-V5~6H-VLVH zFtDQ7mM2H-F&XRV0)UymPp+|IH9YJs44pfFzafx_Pt$?5l1(L`yY7aU%E@ zS+i2~lxx4DIER!|-P!S5cWwFmFX9kR!x0-xsPy*rOfc8=Ri??V>ilsEsH>%2@Ls16 zW0L4gf@w_0GS9c{WQN9XmeO(6v@=74%SW77h~T?_xN*#{&3~gI7YjSC9fLSxELQ%k zBX_8x#`$fk(t1=Bd6i?Nn!@}nR$RL8^;hZZQ5|K4`{v=lpC^|MCFC61HxpLKV#6`G ztdkQ-wi79{9Xf(;)sF&y_=v+WKg9AqSMG-Wi_KNWy8c#`OUWMemqsT{I1Ym!?x6V9 z`%p)P&)G9n8#(nuO3n?kH#|PllG@1>YKizXcRgmGyg#FCzWY#iFP2;->I+)yY8f=o z2=@=pVxO~>V`0BNJYb@3ahpqmvScV{Q=m9W?nE17BY(OT%slTQQjxy)xJxB_m6_zd zIL^KQOq+)bF8CD!?;_v#!{xLNb|XBPgd8dBSg2a9yolH><*~PMGjm4!2wxd= zpzzU6ClR|a4~exGw+i`*>iN-E4y0zrExqP64n96a`yB70S{;y*cpeP!nvjmd^lo!U zVn`_hYlls|UU#IY;v%In8ji=<^d=1sGDx0RZThQZU=oqpf9|wgvd?xB0pYq$hH3zJ zyeo1gT za%TsU#qKq+)3yGbJ&~h7ebQ0*Rkv~EGr}LA7k&`0>_W&Kz=;mX@RX%BXsi#4say zEAJJNS%*FrXiT&j3O4K{95HPBCEO2i_H)H;!G@vqK3mlR-2{l|=nM80y|ta+e#x$Y z@|8!anUU_Be{2w6@=Bt8=I1r8@)%#(R9B_*LdhE>V+r$(b+SU{kD*JhaL_&*8 z;ot3ij0)Mmub4Wm54v3C7X8HH|2hs$;`^100Neic8S&ctOfc>Rc?e*2hW4RU!$Yh% zFNnHL6J8+R5=WQ6llRq$hjm|FZFRSfvNPYcBp646mPSB`4VS|&93H~S4>NessLgqp z7Q6FYk2ezV*rI*a#(PxaBVUeZx6niMwgzic@xV71=jLZm$38dy4=GBO&Yq6cZ6Sf0 zd@@XFwY&7e^sUQHBLSDKo;N}~@()XVDKTag6*;+;>acp^W<~?A+GmZh&JcAw+H4TD z-_#RxOKrtrJGqR5$=p=vY|HA`rAHisTx3G-qS6u$aw7Ko4j7IewOEM z!rsTu#z3MIz&%~Z2#x3=3ShMNtZFAvrVnJQ`sySbMNofl&+@Ny$aas#AyPV&O5?1f zM9C%c*!@GwJ_ApTkCo2r8zQ3D($;_?jRR+P zvKvSX;<@kdc9$`LH%fG*GdjH5!xk@FIMJ@g6(|f%5k`hXCB2p?F*T9!ZG&}-5z;J{ zIA~tqrAxv)Q|$Hqnt@XNJne`xid+hdg;g)1_1(Gb{1MM{n1~$OY7HB=l&v~2NKe8J zpO1z`A-;9SFuY0q;)u0KU@IWKot!`%s!ljgMX@jvN8}HPu_L-17 zoH9eW53N4HWw$3sy;8TS1U_ekbi_)X^ewI@j^BHeJNcy4)d`pr2_kr)!=J`b!>VwcPhlHtUAlO|S$wT!w9;IS1~C!Xc$63y*Hq_>|+@4ROPf+T@% zS+4&FSIe6Zv{^FOM!WmDI1tX+;8)tVnyuZK<(_BA$S+1^dvo2)ca|4`iQi=yL;CrH z310qkJ_@Y=qmR68EY*F;^AA~9!jSFQ)2*2K2+)`61U;KO^>RWxCr~zq=ir6N%=Xk9 z>+!q<=zn?S z`FF-1hiwm%eoJm?%&}WUUNP%3WUuY_{IfvImnT~Jbafvg=xS!oCr%K?1=3ZSCe!uC z=uO!D$U;iY?#n8}lSvz*b99+mJEsuNw!%tED65$Y4P1Y7ko{v3C#d516kPT)WT1}2 zZawmuxQ*YwrbG9Z6m*_;YU1a3wj|HSZY4M$nXKQg^bAfA@O|w~Beg%upI^Lu%1@wT zm%qLsEkA6aH0n#O%vprj+{l3dO#KV57!#EA_KR@U@&2ZFSEh(z4?Wy*^W)BK38z8x=cqFDs^5EoZ-T7kd$W9EM>t;7;j_qw5sVWKDm?e2bvU%xRof^fy>7@Q9>no8 z#efIUwBa#=lT3+bBMO0d(xl~aSNobt`}G?p0SGMTiLB9q?fJ$jzxAW1`5X6c%w13L zepS~>#XQ5uF&ee_I4d-;!nW-a(92t!rqdhu84s!0$b6CsL!YZ_*;%H>Rsbe=->qI88*g)uR2l&bbwyvshtjw92koyXN1xdg->|d1!BqnnU2(!F-UY>;CSbFq4R;L)jnfyr2c|vjHExvr zt_mMDZS2|CSr~CjJBf9&&#^=T7YLX3`E``do@Z4>)LNsQa((_A`Uz8^tr;0`cc6|M zjo}a&b+LR4!=|`A8rFaE(-()f9UjogE~)aV->`)Y+=rci0&Q z^lWNZJN3RcP95x1*jJ*<`DLgu5F|(LYYB=0TR~!dMjJ%O#A{^%&W!zsj$dVn1a(9=(Yp(Ano% zJ>zAe0S<$Ao8}Jgv8PRO7#WY~EdKUQ!24BPoR|SOamAS(18s6Dag%yf?&8A-6u-f2bvg!-6kqb>WTNnT zie!X5QLRRCRD*{Q)XVPKfTJ*Vbd{o`Cum`957V^N1_emPa02z(RS&JiSqbK~-QUE} z(ykPhL^wKO1m)t1yM z=KF7$D!+FoQ6R+inFh$tg^IpL+BhCHH>50y=7Z@a@5%Pa0PN~8wC>wT6>h2J)ts_@ z&=cI=3`d#Iz-1=&5ag!?9l`L~)@lFk^VV&lQHAFc(d}5yvo7zD1QID(2Fc=L-<>YT zQuiix{iLH>rU>15n0GEDmzTcOpkR{W{0z#>uP)*cihlVdQxdqRB&_v)A&`fMT&=}@ z$rUjfy@8kK)6@|i3VPD-zHG}0KS8Nx!Cy92Bb9c#B$@x@Gv~BT8M0)0_hKse#SaTl z&fh-~v`O;eo#iL#`>MlGIQ7r^740~HH51bxIihiKR+9Ao$f&FJF%Y5`pkAxH20Db%_**WnLOo1wG+OmU5mx-_7v%yx@b(qAnXQQbE_@*2v*%FPbyw^uX|k z9oV>Iniz4z-sDn4omspS%7lf4r}7}l(wFe2_)Azhgz z%Lft10kBpyUZ5Q}yV3*Yo<_dhygqCBlP?QHZ>I&}%IpnWBQH7NyVefM8~e-0dSh?) zY*@tU{zJnXbZjJ-!g06T`J0Vt^o`bT*<$fP^G0M_Q{TN{OHPt^{DTO%0~<~1U2J1o zDMbB0v7aTNk5jtu3(;tHHbGUhv&jCUX4;M+r_-%FWdn2)JujE%$Eg|c!9$^bpel@~ zs|Yw6U%EN02!1ikv7mH4nxSmp79O>#79Y+~KB{`(ghxjl#}K$t ziflqf+p*JP*4)UaAxRLtfO$_#S`Qpiwz8crV?$c9j=TqQ>lH&RygMzOS{!A zD7W9vt3)U{#`KX3Odpc|hSkgZ!S(YaPjZ=^rPeKJKEXsNd*SC}{|?_sZ_-Q+^+*~U zd483t&P4C!`@b(7&!Y)J)Y{GUDuSrt~gdM(wSYrs18KLY-= z@z2!_iKFXAd#y(OkIsXovbFt=&AB>5DV+kXSVk`l{+7EvIDtolT8lYw&GYYcxfJaD zP;|Wj`3{EL+Q)o==Tn zaekuUTI#?jG-4TUST0RW2<^^}{zU9MZGKcSyy)XEw}v(|Zfw*-D^E0{_ECNHwn185 zT8do9qL>49p@ykvEd+R2)JY~Cd(if=0lJwh-+Cg#k;eHVcT^35p-B5oD1mL_hF#i~ z95N`Dn-8kcb!_AMlXrv3mR!B#50w;vY-lMvTD+Ayok-<$JYN#13SclqANNrSs7-6N zzc|w|C9FSr93UhH%Rm8xIznS;fD?Ss!2pl=01jOFTE`pkgVmSgbHYh=QS)vwF@bJ z<&El2I)m=G;xOVP*&fl~U6l;bLV}?lAtdtWv0|NYqvap=>iH|~MmghoT%ENn@^pi} z`rRj>R{atSJG!v==WsX@UZ$UN_YcCPNJGdh$S1UK<7Zv;ds8z~&1f?I<4C8W&Gy+p z)>!x-zm{7A{%>P)ea{H;2isWScCJ;olE32@kH4{PeD06_{aJ&@H%Pl=*GIuK8W$27 z+fW~%sQ#UmKeRoZ>B(0>%J98%CR25!^_7H#P=jC-`e`Qm7=kwvP+vE~H$qRdz0>E~ zQq8*uFhhx}LjnEE4n2%Sp_MiNy`LK)&pFNiHWgXz_W~J4-(et?pLNU+lvoZbW(ZS^ zU#eAe;!Bpqa@Ow3F@w=%GzNqTKwVtl>?%c*6%E!M0M^2fX9z&5q<$%`_7D2#fYM=S z-|Q(F8L-b%2hv$sS{fe4Lif0N9}&ewLKoc+~v|hm%t_hoBv8rC#b4B zBNf`_)!ziVZ1P=FXS2WV^`M=3%n-a@`(>C4tuxFJ)3`2T*-$8-TCFW0B+|WZcwuWb zp)21}A=eW&V?6ItvQ&!dllSK&umAQ(|LL%gT9f~zgBy}!y+r)SbR1NLb~AQJ@DdUj z*2Hd%UAEdct5>Q z3$zJg(kK_ot&V@ph#cV`n%An&s7S9Fz6T4(j|3HR>2@4ZQql&} zLbX=y7(ECRSa7AhK2cpWE`nv+t-!4F%%~TLT4&HR;Zw-r(nZD>iu77GyxCrK*g!rx z>6Y>kBt+D3m#T1_!F=n2#gb`D?GPEr?i0d1)9&+-XHjyw?&u3d)JhvdFvp}Sef{Q^ zScNzOHi_oien|9iZGUuq>>&eBE92ba5qY_8x0Eea0FT%=G0Wp`ncqV*zqUKOb}v!; zYh zEf`2(fCmrXzsvdn{~c`dL-zgm+y(2~h^(UsXTykRXJ2x0e(z*bu2&bS3EZ!~R6V8v z!Rx7t`Laa-4Z<$WhQwVE4nj&|O@qh~JOOB~2!I&%9^FMD!*@lh3AUbQOhlyQozXtZ zw9&U0dc9|@4AdSFxu;yar*5h&p7`>Aap{QlRJ5=UZN+uLeC%S`7^g3wL(C4z)C4wc z0WGfeJmrMJwZF%t~=QNPVn0p z&$ng{n?PP@_{ok#pQk&sR@*k@|EG93n=szzEXg?1V<&&3lch@jpwQGrJlA$U=lYX( z9}$>`kOMkb9QjxFgaW5a@*~l~q9ePIs?Bjq>Fow@cX)66{^_aJaFBd)UaWru>50J0 z&?MZ?LH{-flQ!^%hDLJbvuJ6n+H!jleg*<}Z-C914vUAbri$ZYx+_4Xc+?1|(#FNi zpW<&P zaRjwWd4Tf`Jph4$IVXX$?bahjWKg5tD%O1M+>SooSTzA%op`bgYS`n#TzJ9SQr=?4 zqnNt!7I@NjSo`Q$*t@G}1dm9^&g@gtaA3zRuTh|iOZv;uz%`RJo$hM=so*p24ZfEM z-HQB=y<+g$^2v(FhtJd9S^TK6hY9IOTy*aF`tRop#J4pV|4G!2SS+hglH<0C)JDCF z!ebxL*16f6k9ni>+DrL&j=u68t9gRhMC`96GGctkL`h|I*Zl6~TEo`rot56%yhG8| z(Y}kAG6SvNlWl>d59TMrE}P5D=WQIZ7C0DK_QS`)1^*!y;!1r%B;V+to1rlH`?3|i zZg94Mzr%lts-ZU%R|2lL<({ddVxuC022rmp!v8Qk7|GdVILC^SamJR1#_v2S`N@}QZ$p;-+b5T{R01>HR&HbmslLjH3AnuGS0gN zdJQ>+Zz2GXa*cWoVVY;{Vha^pN!UvwQWF#rH5BKdMYX76D#a3<-0>kFC-cDxH~i37 z@$vrr8D)e%V6!(`-n$gUK4=su<#JjPK;x`Y*QAo5#0|Wj5lZ5t!S1EvCt;yN`71A= zqOuP@g+*&gPapjchK@dZa%R!U`;P3

FI|DOKh2&5U-&!S|u)9mU^FBP|wRaSj9m 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 + + + view.amazon_marketplace.form + amazon.marketplace + +

+
+
+ + +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + + + view.amazon_marketplace.tree + amazon.marketplace + + + + + + + + + + amazon.marketplace.dashboard + amazon.marketplace + + + + + + + + +
+
+
+
Country +
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+ + + view.amazon_marketplace.search + amazon.marketplace + + + + + + + + + + diff --git a/amazon_integration/views/amazon_menuitems.xml b/amazon_integration/views/amazon_menuitems.xml new file mode 100644 index 00000000..1c35d66b --- /dev/null +++ b/amazon_integration/views/amazon_menuitems.xml @@ -0,0 +1,56 @@ + + + + + + Marketplace + amazon.marketplace + tree,form + + + + Dashboard + ir.actions.act_window + amazon.marketplace + kanban,form + {'search_default_group_country_id':1} + form + + + + + Seller + amazon.seller + tree,form + +

+ Click to create a new Seller. +

+
+
+ + + Settings + res.config.settings + ir.actions.act_window + + form + inline + {'module' : 'amazon_integration'} + + + + + + + + + + + + + + + + +
diff --git a/amazon_integration/views/amazon_seller.xml b/amazon_integration/views/amazon_seller.xml new file mode 100644 index 00000000..9f4d29be --- /dev/null +++ b/amazon_integration/views/amazon_seller.xml @@ -0,0 +1,71 @@ + + + + view.amazon_seller.form + amazon.seller + +
+
+
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + view.amazon_seller.tree + amazon.seller + + + + + + + + + + view.amazon_seller.search + amazon.seller + + + + + + + + + + +
diff --git a/amazon_integration/views/res_config_settings.xml b/amazon_integration/views/res_config_settings.xml new file mode 100644 index 00000000..b49db515 --- /dev/null +++ b/amazon_integration/views/res_config_settings.xml @@ -0,0 +1,38 @@ + + + + + view.amazon_res_config_settings.form + res.config.settings + + + + +
+

Order Info

+
+
+
+
+ Amazon User + +
+ Default user for sales +
+
+
+
+
+
+
+ +
+
+ + + + + + diff --git a/amazon_integration/views/sale_order.xml b/amazon_integration/views/sale_order.xml new file mode 100644 index 00000000..0924deb7 --- /dev/null +++ b/amazon_integration/views/sale_order.xml @@ -0,0 +1,39 @@ + + + + view.amazon_sale_ref.form + sale.order + + + + + + + + + + + + + + + view.amazon_sale_order.search + sale.order + + + + + + + + + + + + + + + + + + diff --git a/amazon_integration/wizard/__init__.py b/amazon_integration/wizard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..2d3f6c2b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +mws==0.8.6 From c1ee39126f84ce51a07604ba11d2bb157716c4bc Mon Sep 17 00:00:00 2001 From: ignacio Date: Fri, 20 Mar 2020 12:50:51 +0100 Subject: [PATCH 2/2] fix noupdate --- amazon_integration/data/ir_cron.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/amazon_integration/data/ir_cron.xml b/amazon_integration/data/ir_cron.xml index ec86a4cd..56ec552f 100644 --- a/amazon_integration/data/ir_cron.xml +++ b/amazon_integration/data/ir_cron.xml @@ -1,6 +1,6 @@ - + Amazon: import orders @@ -14,4 +14,5 @@ 1000 +