From f990125321c69f12070e1396b346592e256cf1d1 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 5 Jun 2020 09:58:25 +0200 Subject: [PATCH 01/33] [ADD] gls_asm_delivery: New module [UPD] Update delivery_gls_asm.pot Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: l10n-spain-12.0/l10n-spain-12.0-delivery_gls_asm Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-delivery_gls_asm/ Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: l10n-spain-12.0/l10n-spain-12.0-delivery_gls_asm Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-delivery_gls_asm/ --- delivery_gls_asm/README.rst | 178 +++ delivery_gls_asm/__init__.py | 2 + delivery_gls_asm/__manifest__.py | 28 + delivery_gls_asm/api/gls_asm_api.wsdl | 1361 +++++++++++++++++ delivery_gls_asm/data/delivery_asm_data.xml | 8 + delivery_gls_asm/i18n/delivery_gls_asm.pot | 724 +++++++++ delivery_gls_asm/i18n/es.po | 750 +++++++++ delivery_gls_asm/models/__init__.py | 3 + delivery_gls_asm/models/delivery_carrier.py | 246 +++ delivery_gls_asm/models/gls_asm_request.py | 409 +++++ delivery_gls_asm/models/stock_picking.py | 29 + delivery_gls_asm/readme/CONFIGURE.rst | 14 + delivery_gls_asm/readme/CONTRIBUTORS.rst | 3 + delivery_gls_asm/readme/DESCRIPTION.rst | 2 + delivery_gls_asm/readme/INSTALL.rst | 6 + delivery_gls_asm/readme/ROADMAP.rst | 4 + delivery_gls_asm/readme/USAGE.rst | 62 + delivery_gls_asm/static/description/icon.png | Bin 0 -> 4444 bytes delivery_gls_asm/static/description/icon.svg | 69 + .../static/description/index.html | 551 +++++++ delivery_gls_asm/tests/__init__.py | 1 + .../tests/test_delivery_gls_asm.py | 105 ++ delivery_gls_asm/views/delivery_asm_view.xml | 58 + .../views/gls_asm_manifest_template.xml | 171 +++ .../views/stock_picking_views.xml | 24 + delivery_gls_asm/wizard/__init__.py | 1 + .../wizard/gls_asm_manifest_wizard.py | 40 + .../wizard/gls_asm_manifest_wizard_views.xml | 26 + 28 files changed, 4875 insertions(+) create mode 100644 delivery_gls_asm/README.rst create mode 100644 delivery_gls_asm/__init__.py create mode 100644 delivery_gls_asm/__manifest__.py create mode 100644 delivery_gls_asm/api/gls_asm_api.wsdl create mode 100644 delivery_gls_asm/data/delivery_asm_data.xml create mode 100644 delivery_gls_asm/i18n/delivery_gls_asm.pot create mode 100644 delivery_gls_asm/i18n/es.po create mode 100644 delivery_gls_asm/models/__init__.py create mode 100644 delivery_gls_asm/models/delivery_carrier.py create mode 100644 delivery_gls_asm/models/gls_asm_request.py create mode 100644 delivery_gls_asm/models/stock_picking.py create mode 100644 delivery_gls_asm/readme/CONFIGURE.rst create mode 100644 delivery_gls_asm/readme/CONTRIBUTORS.rst create mode 100644 delivery_gls_asm/readme/DESCRIPTION.rst create mode 100644 delivery_gls_asm/readme/INSTALL.rst create mode 100644 delivery_gls_asm/readme/ROADMAP.rst create mode 100644 delivery_gls_asm/readme/USAGE.rst create mode 100644 delivery_gls_asm/static/description/icon.png create mode 100644 delivery_gls_asm/static/description/icon.svg create mode 100644 delivery_gls_asm/static/description/index.html create mode 100644 delivery_gls_asm/tests/__init__.py create mode 100644 delivery_gls_asm/tests/test_delivery_gls_asm.py create mode 100644 delivery_gls_asm/views/delivery_asm_view.xml create mode 100644 delivery_gls_asm/views/gls_asm_manifest_template.xml create mode 100644 delivery_gls_asm/views/stock_picking_views.xml create mode 100644 delivery_gls_asm/wizard/__init__.py create mode 100644 delivery_gls_asm/wizard/gls_asm_manifest_wizard.py create mode 100644 delivery_gls_asm/wizard/gls_asm_manifest_wizard_views.xml diff --git a/delivery_gls_asm/README.rst b/delivery_gls_asm/README.rst new file mode 100644 index 00000000000..dd4a5e1360e --- /dev/null +++ b/delivery_gls_asm/README.rst @@ -0,0 +1,178 @@ +================ +Delivery GLS-ASM +================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--spain-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-spain/tree/12.0/delivery_gls_asm + :alt: OCA/l10n-spain +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-delivery_gls_asm + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/189/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Este módulo integra la API de GLS España (antigua API de ASM) con Odoo. No es +válido para integraciones de GLS en otros países, que podrían usar otras APIs. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +Este módulo necesita la librería python `suds` y depende igualmente de los +módulos de OCA/delivery-carrier `delivery_package_number` y `delivery_state`. + +La API de GLS/ASM no provee métodos de cálculo de precio, de modo que para poder +calcular los costes de envío sería recomendable instalar el módulo +`delivery_price_method`. + +Configuration +============= + +Para configurar el transportista: + +#. Vaya a *Inventario > Configuración > Entrega > Método de envío* y cree uno + nuevo. +#. Escoja *GLS ASM* Como proveedor. +#. Configure los datos de servicio que tiene contratados y el producto de + envío que desea utilizar. + +Si no tiene credenciales todavía, puede poner datos inventados y dejar el +método de envío en "Entorno de prueba". Se utilizará el usuario de pruebas de +la API GLS ASM. + +Si GLS cambiase en un futuro el usuario de prueba, puede cambiarlo en los +*Parámetros del sistema* en la clave `delivery_gls_asm.api_user_demo`. + +Usage +===== + +Estas son las distintas operaciones posibles con este módulo: + +Grabar servicios +~~~~~~~~~~~~~~~~ + + #. Al confirmar el albarán, el servicio se grabará en GLS. + #. Con la respuesta, se registrará en el chatter la referencia de envío y + las etiquetas correspondientes. + #. Para gestionar los bultos del envío, se puede utilizar el campo de número + de bultos que añade `delivery_package_number` (ver el README para mayor + información) o bien el flujo nativo de Odoo con paquetes de envío. El + módulo mandará a la API de GLS/ASM el número correspondiente y podremos + descargar las etiquetas en PDF con su correspondiente numeración. + +Cancelar servicios +~~~~~~~~~~~~~~~~~~ + + #. Al igual que en otros métodos de envío, en los albaranes de salida podemos + cancelar un servicio determinado mediante la acción correspondiente en la + pestaña de *Información Adicional*, sección *Información de entrega* una + vez el pedido esté confirmado y la expedición generada. + #. Podremos generar una nueva expedición una vez cancelado si fuese necesario. + +Obtener etiquetas +~~~~~~~~~~~~~~~~~~ + + #. Si por error hubiésemos eliminado el adjunto de las etiquetas que obtuvimos + en la grabación del servicio, podemos obtenerlas de nuevo pulsando en el + botón "Etiqueta GLS" que tenemos en la parte superior de la vista + formulario del albarán. + +Seguimiento de envíos +~~~~~~~~~~~~~~~~~~~~~ + + #. El módulo está integrado con `delivery_state` para poder recabar la + información de seguimiento de nuestros envíos directamente desde la API de + GLS-ASM. + #. Para ello, vaya al albarán con un envío GLS ya grabado y en la pestaña de + *Información adicional* verá el botón *Actualizar seguimiento* para pedir + a la API de GLS que actualice el estado de este envío en Odoo. + +Manifiesto de envíos +~~~~~~~~~~~~~~~~~~~~ + + #. Para obtener el manifiesto de expediciones que firmaría el repartidor, + puede ir al menú *Inventario > Informes > Manifiesto de Envíos GLS*. + #. También puede obtener el manifiesto desde un smart button en el formulario + del transportista. + #. En el asistente, seleccione el servicio GLS del cual quiere sacar el + manifiesto y la fecha desde la que desea listar los envíos. + #. Pulse en el botón "Manifiesto GlS" para obtener un listado en PDF de los + envíos del servicio seleccionado. + +Depuración de errores +~~~~~~~~~~~~~~~~~~~~~ + + #. En cada servicio GLS-ASM dispone de una pestaña llamada "Técnico" en la + que puede consultar la última petición y respuesta a la API de GLS-ASM. + Esto le servirá como ayuda a la hora de depurar posibles errores de + comunicación. + #. También puede activar Odoo con `--log-level=debug` para refistrar las + peticiones y las respuestas en el log. + +Known issues / Roadmap +====================== + +* La API no facilita métodos para cotizar el coste real de los envíos, por lo + que siempre se cotizan a 0. Si la cotización de envíos es necesaria, + puede instalarse el módulo OCA `delivery_price_method` o bien personalizar + el método de cotización para este tipo de transportista. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_: + + * David Vidal + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/l10n-spain `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/delivery_gls_asm/__init__.py b/delivery_gls_asm/__init__.py new file mode 100644 index 00000000000..9b4296142f4 --- /dev/null +++ b/delivery_gls_asm/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/delivery_gls_asm/__manifest__.py b/delivery_gls_asm/__manifest__.py new file mode 100644 index 00000000000..6a711db2533 --- /dev/null +++ b/delivery_gls_asm/__manifest__.py @@ -0,0 +1,28 @@ +# Copyright 2020 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Delivery GLS-ASM", + "summary": "Delivery Carrier implementation for GLS with ASMRed API", + "version": "12.0.1.0.0", + "category": "Stock", + "website": "https://github.com/OCA/l10n-spain", + "author": "Tecnativa, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "delivery_package_number", + "delivery_state", + ], + "external_dependencies" : { + "python" : ["suds"], + }, + "data": [ + "data/delivery_asm_data.xml", + "views/delivery_asm_view.xml", + "views/gls_asm_manifest_template.xml", + "views/stock_picking_views.xml", + "wizard/gls_asm_manifest_wizard_views.xml", + ], +} diff --git a/delivery_gls_asm/api/gls_asm_api.wsdl b/delivery_gls_asm/api/gls_asm_api.wsdl new file mode 100644 index 00000000000..a2fc54d2322 --- /dev/null +++ b/delivery_gls_asm/api/gls_asm_api.wsdl @@ -0,0 +1,1361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_gls_asm/data/delivery_asm_data.xml b/delivery_gls_asm/data/delivery_asm_data.xml new file mode 100644 index 00000000000..4ceb87f9bd0 --- /dev/null +++ b/delivery_gls_asm/data/delivery_asm_data.xml @@ -0,0 +1,8 @@ + + + + + delivery_gls_asm.api_user_demo + 6BAB7A53-3B6D-4D5A-9450-702D2FAC0B11 + + diff --git a/delivery_gls_asm/i18n/delivery_gls_asm.pot b/delivery_gls_asm/i18n/delivery_gls_asm.pot new file mode 100644 index 00000000000..446f5ace645 --- /dev/null +++ b/delivery_gls_asm/i18n/delivery_gls_asm.pot @@ -0,0 +1,724 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * delivery_gls_asm +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \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: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "10:00 Service" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "14:00 Service" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "14H SOBRES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "24H SOBRES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "72H SOBRES" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "
(Kg.)" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "
(Packages)" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "\n" +" Carrier Signature / Stamp\n" +" " +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "TOTAL EXPEDITIONS: " +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Company:" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Date of printing" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "GLS MANIFEST" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Manifest Date:" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Printed by" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "TOTAL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASM BUROFAX" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASM GO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASM0830" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASMTRAVELLERS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "BICI" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "Based on Rules" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "BusinessParcel" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CAN MUESTRAS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CARGA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CARGA MARITIMA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "COMPRAS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CORREO INTERNO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "COURIER" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.delivery_manifest_wizard_form +msgid "Cancelar" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_postage_type:0 +msgid "Cash On Delivery" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "City" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__create_uid +msgid "Created by" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__create_date +msgid "Created on" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Customer" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "DEVOLUCION" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "DISTRIBUCION PROPIA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "DISTRIBUCION  RED" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__date_from +msgid "Date From" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model,name:delivery_gls_asm.model_delivery_carrier +msgid "Delivery Methods" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__display_name +msgid "Display Name" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EASYBAG" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EURO ESTANDAR" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EURO SMALL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EUROBUSINESS PARCEL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EUROBUSINESS SMALL PARCEL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "EconomyParcel" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Ent. Pto. ASM" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "Fixed Price" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Franja Horaria" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "GLASS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "GLS ASM" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_stock_picking__gls_asm_public_tracking_ref +msgid "GLS Barcode" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:204 +#, python-format +msgid "GLS Cancellation failed with reason: %s" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_delivery_carrier_form +msgid "GLS Configuration" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.ui.menu,name:delivery_gls_asm.menu_gls_asm_manifest +msgid "GLS Deliveries Manifest" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:210 +#, python-format +msgid "GLS Expedition with reference %s cancelled" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_picking_form +msgid "GLS Label" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:237 +#: model:ir.actions.act_window,name:delivery_gls_asm.action_delivery_gls_asm_manifest_wizard +#: model:ir.actions.report,name:delivery_gls_asm.gls_asm_manifest_report +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.delivery_manifest_wizard_form +#, python-format +msgid "GLS Manifest" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_service +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__carrier_id +msgid "GLS Service" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:160 +#, python-format +msgid "GLS Shipping extra info:\n" +"barcode: %s" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_uid +msgid "GLS UID" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/stock_picking.py:27 +#, python-format +msgid "GLS label for %s" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:297 +#, python-format +msgid "GLS returned an error trying to record the shipping for {}.\n" +"Error:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:318 +#, python-format +msgid "GLS: No response from server getting state from ref {}.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:347 +#, python-format +msgid "GLS: No response from server printing label with ref {}.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.delivery_manifest_wizard_form +msgid "Get Manifest" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model,name:delivery_gls_asm.model_gls_asm_minifest_wizard +msgid "Get the GLS Manifest for the given date range" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "IBEX" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__id +msgid "ID" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INT PAQUET" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INTERC. EUROESTANDAR" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "INTERDIA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INTERNACIONAL ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INTERNACIONAL EXPRESS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "Int. WEB" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/wizard/gls_asm_manifest_wizard.py:28 +#, python-format +msgid "It wasn't possible to get the manifest. Maybe there aren'tdeliveries for the selected date." +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_last_request +msgid "Last GLS xml request" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_last_response +msgid "Last GLS xml response" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard____last_update +msgid "Last Modified on" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__write_date +msgid "Last Updated on" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "MR1" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_delivery_carrier_form +msgid "Manifest" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Maritimo" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Masivo" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:404 +#, python-format +msgid "No response from server getting manifisto for GLS.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:286 +#, python-format +msgid "No response from server recording GLS delivery {}.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "OPERACIONES RED" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "OPTIPLUS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "OTROS PUENTES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "PREPAGO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "PROPIO AGENTE" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Packages" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "ParcelShop" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_postage_type +msgid "Postage Type" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_asm_postage_type +msgid "Postage type, usually 'Prepaid'" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_postage_type:0 +msgid "Prepaid" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__delivery_type +msgid "Provider" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RC. PARCEL SHOP" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RC.SELLADA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "REC. INT" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "REC. INT WW" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "REC. INTERCIUDAD ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECANALIZA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA CRUZADA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. CAMION" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. F.GRANDE" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. FURGONETA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. MOTO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MENSAJERO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA SIN MERCANCIA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RETORNO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Rec. en NAVE." +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Ref." +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL CAMION" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL F. GRANDE" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL FURGONETA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL MOTO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIOS ESPECIALES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIOS RUTAS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "SaturdayService" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_asm_service +msgid "Set the contracted GLS Service" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_asm_shiptime +msgid "Set the desired GLS shipping time for this carrier" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "Seur" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_shiptime +msgid "Shipping Time" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_delivery_carrier_form +msgid "Technical" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model,name:delivery_gls_asm.model_stock_picking +msgid "Transfer" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_last_request +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_last_response +msgid "Used for issues debugging" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "VALIJA" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Weight" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "ZIP Code" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "dPRO" +msgstr "" + diff --git a/delivery_gls_asm/i18n/es.po b/delivery_gls_asm/i18n/es.po new file mode 100644 index 00000000000..2ab14c9707c --- /dev/null +++ b/delivery_gls_asm/i18n/es.po @@ -0,0 +1,750 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * delivery_gls_asm +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-06-05 07:09+0000\n" +"PO-Revision-Date: 2020-08-13 11:01+0200\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 2.3\n" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "10:00 Service" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "14:00 Service" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "14H SOBRES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "24H SOBRES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "72H SOBRES" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "
(Kg.)" +msgstr "
(Kg.)" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "
(Packages)" +msgstr "
(Bultos)" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "" +"\n" +" Carrier Signature / Stamp\n" +" " +msgstr "" +"\n" +" Sello / Firma del " +"Transportista\n" +" " + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "TOTAL EXPEDITIONS: " +msgstr "TOTAL EXPEDICIONES: " + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Company:" +msgstr "Compañía:" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Date of printing" +msgstr "Fecha de impresión" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "GLS MANIFEST" +msgstr "MANIFIESTO GLS" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Manifest Date:" +msgstr "Fecha de manifiesto:" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Printed by" +msgstr "Imprimido por" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "TOTAL" +msgstr "TOTAL" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASM BUROFAX" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASM GO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASM0830" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ASMTRAVELLERS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "BICI" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "Based on Rules" +msgstr "En base a reglas" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "BusinessParcel" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CAN MUESTRAS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CARGA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CARGA MARITIMA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "COMPRAS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "CORREO INTERNO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "COURIER" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.delivery_manifest_wizard_form +msgid "Cancelar" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_postage_type:0 +msgid "Cash On Delivery" +msgstr "Reembolso" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "City" +msgstr "Ciudad" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Customer" +msgstr "Cliente" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "DEVOLUCION" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "DISTRIBUCION PROPIA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "DISTRIBUCION  RED" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__date_from +msgid "Date From" +msgstr "Fecha desde" + +#. module: delivery_gls_asm +#: model:ir.model,name:delivery_gls_asm.model_delivery_carrier +msgid "Delivery Methods" +msgstr "Método de envío" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EASYBAG" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EURO ESTANDAR" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EURO SMALL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EUROBUSINESS PARCEL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "EUROBUSINESS SMALL PARCEL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "EconomyParcel" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Ent. Pto. ASM" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "Fixed Price" +msgstr "Precio fijo" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Franja Horaria" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "GLASS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "GLS ASM" +msgstr "GLS ASM" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_stock_picking__gls_asm_public_tracking_ref +msgid "GLS Barcode" +msgstr "Código de barras GLS" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:204 +#, python-format +msgid "GLS Cancellation failed with reason: %s" +msgstr "La cancelación de GLS falló por esta causa: %s" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_delivery_carrier_form +msgid "GLS Configuration" +msgstr "Configuración GLS" + +#. module: delivery_gls_asm +#: model:ir.ui.menu,name:delivery_gls_asm.menu_gls_asm_manifest +msgid "GLS Deliveries Manifest" +msgstr "Manifiesto de Envíos GLS" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:210 +#, python-format +msgid "GLS Expedition with reference %s cancelled" +msgstr "Expedición GLS con referencia %s cancelada" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_picking_form +msgid "GLS Label" +msgstr "Etiqueta GLS" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:237 +#: model:ir.actions.act_window,name:delivery_gls_asm.action_delivery_gls_asm_manifest_wizard +#: model:ir.actions.report,name:delivery_gls_asm.gls_asm_manifest_report +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.delivery_manifest_wizard_form +#, python-format +msgid "GLS Manifest" +msgstr "Manifiesto GLS" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_service +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__carrier_id +msgid "GLS Service" +msgstr "Servicio GLS" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/delivery_carrier.py:160 +#, python-format +msgid "" +"GLS Shipping extra info:\n" +"barcode: %s" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_uid +msgid "GLS UID" +msgstr "UID GLS" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/stock_picking.py:27 +#, fuzzy, python-format +msgid "GLS label for %s" +msgstr "Etiqueta GLS" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:297 +#, python-format +msgid "" +"GLS returned an error trying to record the shipping for {}.\n" +"Error:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:318 +#, python-format +msgid "" +"GLS: No response from server getting state from ref {}.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:347 +#, python-format +msgid "" +"GLS: No response from server printing label with ref {}.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.delivery_manifest_wizard_form +msgid "Get Manifest" +msgstr "Obtenter manifiesto" + +#. module: delivery_gls_asm +#: model:ir.model,name:delivery_gls_asm.model_gls_asm_minifest_wizard +msgid "Get the GLS Manifest for the given date range" +msgstr "Obtener el Manifiesto de GLS para el rango de fechas indicado" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "IBEX" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__id +msgid "ID" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INT PAQUET" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INTERC. EUROESTANDAR" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "INTERDIA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INTERNACIONAL ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "INTERNACIONAL EXPRESS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "Int. WEB" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/wizard/gls_asm_manifest_wizard.py:28 +#, python-format +msgid "" +"It wasn't possible to get the manifest. Maybe there aren'tdeliveries for the " +"selected date." +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_last_request +msgid "Last GLS xml request" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_last_response +msgid "Last GLS xml response" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_gls_asm_minifest_wizard__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "MR1" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_delivery_carrier_form +msgid "Manifest" +msgstr "Manifiesto" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Maritimo" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Masivo" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:404 +#, python-format +msgid "" +"No response from server getting manifisto for GLS.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: code:addons/delivery_gls_asm/models/gls_asm_request.py:286 +#, python-format +msgid "" +"No response from server recording GLS delivery {}.\n" +"Traceback:\n" +"{}" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "OPERACIONES RED" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "OPTIPLUS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "OTROS PUENTES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "PREPAGO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "PROPIO AGENTE" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Packages" +msgstr "Bultos" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "ParcelShop" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_postage_type +msgid "Postage Type" +msgstr "Tipo de envío" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_asm_postage_type +msgid "Postage type, usually 'Prepaid'" +msgstr "Tipo de envío, normalment 'Prepago'" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_postage_type:0 +msgid "Prepaid" +msgstr "Prepago" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__delivery_type +msgid "Provider" +msgstr "Proveedor" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RC. PARCEL SHOP" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RC.SELLADA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "REC. INT" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "REC. INT WW" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "REC. INTERCIUDAD ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECANALIZA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA CRUZADA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA ECONOMY" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. CAMION" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. F.GRANDE" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. FURGONETA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MEN. MOTO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA MENSAJERO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RECOGIDA SIN MERCANCIA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "RETORNO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "Rec. en NAVE." +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Ref." +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL CAMION" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL F. GRANDE" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL FURGONETA" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIO LOCAL MOTO" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIOS ESPECIALES" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "SERVICIOS RUTAS" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_shiptime:0 +msgid "SaturdayService" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_asm_service +msgid "Set the contracted GLS Service" +msgstr "Establezca el servicio GLS contratado" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_asm_shiptime +msgid "Set the desired GLS shipping time for this carrier" +msgstr "Establezca el tiempo de envío de las opciones de GLS" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,delivery_type:0 +msgid "Seur" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model.fields,field_description:delivery_gls_asm.field_delivery_carrier__gls_asm_shiptime +msgid "Shipping Time" +msgstr "Tiempo de envío" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.view_delivery_carrier_form +msgid "Technical" +msgstr "" + +#. module: delivery_gls_asm +#: model:ir.model,name:delivery_gls_asm.model_stock_picking +msgid "Transfer" +msgstr "Albarán" + +#. module: delivery_gls_asm +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_last_request +#: model:ir.model.fields,help:delivery_gls_asm.field_delivery_carrier__gls_last_response +msgid "Used for issues debugging" +msgstr "" + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "VALIJA" +msgstr "" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "Weight" +msgstr "Peso" + +#. module: delivery_gls_asm +#: model_terms:ir.ui.view,arch_db:delivery_gls_asm.gls_asm_manifest_report_view +msgid "ZIP Code" +msgstr "C.P." + +#. module: delivery_gls_asm +#: selection:delivery.carrier,gls_asm_service:0 +msgid "dPRO" +msgstr "" + +#~ msgid "Carrier" +#~ msgstr "Transportista" + +#~ msgid "No carrier integration" +#~ msgstr "Sin integración de transportista" + +#~ msgid "Product Packaging" +#~ msgstr "Empaquetado del producto" diff --git a/delivery_gls_asm/models/__init__.py b/delivery_gls_asm/models/__init__.py new file mode 100644 index 00000000000..0c424d37f19 --- /dev/null +++ b/delivery_gls_asm/models/__init__.py @@ -0,0 +1,3 @@ +from . import gls_asm_request +from . import delivery_carrier +from . import stock_picking diff --git a/delivery_gls_asm/models/delivery_carrier.py b/delivery_gls_asm/models/delivery_carrier.py new file mode 100644 index 00000000000..d2dc7593c9a --- /dev/null +++ b/delivery_gls_asm/models/delivery_carrier.py @@ -0,0 +1,246 @@ +# Copyright 2020 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import _, fields, models +from .gls_asm_request import GlsAsmRequest +from .gls_asm_request import ( + GLS_ASM_SERVICES, GLS_SHIPPING_TIMES, GLS_POSTAGE_TYPE, + GLS_DELIVERY_STATES_STATIC) + + +class DeliveryCarrier(models.Model): + _inherit = "delivery.carrier" + + delivery_type = fields.Selection(selection_add=[("gls_asm", "GLS ASM")]) + gls_asm_uid = fields.Char( + string="GLS UID", + ) + gls_asm_service = fields.Selection( + selection=GLS_ASM_SERVICES, + string="GLS Service", + help="Set the contracted GLS Service", + default="1", # Courier + ) + gls_asm_shiptime = fields.Selection( + selection=GLS_SHIPPING_TIMES, + string="Shipping Time", + help="Set the desired GLS shipping time for this carrier", + default="0", # 10h + ) + gls_asm_postage_type = fields.Selection( + selection=GLS_POSTAGE_TYPE, + string="Postage Type", + help="Postage type, usually 'Prepaid'", + default="P", + ) + gls_last_request = fields.Text( + string="Last GLS xml request", + help="Used for issues debugging", + readonly=True, + ) + gls_last_response = fields.Text( + string="Last GLS xml response", + help="Used for issues debugging", + readonly=True, + ) + + def _gls_asm_uid(self): + """The carrier can be put in test mode. The tests user must be set. + A default given by GLS is put in the config parameter data """ + self.ensure_one() + uid = ( + self.gls_asm_uid if self.prod_environment else + self.env['ir.config_parameter'].sudo().get_param( + 'delivery_gls_asm.api_user_demo', '')) + return uid + + def gls_asm_get_tracking_link(self, picking): + """Provide tracking link for the customer""" + tracking_url = ("http://www.asmred.com/extranet/public/" + "ExpedicionASM.aspx?codigo={}&cpDst={}") + return tracking_url.format( + picking.carrier_tracking_ref, picking.partner_id.zip) + + def _prepare_gls_asm_shipping(self, picking): + """Convert picking values for asm api + :param picking record with picking to send + :returns dict values for the connector + """ + self.ensure_one() + # A picking can be delivered from any warehouse + sender_partner = ( + picking.picking_type_id.warehouse_id.partner_id or + picking.company_id.partner_id) + return { + "fecha": fields.Date.today().strftime("%d/%m/%Y"), + "portes": self.gls_asm_postage_type, + "servicio": self.gls_asm_service, + "horario": self.gls_asm_shiptime, + "bultos": picking.number_of_packages, + "peso": round(picking.shipping_weight, 3), + "volumen": "", # [optional] Volume, in m3 + "declarado": "", # [optional] + "dninomb": "0", # [optional] + "fechaentrega": "", # [optional] + "retorno": "0", # [optional] + "pod": "N", # [optional] + "podobligatorio": "N", # [deprecated] + "remite_plaza": "", # [optional] Origin agency + "remite_nombre": sender_partner.name, + "remite_direccion": sender_partner.street or "", + "remite_poblacion": sender_partner.city or "", + "remite_provincia": sender_partner.state_id.name or "", + "remite_pais": "34", # [mandatory] always 34=Spain + "remite_cp": sender_partner.zip or "", + "remite_telefono": sender_partner.phone or "", + "remite_movil": sender_partner.mobile or "", + "remite_email": sender_partner.email or "", + "remite_departamento": "", + "remite_nif": sender_partner.vat or "", + "remite_observaciones": "", + "destinatario_codigo": "", + "destinatario_plaza": "", + "destinatario_nombre": ( + picking.partner_id.name or + picking.partner_id.commercial_partner_id.name), + "destinatario_direccion": picking.partner_id.street or "", + "destinatario_poblacion": picking.partner_id.city or "", + "destinatario_provincia": picking.partner_id.state_id.name or "", + "destinatario_pais": ( + picking.partner_id.country_id.phone_code or ""), + "destinatario_cp": picking.partner_id.zip, + "destinatario_telefono": picking.partner_id.phone or "", + "destinatario_movil": picking.partner_id.mobile or "", + "destinatario_email": picking.partner_id.email or "", + "destinatario_observaciones": "", + "destinatario_att": "", + "destinatario_departamento": "", + "destinatario_nif": "", + "referencia_c": picking.name, # Our unique reference + "referencia_0": "", # Not used if the above is set + "importes_debido": "0", # The customer pays the shipping + "importes_reembolso": "", # TODO: Support Cash On Delivery + "seguro": "0", # [optional] + "seguro_descripcion": "", # [optional] + "seguro_importe": "", # [optional] + "etiqueta": "PDF", # Get Label in response + "etiqueta_devolucion": "PDF", + # [optional] GLS Customer Code + # (when customer have several codes in GLS) + "cliente_codigo": "", + "cliente_plaza": "", + "cliente_agente": "", + } + + def gls_asm_send_shipping(self, pickings): + """Send the package to GLS + :param pickings: A recordset of pickings + :return list: A list of dictionaries although in practice it's + called one by one and only the first item in the dict is taken. Due + to this design, we have to inject vals in the context to be able to + add them to the message. + """ + gls_request = GlsAsmRequest(self._gls_asm_uid()) + result = [] + for picking in pickings: + vals = self._prepare_gls_asm_shipping(picking) + vals.update({"tracking_number": False, "exact_price": 0}) + response = gls_request._send_shipping(vals) + self.gls_last_request = response and response.get( + "gls_sent_xml", "") + self.gls_last_response = response or "" + if not response or response.get("_return", -1) < 0: + result.append(vals) + continue + # For compatibility we provide this number although we get + # two more codes: codbarras and uid + vals["tracking_number"] = response.get("_codexp") + picking.gls_asm_public_tracking_ref = response.get("_codbarras") + # We post an extra message in the chatter with the barcode and the + # label because there's clean way to override the one sent by core. + body = (_( + "GLS Shipping extra info:\n" + "barcode: %s") % response.get("_codbarras")) + attachment = [] + if response.get("gls_label"): + attachment = [( + "gls_label_{}.pdf".format(response.get("_codbarras")), + response.get("gls_label") + )] + picking.message_post(body=body, attachments=attachment) + result.append(vals) + return result + + def gls_asm_tracking_state_update(self, picking): + """Tracking state update""" + self.ensure_one() + if not picking.carrier_tracking_ref: + return + gls_request = GlsAsmRequest(self._gls_asm_uid()) + tracking_states = gls_request._get_tracking_states( + picking.carrier_tracking_ref) + if not tracking_states: + return + picking.tracking_state_history = "\n".join([ + "%s - [%s] %s" % ( + t.get("fecha"), t.get("codigo"), t.get("evento")) + for t in tracking_states + ]) + tracking = tracking_states.pop() + picking.tracking_state = "[{}] {}".format( + tracking.get("codigo"), tracking.get("evento")) + picking.delivery_state = GLS_DELIVERY_STATES_STATIC.get( + tracking.get("codigo"), 'incidence') + + def gls_asm_cancel_shipment(self, pickings): + """Cancel the expedition""" + gls_request = GlsAsmRequest(self._gls_asm_uid()) + for picking in pickings.filtered("carrier_tracking_ref"): + response = gls_request._cancel_shipment( + picking.carrier_tracking_ref) + self.gls_last_request = response and response.get( + "gls_sent_xml", "") + self.gls_last_response = response or "" + if not response or response.get("_return") < 0: + msg = (_( + "GLS Cancellation failed with reason: %s") % + response.get("value", "Connection Error")) + picking.message_post(body=msg) + continue + picking.gls_asm_public_tracking_ref = False + picking.message_post(body=_( + "GLS Expedition with reference %s cancelled") % + picking.carrier_tracking_ref) + + def gls_asm_get_label(self, gls_asm_public_tracking_ref): + """Generate label for picking + :param picking - stock.picking record + :returns pdf file + """ + self.ensure_one() + if not gls_asm_public_tracking_ref: + return False + gls_request = GlsAsmRequest(self._gls_asm_uid()) + label = gls_request._shipping_label(gls_asm_public_tracking_ref) + if not label: + return False + return label + + def action_get_manifest(self): + """Action to launch the manifest wizard""" + self.ensure_one() + wizard = self.env["gls.asm.minifest.wizard"].create({ + "carrier_id": self.id}) + view_id = self.env.ref( + "delivery_gls_asm.delivery_manifest_wizard_form" + ).id + return { + "name": _("GLS Manifest"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "gls.asm.minifest.wizard", + "view_id": view_id, + "views": [(view_id, "form")], + "target": "new", + "res_id": wizard.id, + "context": self.env.context, + } diff --git a/delivery_gls_asm/models/gls_asm_request.py b/delivery_gls_asm/models/gls_asm_request.py new file mode 100644 index 00000000000..709d3308c91 --- /dev/null +++ b/delivery_gls_asm/models/gls_asm_request.py @@ -0,0 +1,409 @@ +# Copyright 2020 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import _ +from odoo.exceptions import UserError +import logging +import binascii +import os +_logger = logging.getLogger(__name__) + +try: + from suds.client import Client + from suds.sax.text import Raw + from suds.sudsobject import asdict +except (ImportError, IOError) as err: + _logger.debug(err) + + +GLS_ASM_SERVICES = [ + ('1', 'COURIER'), + ('2', 'VALIJA'), + ('5', 'BICI'), + ('6', 'CARGA'), + ('7', 'RECOGIDA'), + ('8', 'RECOGIDA CRUZADA'), + ('9', 'DEVOLUCION'), + ('10', 'RETORNO'), + ('11', 'IBEX'), + ('12', 'INTERNACIONAL EXPRESS'), + ('13', 'INTERNACIONAL ECONOMY'), + ('14', 'DISTRIBUCION PROPIA'), + ('15', 'OTROS PUENTES'), + ('16', 'PROPIO AGENTE'), + ('17', 'RECOGIDA SIN MERCANCIA'), + ('18', 'DISTRIBUCION  RED'), + ('19', 'OPERACIONES RED'), + ('20', 'CARGA MARITIMA'), + ('21', 'GLASS'), + ('22', 'EURO SMALL'), + ('23', 'PREPAGO'), + ('24', 'OPTIPLUS'), + ('25', 'EASYBAG'), + ('26', 'CORREO INTERNO'), + ('27', '14H SOBRES'), + ('28', '24H SOBRES'), + ('29', '72H SOBRES'), + ('30', 'ASM0830'), + ('31', 'CAN MUESTRAS'), + ('32', 'RC.SELLADA'), + ('33', 'RECANALIZA'), + ('34', 'INT PAQUET'), + ('35', 'dPRO'), + ('36', 'Int. WEB'), + ('37', 'ECONOMY'), + ('38', 'SERVICIOS RUTAS'), + ('39', 'REC. INT'), + ('40', 'SERVICIO LOCAL MOTO'), + ('41', 'SERVICIO LOCAL FURGONETA'), + ('42', 'SERVICIO LOCAL F. GRANDE'), + ('43', 'SERVICIO LOCAL CAMION'), + ('44', 'SERVICIO LOCAL'), + ('45', 'RECOGIDA MEN. MOTO'), + ('46', 'RECOGIDA MEN. FURGONETA'), + ('47', 'RECOGIDA MEN. F.GRANDE'), + ('48', 'RECOGIDA MEN. CAMION'), + ('49', 'RECOGIDA MENSAJERO'), + ('50', 'SERVICIOS ESPECIALES'), + ('51', 'REC. INT WW'), + ('52', 'COMPRAS'), + ('53', 'MR1'), + ('54', 'EURO ESTANDAR'), + ('55', 'INTERC. EUROESTANDAR'), + ('56', 'RECOGIDA ECONOMY'), + ('57', 'REC. INTERCIUDAD ECONOMY'), + ('58', 'RC. PARCEL SHOP'), + ('59', 'ASM BUROFAX'), + ('60', 'ASM GO'), + ('66', 'ASMTRAVELLERS'), + ('74', 'EUROBUSINESS PARCEL'), + ('76', 'EUROBUSINESS SMALL PARCEL'), +] + +GLS_SHIPPING_TIMES = [ + ("0", "10:00 Service"), + ("2", "14:00 Service"), + ("3", "BusinessParcel"), + ("5", "SaturdayService"), + ("7", "INTERDIA"), + ("9", "Franja Horaria"), + ("4", "Masivo"), + ("10", "Maritimo"), + ("11", "Rec. en NAVE."), + ("13", "Ent. Pto. ASM"), + ("18", "EconomyParcel"), + ("19", "ParcelShop"), +] + +GLS_POSTAGE_TYPE = [ + ("P", "Prepaid"), + ("D", "Cash On Delivery"), +] + +GLS_DELIVERY_STATES_STATIC = { + "-10": "shipping_recorded_in_carrier", # GRABADO + "0": "shipping_recorded_in_carrier", # MANIFESTADA + "2": "in_transit", # EN TRANSITO A DESTINO + "3": "in_transit", # EN DELEGACION DESTINO + "20": "incidence", # PERDIDA / ROTURA + "5": "canceled_shipment", # ANULADA + "6": "in_transit", # EN REPARTO + "7": "customer_delivered", # ENTREGADO + "8": "customer_delivered", # ENTREGA PARCIAL + "9": "in_transit", # ALMACENADO + "10": "incidence", # DEVUELTA + "11": "incidence", # PENDIENTE DATOS, EN DELEGACION + "1": "incidence", # RETENIDA EN DELEGACION + "91": "incidence", # CON INCIDENCIA + "90": "incidence", # CERRADO DEFINITIVO + "50": "in_transit", # PRECONFIRMADA ENTREGA + "51": "incidence", # ENTREGA ANULADA (DEVUELTA) + "12": "incidence", # DEVUELTA AL CLIENTE + "13": "incidence", # POSIBLE DEVOLUCION + "14": "incidence", # SOLICITUD DE DEVOLUCION + "15": "incidence", # EN DEVOLUCION + "16": "in_transit", # EN DELEGACION ORIGEN + "17": "incidence", # DESTRUIDO POR ORDEN DEL CLIENTE + "18": "incidence", # RETENIDO POR ORDEN DE PAGA + "19": "in_transit", # EN PLATAFORMA DE DESTINO + "21": "incidence", # RECANALIZADA (A EXTINGUIR) + "22": "in_transit", # ENTREGADO EN ASM PARCELSHOP + "25": "in_transit", # ASM PARCELSHOP CONFIRMA RECEPCION +} + + +class GlsAsmRequest(): + """Interface between GLS-ASM SOAP API and Odoo recordset + Abstract GLS-ASM API Operations to connect them with Odoo + + Not all the features are implemented, but could be easily extended with + the provided API. We leave the operations empty for future. + """ + + def __init__(self, uidcustomer=None): + """As the wsdl isn't public, we have to load it from local""" + wsdl_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + '../api/gls_asm_api.wsdl') + self.uidcustomer = uidcustomer or "" + self.client = Client("file:{}".format(wsdl_path)) + + def _recursive_asdict(self, suds_object): + """As suds response is an special object, we convert it into + a more usable python dict. Taken form: + https://stackoverflow.com/a/15678861 + """ + out = {} + for k, v in asdict(suds_object).items(): + if hasattr(v, '__keylist__'): + out[k] = self._recursive_asdict(v) + elif isinstance(v, list): + out[k] = [] + for item in v: + if hasattr(item, '__keylist__'): + out[k].append(self._recursive_asdict(item)) + else: + out[k].append(item) + else: + out[k] = v + return out + + def _prepare_cancel_shipment_docin(self, **kwargs): + """ASM API is not very standard. Prepare parameters to pass them raw in + the SOAP message""" + return """ + + + + """.format(**kwargs) + + def _prepare__get_manifest_docin(self, **kwargs): + """ASM API is not very standard. Prepare parameters to pass them raw in + the SOAP message""" + return """ + + {date_from} + + + """.format(**kwargs) + + def _prepare_send_shipping_docin(self, **kwargs): + """ASM API is not very standard. Prepare parameters to pass them raw in + the SOAP message""" + return """ + + + {fecha} + {portes} + {servicio} + {horario} + {bultos} + {peso} + {volumen} + {declarado} + {dninomb} + {fechaentrega} + {retorno} + {pod} + {podobligatorio} + + {remite_plaza} + {remite_nombre} + {remite_direccion} + {remite_poblacion} + {remite_provincia} + {remite_pais} + {remite_cp} + {remite_telefono} + {remite_movil} + {remite_email} + {remite_departamento} + {remite_nif} + {remite_observaciones} + + + {destinatario_codigo} + {destinatario_plaza} + {destinatario_nombre} + {destinatario_direccion} + {destinatario_poblacion} + {destinatario_provincia} + {destinatario_pais} + {destinatario_cp} + {destinatario_telefono} + {destinatario_movil} + {destinatario_email} + + {destinatario_observaciones} + + {destinatario_att} + {destinatario_departamento} + {destinatario_nif} + + + {referencia_c} + {referencia_0} + + + {importes_debido} + {importes_reembolso} + + + {seguro_descripcion} + {seguro_importe} + + + + + + + + + {cliente_codigo} + {cliente_plaza} + {cliente_agente} + + + + """.format(**kwargs) + + def _send_shipping(self, vals): + """Create new shipment + :params vals dict of needed values + :returns dict with GLS response containing the shipping codes, labels, + an other relevant data + """ + vals.update({ + 'uidcustomer': self.uidcustomer, + }) + xml = Raw(self._prepare_send_shipping_docin(**vals)) + _logger.debug(xml) + try: + res = self.client.service.GrabaServicios(docIn=xml) + except Exception as e: + raise UserError(_( + "No response from server recording GLS delivery {}.\n" + "Traceback:\n{}").format(vals.get("referencia_c", ""), e)) + # Convert result suds object to dict and set the root conveniently + # GLS API Errors have codes below 0 so we have to + # convert to int as well + res = self._recursive_asdict(res)['Servicios']['Envio'] + res["gls_sent_xml"] = xml + _logger.debug(res) + res["_return"] = int(res["Resultado"]["_return"]) + if res["_return"] < 0: + raise UserError(_( + "GLS returned an error trying to record the shipping for {}.\n" + "Error:\n{}").format( + vals.get("referencia_c", ""), + res.get("Errores", {}).get( + "Error", "code {}".format(res["_return"])))) + if res.get('Etiquetas', {}).get('Etiqueta', {}).get("value"): + res["gls_label"] = ( + binascii.a2b_base64(res["Etiquetas"]["Etiqueta"]["value"])) + return res + + def _get_delivery_info(self, reference=False): + """Get delivery info recorded in GLS for the given reference + :param str reference -- GLS tracking number + :returns: shipping info dict + """ + try: + res = self.client.service.GetExpCli( + codigo=reference, uid=self.uidcustomer) + _logger.debug(res) + except Exception as e: + raise UserError(_( + "GLS: No response from server getting state from ref {}.\n" + "Traceback:\n{}").format(reference, e)) + res = self._recursive_asdict(res) + return res + + def _get_tracking_states(self, reference=False): + """Get just tracking states from GLS info for the given reference + :param str reference -- GLS tracking number + :returns: list of tracking states + """ + res = self._get_delivery_info(reference) + res = res.get("expediciones", {}).get("exp", {}).get( + "tracking_list", {}).get("tracking", []) + # If there's just one state, we'll get a single dict, otherwise we + # get a list of dicts + if isinstance(res, dict): + return [res] + return res + + def _shipping_label(self, reference=False): + """Get shipping label for the given ref + :param str reference -- public shipping reference + :returns: base64 with pdf label or False + """ + try: + res = self.client.service.EtiquetaEnvio(reference, 'PDF') + _logger.debug(res) + except Exception as e: + raise UserError(_( + "GLS: No response from server printing label with ref {}.\n" + "Traceback:\n{}").format(reference, e)) + res = self._recursive_asdict(res) + label = res.get("base64Binary") + return label and binascii.a2b_base64(str(label[0])) + + def _cancel_shipment(self, reference=False): + """Cancel shipment for a given reference + :param str reference -- shipping reference to cancel + :returns: dict -- result of operation with format + { + 'value': str - response message, + '_return': int - response status + } + Possible response values: + 0 -> Expedición anulada + -1 -> No existe envío + -2 -> Tiene tracking operativo + """ + xml = Raw(self._prepare_cancel_shipment_docin( + uidcustomer=self.uidcustomer, referencia=reference)) + _logger.debug(xml) + try: + response = self.client.service.Anula(docIn=xml) + _logger.debug(response) + except Exception as e: + _logger.error( + "No response from server canceling GLS ref {}.\n" + "Traceback:\n{}".format(reference, e)) + return {} + response = self._recursive_asdict(response.Servicios.Envio.Resultado) + response["gls_sent_xml"] = xml + response["_return"] = int(response["_return"]) + return response + + def _get_manifest(self, date_from): + """Get shipping manifest for a given range date + :param str date_from -- date in format "%d/%m&Y" + :returns: list of dicts with format + { + 'codplaza_pag': 771, 'codcli': 601, 'cliente': Pruebas WS + 'codplaza_org': 771, 'codexp': 468644476, 'codservicio': 74, + 'servicio': EUROBUSINESS PARCEL, 'codhorario': 3, + 'horario': BusinessParcel, 'codestado': -10, 'estado': GRABADO, + 'bultos': 1, 'kgs': 7,0, 'nombre_dst': TEST USER, + 'calle_dst': direccion, 'localidad_dst': Fontenay-Trésigny, + 'cp_dst': 77610, 'departamento_dst': , 'pais_dst': FR, + } + """ + xml = Raw(self._prepare__get_manifest_docin( + uidcustomer=self.uidcustomer, date_from=date_from)) + _logger.debug(xml) + try: + res = self.client.service.GetManifiesto(docIn=xml) + _logger.debug(res) + except Exception as e: + raise UserError(_( + "No response from server getting manifisto for GLS.\n" + "Traceback:\n{}").format(e)) + res = self._recursive_asdict(res.Servicios.Envios).get("Envio", []) + res["gls_sent_xml"] = xml + return res diff --git a/delivery_gls_asm/models/stock_picking.py b/delivery_gls_asm/models/stock_picking.py new file mode 100644 index 00000000000..9b1e2a12309 --- /dev/null +++ b/delivery_gls_asm/models/stock_picking.py @@ -0,0 +1,29 @@ +# Copyright 2020 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import _, fields, models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + # ASM API has two references for each delivery. This one is needed + # for some operations like getting the label + gls_asm_public_tracking_ref = fields.Char( + string="GLS Barcode", + readonly=True, + copy=False, + ) + + def gls_asm_get_label(self): + """Get GLS Label for this picking expedition""" + self.ensure_one() + if (self.delivery_type != "gls_asm" or not + self.gls_asm_public_tracking_ref): + return + pdf = self.carrier_id.gls_asm_get_label( + self.gls_asm_public_tracking_ref) + label_name = "gls_{}.pdf".format(self.gls_asm_public_tracking_ref) + self.message_post( + body=(_("GLS label for %s") % self.gls_asm_public_tracking_ref), + attachments=[(label_name, pdf)], + ) diff --git a/delivery_gls_asm/readme/CONFIGURE.rst b/delivery_gls_asm/readme/CONFIGURE.rst new file mode 100644 index 00000000000..bfad09825f2 --- /dev/null +++ b/delivery_gls_asm/readme/CONFIGURE.rst @@ -0,0 +1,14 @@ +Para configurar el transportista: + +#. Vaya a *Inventario > Configuración > Entrega > Método de envío* y cree uno + nuevo. +#. Escoja *GLS ASM* Como proveedor. +#. Configure los datos de servicio que tiene contratados y el producto de + envío que desea utilizar. + +Si no tiene credenciales todavía, puede poner datos inventados y dejar el +método de envío en "Entorno de prueba". Se utilizará el usuario de pruebas de +la API GLS ASM. + +Si GLS cambiase en un futuro el usuario de prueba, puede cambiarlo en los +*Parámetros del sistema* en la clave `delivery_gls_asm.api_user_demo`. diff --git a/delivery_gls_asm/readme/CONTRIBUTORS.rst b/delivery_gls_asm/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..94b6ba95366 --- /dev/null +++ b/delivery_gls_asm/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Tecnativa `_: + + * David Vidal diff --git a/delivery_gls_asm/readme/DESCRIPTION.rst b/delivery_gls_asm/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..1228d7570de --- /dev/null +++ b/delivery_gls_asm/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +Este módulo integra la API de GLS España (antigua API de ASM) con Odoo. No es +válido para integraciones de GLS en otros países, que podrían usar otras APIs. diff --git a/delivery_gls_asm/readme/INSTALL.rst b/delivery_gls_asm/readme/INSTALL.rst new file mode 100644 index 00000000000..4c250c4fc2a --- /dev/null +++ b/delivery_gls_asm/readme/INSTALL.rst @@ -0,0 +1,6 @@ +Este módulo necesita la librería python `suds` y depende igualmente de los +módulos de OCA/delivery-carrier `delivery_package_number` y `delivery_state`. + +La API de GLS/ASM no provee métodos de cálculo de precio, de modo que para poder +calcular los costes de envío sería recomendable instalar el módulo +`delivery_price_method`. diff --git a/delivery_gls_asm/readme/ROADMAP.rst b/delivery_gls_asm/readme/ROADMAP.rst new file mode 100644 index 00000000000..7a2e7416179 --- /dev/null +++ b/delivery_gls_asm/readme/ROADMAP.rst @@ -0,0 +1,4 @@ +* La API no facilita métodos para cotizar el coste real de los envíos, por lo + que siempre se cotizan a 0. Si la cotización de envíos es necesaria, + puede instalarse el módulo OCA `delivery_price_method` o bien personalizar + el método de cotización para este tipo de transportista. diff --git a/delivery_gls_asm/readme/USAGE.rst b/delivery_gls_asm/readme/USAGE.rst new file mode 100644 index 00000000000..2445f6de043 --- /dev/null +++ b/delivery_gls_asm/readme/USAGE.rst @@ -0,0 +1,62 @@ +Estas son las distintas operaciones posibles con este módulo: + +Grabar servicios +~~~~~~~~~~~~~~~~ + + #. Al confirmar el albarán, el servicio se grabará en GLS. + #. Con la respuesta, se registrará en el chatter la referencia de envío y + las etiquetas correspondientes. + #. Para gestionar los bultos del envío, se puede utilizar el campo de número + de bultos que añade `delivery_package_number` (ver el README para mayor + información) o bien el flujo nativo de Odoo con paquetes de envío. El + módulo mandará a la API de GLS/ASM el número correspondiente y podremos + descargar las etiquetas en PDF con su correspondiente numeración. + +Cancelar servicios +~~~~~~~~~~~~~~~~~~ + + #. Al igual que en otros métodos de envío, en los albaranes de salida podemos + cancelar un servicio determinado mediante la acción correspondiente en la + pestaña de *Información Adicional*, sección *Información de entrega* una + vez el pedido esté confirmado y la expedición generada. + #. Podremos generar una nueva expedición una vez cancelado si fuese necesario. + +Obtener etiquetas +~~~~~~~~~~~~~~~~~~ + + #. Si por error hubiésemos eliminado el adjunto de las etiquetas que obtuvimos + en la grabación del servicio, podemos obtenerlas de nuevo pulsando en el + botón "Etiqueta GLS" que tenemos en la parte superior de la vista + formulario del albarán. + +Seguimiento de envíos +~~~~~~~~~~~~~~~~~~~~~ + + #. El módulo está integrado con `delivery_state` para poder recabar la + información de seguimiento de nuestros envíos directamente desde la API de + GLS-ASM. + #. Para ello, vaya al albarán con un envío GLS ya grabado y en la pestaña de + *Información adicional* verá el botón *Actualizar seguimiento* para pedir + a la API de GLS que actualice el estado de este envío en Odoo. + +Manifiesto de envíos +~~~~~~~~~~~~~~~~~~~~ + + #. Para obtener el manifiesto de expediciones que firmaría el repartidor, + puede ir al menú *Inventario > Informes > Manifiesto de Envíos GLS*. + #. También puede obtener el manifiesto desde un smart button en el formulario + del transportista. + #. En el asistente, seleccione el servicio GLS del cual quiere sacar el + manifiesto y la fecha desde la que desea listar los envíos. + #. Pulse en el botón "Manifiesto GlS" para obtener un listado en PDF de los + envíos del servicio seleccionado. + +Depuración de errores +~~~~~~~~~~~~~~~~~~~~~ + + #. En cada servicio GLS-ASM dispone de una pestaña llamada "Técnico" en la + que puede consultar la última petición y respuesta a la API de GLS-ASM. + Esto le servirá como ayuda a la hora de depurar posibles errores de + comunicación. + #. También puede activar Odoo con `--log-level=debug` para refistrar las + peticiones y las respuestas en el log. diff --git a/delivery_gls_asm/static/description/icon.png b/delivery_gls_asm/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..84c81ec42421dff8ae06546115f088975c32f9ca GIT binary patch literal 4444 zcmd5=S5y;Pvq+BaqxKaX0mw>cTr1vVl6FNjgl~6@`009vp^xgs@iXcQK zq4yp_7YIcHyxi~i^FH6lKC{;O+H3DwGjq-xJ*YY(J%}Cv05EDiS2dtu@PBoUj&jO4 zO5rGQ-RHTPKLBvE_rIe0?)}M;a>*G0F%5X({W2iP&d&)D6cqH>)yv)A!Oq9&vA3Ud z-i{my0Ju%mP*pYzMs4SZ1h5))z3R5EhaDwF3p?5kLa)VsV`8E;bL8ZP;DV16(dF~3WRbn zi7c&FKB0&S{QW$F`aD2R z?o1k{1Ck2Q*KSdcthCWN)Y?n*b>~5p2 zBCou+$n>|I3Z=P;x5OL9Nj8oTi@jJRssi-wH}Q}aI0{J3<+-2z zNcRKH{8RWnrnJ|Hv-b9Ofv4!wh6ZG+9=y0Xs{dDmjeHaf;ynCNxShlyvRx3~6_nk} zAR0Gva$xenCX6-9LJ^*!Nn6tmE3|4WOZZi{jVxIy{PaP2T2txOExSdk2W4vihHA^@ zZ^1vi5Kc#?^QrLua(+Ik z+aXBz^^J|@$!Y@uNa5skGgni{m{fr`JLaa=7QHdQ?GDTtz|Y@7b{pgoEKM^3C;19` znipq=d9&>@x2n`ZfK|pqX7wKJw(UQm^2f91Y**pZ+hV$&5khAhNUG<&tLD@~(x#oN zKXdcG#ReT0;fdVVy`>XCF77cmui55+;C57-I7cY!mK-xd%&OLgPm93qJ18^#bkuN! zM9cdUi@o<)L0fEFXs|`*;jw`#Em97gm-|$VBb4T0$^dksVOuLCeE19{s6fEMCaS*1 zeLI9?k|nF><#$x7HWo{-9MpC5(=B)l_n&23MO`vBs zl)BV;6LK)v&-LXp;y~h9-Up*KZr4I{c6O+tqdQVhoKAb}v~zQ$g2y`2g?HJ&Z6?!M zKV*Jct<=D8R(0`L)9Es=r%DPyxd$ZWW$oC2X*3)xxiLnS`sg=8iX)VNsD>F+&A55I zKeIm#ISva6*;`5o`T8}wmV7EwOcbsYY9*=Iz&-q4(ke%`3*mH_d!KpQo+8d?-WlzT zg(HQ{e`^fr)6lun;JGJ)41B`OLxqVYu@fGOVSR>I&dC^BH2Lj|rhtHeH`e24yE{%( zL;Bh$qdpzumwUwmT(YKLesYHd;$KGzPSxLCS{}u+c!ko*_AdMm9Fsqne9_nX=vW(; z+N+f46mRgUbXu#XR*T7f`{>9Uk8_}P_-=nbZ+&P*7YY9*=+}Jd0p|Yfpyd^qO~-Yu z+I6qAwo-Rrgym=LNwWjgX@-}gRQrqKG9TI}BHVTj8>IL~y$rSItBOCgi)P@3{`kO zW>iNi6*cvn{`Vf@Y`oqG9eQG94)j*IVC0oQd+3mExk(2IfT4r`=D*pJ;py$an-qw* z1}(U_GIi@a57kGM7Y_%&l@3V79_4OyeeTwy8FZ0&3;*JKz4=3XMH&g+%|7ES0m`Qj zlm;RriBZ0)v5o2ZhVFA~l%<@D@1NEXX~~8h0~aj%Tms1phYugB#%J#t|`%sxwR(Hj%5Z8Ev%4mRGd$3?rlZeMm?L1ecwnh@u7Mij{ zOs5=&tninYaH5$=)je?f)U%kBl(L13ca1JR4nNHvGIGw*aViigOmtVip$Lyzud2t3+v}q<98+{2gn1N4 zmAo&ni)um#K84-Pid8z|09Il(maExc?nhMnjQT#5nP2L4FLeBq=S-OBr+uE#WD_d1 zL3Z73#FW{pLDg z|7e*&ABiXrT7iM$Fzq&%H-T5b0eiyRou#LbZb8b};aw?QOY5iZXE!kkC##G zCPV%l8ucG4>eEQ>fesQN%6t;FdA3G;DT#xFLH^UI=GzzC{D)RuwCjTwoC zqSD!P&#TOnf&VaN;GTb3c*%S(kCS;=CEQV{F3S85K7hg`rE;;Q&8qLVhPa6>$TKvU zgav^tFrO-q362mkKA|Yr?uD6JpjPphDOXo^_~z=mnv9uYZ>P;A@-Wf#k*( z>0R$yXc;PFx3Lk;t24H0_oA$DzGGJi`wCcTAaLq8{(^y*$#w3CpcpxHb$8og3^gqG zr_7Auj@Q%nx+6<*p-YnFZq;n>R-0Mp#aM)tD^G+EH^s#zFDbq}8Mf{neXE`)4h1iM zOH4Ou{qv%&kV+_++|*mSa^*pps_!L2gM7aFR5b+|&#J>ty2}b=jw+#6q#eay%Y; z#-bGA~=I=JY~eiBt}vMzj(DReJoUodF<5M$fIke`#KY-1J`3+jQQcjKjF$cBaUr($rqrkYbtckxu$#Lq|V3 z3&DqTS8$Xa?yXyf>$l_4}=i)#?7p3-Rf0G0FHxP|bSH zv;HN4@QzE)f{-2Kk5Dc3QUlz~h}{Jz*C@DcYp+OrtxX{b48L1=D<9w@b0 z|JWMp?>6VqLjdV%wF*(nD+@|=5E=tRQ|y;h_aXF{>i3D8NF6TO_?VR0ukE+k-dZ#w zur}n^!wyUOVW0NuO?@gmwFk?Q56z48ZWrE${{3|KL0NWeV`SGUANd@EC3bX#eX6Ke z)IN5zRk~gvBb2`K&V`kpwq-U=B-d+`pibkA6Jn+Bvw4d8)hy!lrKwkXA8&ThwU47q zK>p2q^ZYpj0gCJ!4ck0s2F?aij~arfti1Q#7Aw3RNyUbO!Q=r>fP_S&zHx=q(gXYy zh>2+o-AiHapAlTrjI?CNmhZCx5R0zb+HLA_fqLRQRJHgmKT%P}<}!?~D2;$rf~hAV2^?bM-<0s8vX zx_d@8h$OXaNoR@sBGIm!7R2@10tuem@Bht`&d?lCFMPZfuO4gxua9q zUiBkLPbf7T2__;T8JK-Qb+R5sz23p_$xss=qjFV+^#QsUi$vGI&+Qg35WX+Pu#XZGZb}`eiD)ekEP?ux!LVM2SRRFNxFR6x-jzx= zdCqJ4!W;mjLlJ*9@q6XoeRF+`XPzrpSlNvmf)_g)n-VTBuape;CyV-rEX)N}Uil}p z9%?Sp7#IOVY#^=f4zfuo< znd6ffiyB_&y1Vm*w5^6`_@l@y8DGD~?yqe=#eU~j2d!RjXBO G5&r}CSG}zO literal 0 HcmV?d00001 diff --git a/delivery_gls_asm/static/description/icon.svg b/delivery_gls_asm/static/description/icon.svg new file mode 100644 index 00000000000..bca2a61d9dd --- /dev/null +++ b/delivery_gls_asm/static/description/icon.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + diff --git a/delivery_gls_asm/static/description/index.html b/delivery_gls_asm/static/description/index.html new file mode 100644 index 00000000000..7fb54d499d2 --- /dev/null +++ b/delivery_gls_asm/static/description/index.html @@ -0,0 +1,551 @@ + + + + + + +Delivery GLS-ASM + + + +
+

Delivery GLS-ASM

+ + +

Beta License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runbot

+

Este módulo integra la API de GLS España (antigua API de ASM) con Odoo. No es +válido para integraciones de GLS en otros países, que podrían usar otras APIs.

+

Table of contents

+ +
+

Installation

+

Este módulo necesita la librería python suds y depende igualmente de los +módulos de OCA/delivery-carrier delivery_package_number y delivery_state.

+

La API de GLS/ASM no provee métodos de cálculo de precio, de modo que para poder +calcular los costes de envío sería recomendable instalar el módulo +delivery_price_method.

+
+
+

Configuration

+

Para configurar el transportista:

+
    +
  1. Vaya a Inventario > Configuración > Entrega > Método de envío y cree uno +nuevo.
  2. +
  3. Escoja GLS ASM Como proveedor.
  4. +
  5. Configure los datos de servicio que tiene contratados y el producto de +envío que desea utilizar.
  6. +
+

Si no tiene credenciales todavía, puede poner datos inventados y dejar el +método de envío en “Entorno de prueba”. Se utilizará el usuario de pruebas de +la API GLS ASM.

+

Si GLS cambiase en un futuro el usuario de prueba, puede cambiarlo en los +Parámetros del sistema en la clave delivery_gls_asm.api_user_demo.

+
+
+

Usage

+

Estas son las distintas operaciones posibles con este módulo:

+
+

Grabar servicios

+
+
    +
  1. Al confirmar el albarán, el servicio se grabará en GLS.
  2. +
  3. Con la respuesta, se registrará en el chatter la referencia de envío y +las etiquetas correspondientes.
  4. +
  5. Para gestionar los bultos del envío, se puede utilizar el campo de número +de bultos que añade delivery_package_number (ver el README para mayor +información) o bien el flujo nativo de Odoo con paquetes de envío. El +módulo mandará a la API de GLS/ASM el número correspondiente y podremos +descargar las etiquetas en PDF con su correspondiente numeración.
  6. +
+
+
+
+

Cancelar servicios

+
+
    +
  1. Al igual que en otros métodos de envío, en los albaranes de salida podemos +cancelar un servicio determinado mediante la acción correspondiente en la +pestaña de Información Adicional, sección Información de entrega una +vez el pedido esté confirmado y la expedición generada.
  2. +
  3. Podremos generar una nueva expedición una vez cancelado si fuese necesario.
  4. +
+
+
+
+

Obtener etiquetas

+
+
    +
  1. Si por error hubiésemos eliminado el adjunto de las etiquetas que obtuvimos +en la grabación del servicio, podemos obtenerlas de nuevo pulsando en el +botón “Etiqueta GLS” que tenemos en la parte superior de la vista +formulario del albarán.
  2. +
+
+
+
+

Seguimiento de envíos

+
+
    +
  1. El módulo está integrado con delivery_state para poder recabar la +información de seguimiento de nuestros envíos directamente desde la API de +GLS-ASM.
  2. +
  3. Para ello, vaya al albarán con un envío GLS ya grabado y en la pestaña de +Información adicional verá el botón Actualizar seguimiento para pedir +a la API de GLS que actualice el estado de este envío en Odoo.
  4. +
+
+
+
+

Manifiesto de envíos

+
+
    +
  1. Para obtener el manifiesto de expediciones que firmaría el repartidor, +puede ir al menú Inventario > Informes > Manifiesto de Envíos GLS.
  2. +
  3. También puede obtener el manifiesto desde un smart button en el formulario +del transportista.
  4. +
  5. En el asistente, seleccione el servicio GLS del cual quiere sacar el +manifiesto y la fecha desde la que desea listar los envíos.
  6. +
  7. Pulse en el botón “Manifiesto GlS” para obtener un listado en PDF de los +envíos del servicio seleccionado.
  8. +
+
+
+
+

Depuración de errores

+
+
    +
  1. En cada servicio GLS-ASM dispone de una pestaña llamada “Técnico” en la +que puede consultar la última petición y respuesta a la API de GLS-ASM. +Esto le servirá como ayuda a la hora de depurar posibles errores de +comunicación.
  2. +
  3. También puede activar Odoo con –log-level=debug para refistrar las +peticiones y las respuestas en el log.
  4. +
+
+
+
+
+

Known issues / Roadmap

+
    +
  • La API no facilita métodos para cotizar el coste real de los envíos, por lo +que siempre se cotizan a 0. Si la cotización de envíos es necesaria, +puede instalarse el módulo OCA delivery_price_method o bien personalizar +el método de cotización para este tipo de transportista.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/l10n-spain project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/delivery_gls_asm/tests/__init__.py b/delivery_gls_asm/tests/__init__.py new file mode 100644 index 00000000000..40bbcefad4c --- /dev/null +++ b/delivery_gls_asm/tests/__init__.py @@ -0,0 +1 @@ +from . import test_delivery_gls_asm diff --git a/delivery_gls_asm/tests/test_delivery_gls_asm.py b/delivery_gls_asm/tests/test_delivery_gls_asm.py new file mode 100644 index 00000000000..b3ba725401a --- /dev/null +++ b/delivery_gls_asm/tests/test_delivery_gls_asm.py @@ -0,0 +1,105 @@ +# Copyright 2020 Tecnativa - David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from unittest import mock +from odoo.tests import common, Form + +# We could rely on test user to make the tests, although we would rely on +# the service stability wich could break CIs +# It's better to mock the interface response and to test +# Odoo flows regressions. +_mock_class = ( + "odoo.addons.delivery_gls_asm.models.gls_asm_request.GlsAsmRequest") + + +class TestDeliveryGlsAsm(common.SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.shipping_product = cls.env['product.product'].create({ + 'type': 'service', + 'name': 'Test Shipping costs', + 'list_price': 10.0, + }) + cls.carrier_gls_asm = cls.env['delivery.carrier'].create({ + 'name': 'GLS ASM', + 'delivery_type': 'gls_asm', + 'product_id': cls.shipping_product.id, + 'prod_environment': False, + }) + cls.product = cls.env['product.product'].create({ + 'type': 'product', + 'name': 'Test product', + }) + cls.partner = cls.env['res.partner'].create({ + 'name': 'Mr. Odoo', + 'city': 'Odoo Ville', + 'zip': '28001', + 'street': 'Calle de La Rua, 3', + }) + cls.partner_wh = cls.env['res.partner'].create({ + 'name': 'WH Test Partner', + 'city': 'Odoo City', + 'zip': '08001', + 'street': 'Strasse Street, 1', + }) + order_form = Form( + cls.env['sale.order'].with_context(tracking_disable=True)) + order_form.partner_id = cls.partner + order_form.carrier_id = cls.carrier_gls_asm + with order_form.order_line.new() as line: + line.product_id = cls.product + line.product_uom_qty = 20.0 + cls.sale_order = order_form.save() + cls.sale_order.action_confirm() + cls.picking = cls.sale_order.picking_ids + cls.picking.move_lines.quantity_done = 20 + + def test_01_gls_picking_confirm_simple(self): + """The picking is confirm and the shipping is recorded to GLS""" + mocked_response = { + "_codexp": "TEST123456789", + "_codbarras": "1234567890123", + "_return": 0, + } + with mock.patch( + _mock_class + '._send_shipping', + return_value=mocked_response, + ): + self.picking.button_validate() + self.assertEqual(self.picking.carrier_tracking_ref, "TEST123456789") + self.assertEqual( + self.picking.gls_asm_public_tracking_ref, "1234567890123") + # Cancel the expedition. The tracking refs go away + mocked_response = { + "_return": 0, + } + with mock.patch( + _mock_class + '._cancel_shipment', + return_value=mocked_response, + ): + self.picking.cancel_shipment() + self.assertFalse(self.picking.gls_asm_public_tracking_ref) + self.assertFalse(self.picking.carrier_tracking_ref) + + def test_02_gls_manifest(self): + """Mock manifest response""" + mocked_response = [{ + 'cliente': "Pruebas WS", + 'codexp': "467247191", + 'bultos': "1", + 'kgs': "1,0", + 'nombre_dst': "Mr. Odoo", + 'calle_dst': "Test Address", + 'localidad_dst': "Test location", + 'cp_dst': "28001", + }] + wizard = self.env["gls.asm.minifest.wizard"].create({ + "carrier_id": self.carrier_gls_asm.id, + "date_from": "2020-05-31", + }) + with mock.patch( + _mock_class + '._get_manifest', + return_value=mocked_response, + ): + report = wizard.get_manifest() + self.assertEqual(report["data"]["deliveries"], mocked_response) diff --git a/delivery_gls_asm/views/delivery_asm_view.xml b/delivery_gls_asm/views/delivery_asm_view.xml new file mode 100644 index 00000000000..d7b56d5c014 --- /dev/null +++ b/delivery_gls_asm/views/delivery_asm_view.xml @@ -0,0 +1,58 @@ + + + + + delivery.carrier + + + + + + + + + + + + + + + + + + + + + + + + + +