diff --git a/README.md b/README.md index 8b37f5e390..233a93b962 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ addon | version | maintainers | summary [base_wamas_ubl](base_wamas_ubl/) | 16.0.1.17.0 | | Base module to aggregate WAMAS - UBL features. [despatch_advice_import](despatch_advice_import/) | 16.0.1.2.0 | | Despatch Advice import [despatch_advice_import_ubl](despatch_advice_import_ubl/) | 16.0.1.1.0 | | Import Despatch Advice files +[edi_voxel_oca](edi_voxel_oca/) | 16.0.1.0.0 | [![macagua](https://github.com/macagua.png?size=30px)](https://github.com/macagua) | Base module for connecting with Voxel [pdf_helper](pdf_helper/) | 16.0.1.1.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![alexis-via](https://github.com/alexis-via.png?size=30px)](https://github.com/alexis-via) | Provides helpers to work w/ PDFs [sale_order_import](sale_order_import/) | 16.0.1.2.0 | | Import RFQ or sale orders from files [sale_order_import_edifact](sale_order_import_edifact/) | 16.0.1.1.0 | [![rmorant](https://github.com/rmorant.png?size=30px)](https://github.com/rmorant) | EDIFACT/D96A Order diff --git a/edi_voxel_oca/README.rst b/edi_voxel_oca/README.rst new file mode 100644 index 0000000000..4e9aa8fbe6 --- /dev/null +++ b/edi_voxel_oca/README.rst @@ -0,0 +1,96 @@ +===== +Voxel +===== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e630ee4dfa257b27f977ff0dbb9e843ff9e6e403cd6914ea293366dec54c1460 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png + :target: https://odoo-community.org/page/development-status + :alt: Production/Stable +.. |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%2Fedi-lightgray.png?logo=github + :target: https://github.com/OCA/edi/tree/16.0/edi_voxel_oca + :alt: OCA/edi +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/edi-16-0/edi-16-0-edi_voxel_oca + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/edi&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This is a base module that allows you to send and receive documents +such as Invoices, Sales Orders, Delivery Orders in XML format using +the baVel electronic platform belonging to Voxel Group. + +Voxel Group is a company that offers leading solutions for B2B payments, +eInvoicing, VAT refund and supply chain via its baVel Platform. For more +information visit `https://www.voxelgroup.net/ `_. + +This module doesn't do anything useful by itself, but it is used by other modules: + +* *edi_voxel_account_invoice* to send invoices to Voxel. +* *edi_voxel_stock_picking* to send delivery orders to Voxel. +* *edi_voxel_sale_order_import* to import a sale order received from Voxel. + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa +* Guavana + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_: + + * Ernesto Tejeda + * Pedro M. Baeza + +* `Guavana `_: + + * Leonardo J. Caballero G. + +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/edi `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/edi_voxel_oca/__init__.py b/edi_voxel_oca/__init__.py new file mode 100644 index 0000000000..69f7babdfb --- /dev/null +++ b/edi_voxel_oca/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models diff --git a/edi_voxel_oca/__manifest__.py b/edi_voxel_oca/__manifest__.py new file mode 100644 index 0000000000..7d2eb1961c --- /dev/null +++ b/edi_voxel_oca/__manifest__.py @@ -0,0 +1,35 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Voxel", + "summary": "Base module for connecting with Voxel", + "version": "16.0.1.0.0", + "development_status": "Production/Stable", + "category": "Hidden", + "author": "Tecnativa, Guavana, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/edi", + "license": "AGPL-3", + "depends": [ + "account", + "product", + "report_xml", + "base_iso3166", + "queue_job", + "product_supplierinfo_for_customer", + ], + "data": [ + "security/voxel_security.xml", + "security/ir.model.access.csv", + "data/data_voxel_uom.xml", + "data/queue_job_channel_data.xml", + "views/res_company_view.xml", + "views/account_tax_views.xml", + "views/product_uom_views.xml", + "views/res_config_settings_views.xml", + "views/res_partner_views.xml", + "views/template_voxel_report.xml", + "views/voxel_login_views.xml", + ], + "installable": True, +} diff --git a/edi_voxel_oca/data/data_voxel_uom.xml b/edi_voxel_oca/data/data_voxel_uom.xml new file mode 100644 index 0000000000..b84de93b39 --- /dev/null +++ b/edi_voxel_oca/data/data_voxel_uom.xml @@ -0,0 +1,23 @@ + + + + + Unidades + + + Kgs + + + Horas + + + Metros + + + Lts + + + Lbs + + diff --git a/edi_voxel_oca/data/queue_job_channel_data.xml b/edi_voxel_oca/data/queue_job_channel_data.xml new file mode 100644 index 0000000000..a92959d67c --- /dev/null +++ b/edi_voxel_oca/data/queue_job_channel_data.xml @@ -0,0 +1,17 @@ + + + + + voxel_export + + + + voxel_import + + + + voxel_status + + + diff --git a/edi_voxel_oca/i18n/edi_voxel.pot b/edi_voxel_oca/i18n/edi_voxel.pot new file mode 100644 index 0000000000..929dae5223 --- /dev/null +++ b/edi_voxel_oca/i18n/edi_voxel.pot @@ -0,0 +1,444 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * edi_voxel +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__exento +msgid "(EXENTO) Exento" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__iba +msgid "(IBA) Impuesto sobre bebidas alcohólicas" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__icio +msgid "(ICIO) Impuesto sobre las construcciones, instalaciones y obras" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__ie +msgid "(IE) Impuestos especiales" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__iecdpcac +msgid "" +"(IECDPCAC) Impuesto especial sobre los combustibles derivados del petróleo " +"en la comunidad Autónoma Canaria" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__igic +msgid "(IGIC) IGIC" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__igtecm +msgid "" +"(IGTECM) Impuesto general sobre el tráfico de empresas que se aplica en " +"Ceuta y Melilla" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__ihc +msgid "(IHC) Impuesto sobre harinas cárnicas" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__iiimab +msgid "" +"(IIIMAB) Impuesto sobre las instalaciones que inciden sobre le medio " +"ambiente en las Baleares" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__imgsn +msgid "(IMGSN) Impuesto municipal sobre gastos suntuarios en Navarra" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__impn +msgid "(IMPN) Impuesto municipal sobre publicidad en Navarra" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__imsn +msgid "(IMSN) Impuesto municipal sobre solares en Navarra" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__imvdn +msgid "(IMVDN) Impuesto municipal sobre las viviendas desocupadas en Navarra" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__irpf +msgid "(IRPF) IRPF" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__itpajd +msgid "" +"(ITPAJD) Impuesto sobre transmisiones patrimoniales y actos jurídicos " +"documentados" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__iva +msgid "(IVA) IVA" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__otro +msgid "(OTRO) Otro" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__ra +msgid "(RA) Renta aduanas" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__account_tax__voxel_tax_code__re +msgid "(RE) Recargo de equivalencia" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.res_config_settings_view_form +msgid "" +"Send mode\n" +" " +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.res_config_settings_view_form +msgid "" +"Web Sevice credentials\n" +" " +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__res_company__voxel_send_mode__fixed +msgid "At fixed time" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__cajas +msgid "Boxes" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__voxel_mixin__voxel_state__cancelled +msgid "Cancelled" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.res_config_settings_view_form +msgid "Choose the send mode for documents to Voxel" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_res_company +msgid "Companies" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__company_id +msgid "Company" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.view_company_form +msgid "Configuration" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_res_partner +msgid "Contact" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__contenedores +msgid "Containers" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__create_uid +msgid "Created by" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__create_date +msgid "Created on" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_res_company__voxel_delay_time +#: model:ir.model.fields,field_description:edi_voxel.field_res_config_settings__voxel_delay_time +msgid "Delay time" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__display_name +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin__display_name +msgid "Display Name" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_res_company__voxel_enabled +#: model:ir.model.fields,field_description:edi_voxel.field_res_partner__voxel_enabled +#: model:ir.model.fields,field_description:edi_voxel.field_res_users__voxel_enabled +msgid "Enable Voxel" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__horas +msgid "Hours" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__id +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin__id +msgid "ID" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,help:edi_voxel.field_voxel_mixin__voxel_state +msgid "Indicates the status of sending report to Voxel" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__kgs +msgid "Kgs" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login____last_update +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin____last_update +msgid "Last Modified on" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__write_date +msgid "Last Updated on" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__lbs +msgid "Lbs" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__lts +msgid "Liters" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.view_company_form +msgid "Logins" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__metros +msgid "Meters" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.res_config_settings_view_form +msgid "Mode" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__name +msgid "Name" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__voxel_mixin__voxel_state__not_sent +msgid "Not sent" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__res_company__voxel_send_mode__auto +msgid "On validate" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__otros +msgid "Others" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__bultos +msgid "Packages" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__palets +msgid "Pallets" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__password +msgid "Password" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin__processing_error +#: model:ir.model.fields.selection,name:edi_voxel.selection__voxel_mixin__voxel_state__processing_error +msgid "Processing error" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_uom_uom +msgid "Product Unit of Measure" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_res_company__voxel_send_mode +#: model:ir.model.fields,field_description:edi_voxel.field_res_config_settings__voxel_send_mode +msgid "Send mode" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__voxel_mixin__voxel_state__sent_errors +msgid "Sending error" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__voxel_mixin__voxel_state__accepted +msgid "Sent and accepted" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__voxel_mixin__voxel_state__sent +msgid "Sent not verified" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_res_company__voxel_sent_time +#: model:ir.model.fields,field_description:edi_voxel.field_res_config_settings__voxel_sent_time +msgid "Sent time" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.res_config_settings_view_form +msgid "Set credentials for connection to Voxel using Web Service" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__metroscuadrados +msgid "Square meters" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_account_tax +msgid "Tax" +msgstr "" + +#. module: edi_voxel +#: code:addons/edi_voxel/models/voxel_mixin.py:0 +#, python-format +msgid "" +"This operation cannot be performed because there are jobs running therefore " +"cannot be unlinked." +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__url +msgid "URL" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__uom_uom__voxel_code__unidades +msgid "Units" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_login__user +msgid "User" +msgstr "" + +#. module: edi_voxel +#: model_terms:ir.ui.view,arch_db:edi_voxel.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:edi_voxel.view_company_form +msgid "Voxel" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_uom_uom__voxel_code +msgid "Voxel Code" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_account_tax__voxel_tax_code +msgid "Voxel Tax Code" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin__voxel_filename +msgid "Voxel filename" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_voxel_login +msgid "Voxel login" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_res_company__voxel_login_ids +msgid "Voxel logins" +msgstr "" + +#. module: edi_voxel +#: model:res.groups,name:edi_voxel.group_voxel_manager +msgid "Voxel manager" +msgstr "" + +#. module: edi_voxel +#: model:ir.model,name:edi_voxel.model_voxel_mixin +msgid "Voxel mixin" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin__voxel_state +msgid "Voxel send state" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields.selection,name:edi_voxel.selection__res_company__voxel_send_mode__delayed +msgid "With delay" +msgstr "" + +#. module: edi_voxel +#: model:ir.model.fields,field_description:edi_voxel.field_voxel_mixin__voxel_xml_report +msgid "XML Report" +msgstr "" diff --git a/edi_voxel_oca/i18n/edi_voxel_oca.pot b/edi_voxel_oca/i18n/edi_voxel_oca.pot new file mode 100644 index 0000000000..7169d8a318 --- /dev/null +++ b/edi_voxel_oca/i18n/edi_voxel_oca.pot @@ -0,0 +1,463 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * edi_voxel_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__exento +msgid "(EXENTO) Exento" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iba +msgid "(IBA) Impuesto sobre bebidas alcohólicas" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__icio +msgid "(ICIO) Impuesto sobre las construcciones, instalaciones y obras" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__ie +msgid "(IE) Impuestos especiales" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iecdpcac +msgid "" +"(IECDPCAC) Impuesto especial sobre los combustibles derivados del petróleo " +"en la comunidad Autónoma Canaria" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__igic +msgid "(IGIC) IGIC" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__igtecm +msgid "" +"(IGTECM) Impuesto general sobre el tráfico de empresas que se aplica en " +"Ceuta y Melilla" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__ihc +msgid "(IHC) Impuesto sobre harinas cárnicas" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iiimab +msgid "" +"(IIIMAB) Impuesto sobre las instalaciones que inciden sobre le medio " +"ambiente en las Baleares" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__imgsn +msgid "(IMGSN) Impuesto municipal sobre gastos suntuarios en Navarra" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__impn +msgid "(IMPN) Impuesto municipal sobre publicidad en Navarra" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__imsn +msgid "(IMSN) Impuesto municipal sobre solares en Navarra" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__imvdn +msgid "(IMVDN) Impuesto municipal sobre las viviendas desocupadas en Navarra" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__irpf +msgid "(IRPF) IRPF" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__itpajd +msgid "" +"(ITPAJD) Impuesto sobre transmisiones patrimoniales y actos jurídicos " +"documentados" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iva +msgid "(IVA) IVA" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__otro +msgid "(OTRO) Otro" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__ra +msgid "(RA) Renta aduanas" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__re +msgid "(RE) Recargo de equivalencia" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "" +"Send mode\n" +" " +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "" +"Web Sevice credentials\n" +" " +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__res_company__voxel_send_mode__fixed +msgid "At fixed time" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__cajas +msgid "Boxes" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__cancelled +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__cancelled +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__cancelled +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__cancelled +msgid "Cancelled" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "Choose the send mode for documents to Voxel" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_res_company +msgid "Companies" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__company_id +msgid "Company" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.view_company_form +msgid "Configuration" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_res_partner +msgid "Contact" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__contenedores +msgid "Containers" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__create_uid +msgid "Created by" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__create_date +msgid "Created on" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_delay_time +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_config_settings__voxel_delay_time +msgid "Delay time" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__display_name +msgid "Display Name" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_enabled +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_partner__voxel_enabled +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_users__voxel_enabled +msgid "Enable Voxel" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__horas +msgid "Hours" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__id +msgid "ID" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,help:edi_voxel_oca.field_voxel_mixin__voxel_state +msgid "Indicates the status of sending report to Voxel" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__kgs +msgid "Kgs" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login____last_update +msgid "Last Modified on" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__write_date +msgid "Last Updated on" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__lbs +msgid "Lbs" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__lts +msgid "Liters" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.view_company_form +msgid "Logins" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__metros +msgid "Meters" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "Mode" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__name +msgid "Name" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__not_sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__not_sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__not_sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__not_sent +msgid "Not sent" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__res_company__voxel_send_mode__auto +msgid "On validate" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__otros +msgid "Others" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__bultos +msgid "Packages" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__palets +msgid "Pallets" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__password +msgid "Password" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__processing_error +msgid "Processing Error" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__processing_error +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__processing_error +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__processing_error +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__processing_error +msgid "Processing error" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_uom_uom +msgid "Product Unit of Measure" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_send_mode +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_config_settings__voxel_send_mode +msgid "Send mode" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__sent_errors +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__sent_errors +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__sent_errors +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__sent_errors +msgid "Sending error" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__accepted +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__accepted +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__accepted +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__accepted +msgid "Sent and accepted" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__sent +msgid "Sent not verified" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_sent_time +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_config_settings__voxel_sent_time +msgid "Sent time" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "Set credentials for connection to Voxel using Web Service" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__metroscuadrados +msgid "Square meters" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_account_tax +msgid "Tax" +msgstr "" + +#. module: edi_voxel_oca +#: code:addons/edi_voxel_oca/models/voxel_mixin.py:0 +#, python-format +msgid "" +"This operation cannot be performed because there are jobs running therefore " +"cannot be unlinked." +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__url +msgid "URL" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__unidades +msgid "Units" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__user +msgid "User" +msgstr "" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.view_company_form +msgid "Voxel" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_uom_uom__voxel_code +msgid "Voxel Code" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__voxel_filename +msgid "Voxel Filename" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_account_tax__voxel_tax_code +msgid "Voxel Tax Code" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_voxel_login +msgid "Voxel login" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_login_ids +msgid "Voxel logins" +msgstr "" + +#. module: edi_voxel_oca +#: model:res.groups,name:edi_voxel_oca.group_voxel_manager +msgid "Voxel manager" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_voxel_mixin +msgid "Voxel mixin" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__voxel_state +msgid "Voxel send state" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__res_company__voxel_send_mode__delayed +msgid "With delay" +msgstr "" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__voxel_xml_report +msgid "XML Report" +msgstr "" diff --git a/edi_voxel_oca/i18n/es.po b/edi_voxel_oca/i18n/es.po new file mode 100644 index 0000000000..ca47a15a76 --- /dev/null +++ b/edi_voxel_oca/i18n/es.po @@ -0,0 +1,490 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * edi_voxel +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-04-03 16:24+0000\n" +"PO-Revision-Date: 2023-11-15 14:36+0000\n" +"Last-Translator: Ivorra78 \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: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__exento +msgid "(EXENTO) Exento" +msgstr "(EXENTO) Exento" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iba +msgid "(IBA) Impuesto sobre bebidas alcohólicas" +msgstr "(IBA) Impuesto sobre bebidas alcohólicas" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__icio +msgid "(ICIO) Impuesto sobre las construcciones, instalaciones y obras" +msgstr "(ICIO) Impuesto sobre las construcciones, instalaciones y obras" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__ie +msgid "(IE) Impuestos especiales" +msgstr "(IE) Impuestos especiales" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iecdpcac +msgid "" +"(IECDPCAC) Impuesto especial sobre los combustibles derivados del petróleo " +"en la comunidad Autónoma Canaria" +msgstr "" +"(IECDPCAC) Impuesto especial sobre los combustibles derivados del petróleo " +"en la comunidad Autónoma Canaria" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__igic +msgid "(IGIC) IGIC" +msgstr "(IGIC) IGIC" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__igtecm +msgid "" +"(IGTECM) Impuesto general sobre el tráfico de empresas que se aplica en " +"Ceuta y Melilla" +msgstr "" +"(IGTECM) Impuesto general sobre el tráfico de empresas que se aplica en " +"Ceuta y Melilla" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__ihc +msgid "(IHC) Impuesto sobre harinas cárnicas" +msgstr "(IHC) Impuesto sobre harinas cárnicas" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iiimab +msgid "" +"(IIIMAB) Impuesto sobre las instalaciones que inciden sobre le medio " +"ambiente en las Baleares" +msgstr "" +"(IIIMAB) Impuesto sobre las instalaciones que inciden sobre le medio " +"ambiente en las Baleares" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__imgsn +msgid "(IMGSN) Impuesto municipal sobre gastos suntuarios en Navarra" +msgstr "(IMGSN) Impuesto municipal sobre gastos suntuarios en Navarra" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__impn +msgid "(IMPN) Impuesto municipal sobre publicidad en Navarra" +msgstr "(IMPN) Impuesto municipal sobre publicidad en Navarra" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__imsn +msgid "(IMSN) Impuesto municipal sobre solares en Navarra" +msgstr "(IMSN) Impuesto municipal sobre solares en Navarra" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__imvdn +msgid "(IMVDN) Impuesto municipal sobre las viviendas desocupadas en Navarra" +msgstr "(IMVDN) Impuesto municipal sobre las viviendas desocupadas en Navarra" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__irpf +msgid "(IRPF) IRPF" +msgstr "(IRPF) IRPF" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__itpajd +msgid "" +"(ITPAJD) Impuesto sobre transmisiones patrimoniales y actos jurídicos " +"documentados" +msgstr "" +"(ITPAJD) Impuesto sobre transmisiones patrimoniales y actos jurídicos " +"documentados" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__iva +msgid "(IVA) IVA" +msgstr "(IVA) IVA" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__otro +msgid "(OTRO) Otro" +msgstr "(OTRO) Otro" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__ra +msgid "(RA) Renta aduanas" +msgstr "(RA) Renta aduanas" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_tax__voxel_tax_code__re +msgid "(RE) Recargo de equivalencia" +msgstr "(RE) Recargo de equivalencia" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "" +"Send mode\n" +" " +msgstr "" +"Enviar modo\n" +" " + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "" +"Web Sevice credentials\n" +" " +msgstr "" +"Credenciales del Servicio web\n" +" " + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__res_company__voxel_send_mode__fixed +msgid "At fixed time" +msgstr "A una hora fija" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__cajas +msgid "Boxes" +msgstr "Cajas" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__cancelled +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__cancelled +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__cancelled +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__cancelled +msgid "Cancelled" +msgstr "Cancelado" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "Choose the send mode for documents to Voxel" +msgstr "Escoge el modo de envío de los documentos a Voxel" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__company_id +msgid "Company" +msgstr "Compañía" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de Configuración" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.view_company_form +msgid "Configuration" +msgstr "Configuración" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_res_partner +msgid "Contact" +msgstr "Contacto" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__contenedores +msgid "Containers" +msgstr "Contenedores" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__create_date +msgid "Created on" +msgstr "Creado en" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_delay_time +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_config_settings__voxel_delay_time +msgid "Delay time" +msgstr "Tiempo de retardo" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_enabled +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_partner__voxel_enabled +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_users__voxel_enabled +msgid "Enable Voxel" +msgstr "Habilitar voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__horas +msgid "Hours" +msgstr "Horas" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__id +msgid "ID" +msgstr "ID (identificación)" + +#. module: edi_voxel_oca +#: model:ir.model.fields,help:edi_voxel_oca.field_voxel_mixin__voxel_state +msgid "Indicates the status of sending report to Voxel" +msgstr "Indica el estado del envío del reporte a Voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__kgs +msgid "Kgs" +msgstr "Kgs" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__write_uid +msgid "Last Updated by" +msgstr "Última actualización de" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__lbs +msgid "Lbs" +msgstr "Lbs" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__lts +msgid "Liters" +msgstr "Lts" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.view_company_form +msgid "Logins" +msgstr "Voxel logins" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__metros +msgid "Meters" +msgstr "Metros" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "Mode" +msgstr "Modo" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__name +msgid "Name" +msgstr "Nombre" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__not_sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__not_sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__not_sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__not_sent +msgid "Not sent" +msgstr "No enviado" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__res_company__voxel_send_mode__auto +msgid "On validate" +msgstr "Al validar" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__otros +msgid "Others" +msgstr "Otros" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__bultos +msgid "Packages" +msgstr "Bultos" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__palets +msgid "Pallets" +msgstr "Palets" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__password +msgid "Password" +msgstr "Contraseña" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__processing_error +msgid "Processing Error" +msgstr "Error de procesamiento" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__processing_error +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__processing_error +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__processing_error +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__processing_error +msgid "Processing error" +msgstr "Error de procesamiento" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_uom_uom +msgid "Product Unit of Measure" +msgstr "Unidad de medida del producto" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_queue_job +msgid "Queue Job" +msgstr "Trabajo en cola" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_send_mode +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_config_settings__voxel_send_mode +msgid "Send mode" +msgstr "Modo de envío" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__sent_errors +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__sent_errors +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__sent_errors +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__sent_errors +msgid "Sending error" +msgstr "Error de envío" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__accepted +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__accepted +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__accepted +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__accepted +msgid "Sent and accepted" +msgstr "Enviado y aceptado" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__account_move__voxel_state__sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__sale_order__voxel_state__sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__stock_picking__voxel_state__sent +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__voxel_mixin__voxel_state__sent +msgid "Sent not verified" +msgstr "Enviado sin verificar" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_sent_time +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_config_settings__voxel_sent_time +msgid "Sent time" +msgstr "Hora de envío" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +msgid "Set credentials for connection to Voxel using Web Service" +msgstr "" +"Establece las credenciales para la conexión con Voxel usando Servicio Web" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__metroscuadrados +msgid "Square meters" +msgstr "Metros Cuadrados" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_account_tax +msgid "Tax" +msgstr "Impuesto" + +#. module: edi_voxel_oca +#: code:addons/edi_voxel_oca/models/voxel_mixin.py:0 +#, python-format +msgid "" +"This operation cannot be performed because there are jobs running therefore " +"cannot be unlinked." +msgstr "" +"Esta operación no se puede realizar porque hay trabajos en ejecución, por lo " +"que no se pueden desvincular." + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__url +msgid "URL" +msgstr "URL" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__uom_uom__voxel_code__unidades +msgid "Units" +msgstr "Unidades" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_login__user +msgid "User" +msgstr "Usuario" + +#. module: edi_voxel_oca +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:edi_voxel_oca.view_company_form +msgid "Voxel" +msgstr "Voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_uom_uom__voxel_code +msgid "Voxel Code" +msgstr "Código Voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__voxel_filename +msgid "Voxel Filename" +msgstr "Nombre de archivo Voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_account_tax__voxel_tax_code +msgid "Voxel Tax Code" +msgstr "Código Voxel" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_voxel_login +msgid "Voxel login" +msgstr "Login Voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_res_company__voxel_login_ids +msgid "Voxel logins" +msgstr "Logins de Voxel" + +#. module: edi_voxel_oca +#: model:res.groups,name:edi_voxel_oca.group_voxel_manager +msgid "Voxel manager" +msgstr "Administrador Voxel" + +#. module: edi_voxel_oca +#: model:ir.model,name:edi_voxel_oca.model_voxel_mixin +msgid "Voxel mixin" +msgstr "Mezcla de voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__voxel_state +msgid "Voxel send state" +msgstr "Estado del envío a Voxel" + +#. module: edi_voxel_oca +#: model:ir.model.fields.selection,name:edi_voxel_oca.selection__res_company__voxel_send_mode__delayed +msgid "With delay" +msgstr "Con retardo" + +#. module: edi_voxel_oca +#: model:ir.model.fields,field_description:edi_voxel_oca.field_voxel_mixin__voxel_xml_report +msgid "XML Report" +msgstr "Reporte XML" diff --git a/edi_voxel_oca/models/__init__.py b/edi_voxel_oca/models/__init__.py new file mode 100644 index 0000000000..5cb4bc98cb --- /dev/null +++ b/edi_voxel_oca/models/__init__.py @@ -0,0 +1,10 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import res_company +from . import res_config_settings +from . import voxel_mixin +from . import uom_uom +from . import account +from . import queue_job +from . import res_partner +from . import voxel_login diff --git a/edi_voxel_oca/models/account.py b/edi_voxel_oca/models/account.py new file mode 100644 index 0000000000..4b8e8277a9 --- /dev/null +++ b/edi_voxel_oca/models/account.py @@ -0,0 +1,60 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AccountTax(models.Model): + _inherit = "account.tax" + + voxel_tax_code = fields.Selection( + selection=[ + ("IVA", "(IVA) IVA"), + ("IGIC", "(IGIC) IGIC"), + ("IRPF", "(IRPF) IRPF"), + ("RE", "(RE) Recargo de equivalencia"), + ( + "ITPAJD", + "(ITPAJD) Impuesto sobre transmisiones patrimoniales y " + "actos jurídicos documentados", + ), + ("IE", "(IE) Impuestos especiales"), + ("RA", "(RA) Renta aduanas"), + ( + "IGTECM", + "(IGTECM) Impuesto general sobre el tráfico de " + "empresas que se aplica en Ceuta y Melilla", + ), + ( + "IECDPCAC", + "(IECDPCAC) Impuesto especial sobre los combustibles " + "derivados del petróleo en la comunidad Autónoma " + "Canaria", + ), + ( + "IIIMAB", + "(IIIMAB) Impuesto sobre las instalaciones que inciden " + "sobre le medio ambiente en las Baleares", + ), + ( + "ICIO", + "(ICIO) Impuesto sobre las construcciones, instalaciones " "y obras", + ), + ( + "IMVDN", + "(IMVDN) Impuesto municipal sobre las viviendas " + "desocupadas en Navarra", + ), + ("IMSN", "(IMSN) Impuesto municipal sobre solares en Navarra"), + ( + "IMGSN", + "(IMGSN) Impuesto municipal sobre gastos " "suntuarios en Navarra", + ), + ("IMPN", "(IMPN) Impuesto municipal sobre publicidad en Navarra"), + ("IBA", "(IBA) Impuesto sobre bebidas alcohólicas"), + ("IHC", "(IHC) Impuesto sobre harinas cárnicas"), + ("EXENTO", "(EXENTO) Exento"), + ("OTRO", "(OTRO) Otro"), + ], + ) diff --git a/edi_voxel_oca/models/queue_job.py b/edi_voxel_oca/models/queue_job.py new file mode 100644 index 0000000000..63c7c4fe07 --- /dev/null +++ b/edi_voxel_oca/models/queue_job.py @@ -0,0 +1,21 @@ +# Copyright 2017 Tecnativa - Pedro M. Baeza +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import models + + +class QueueJob(models.Model): + _inherit = "queue.job" + + def voxel_do_now(self): + self.sudo().write({"eta": False}) + + def voxel_cancel_now(self): + self.sudo().filtered( + lambda x: x.state in ["pending", "enqueued", "failed"] + ).unlink() + + def voxel_requeue_sudo(self): + self.sudo().requeue() diff --git a/edi_voxel_oca/models/res_company.py b/edi_voxel_oca/models/res_company.py new file mode 100644 index 0000000000..1cd4433d48 --- /dev/null +++ b/edi_voxel_oca/models/res_company.py @@ -0,0 +1,49 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from datetime import datetime, timedelta + +import pytz + +from odoo import fields, models + + +class Company(models.Model): + _inherit = "res.company" + + voxel_enabled = fields.Boolean(string="Enable Voxel") + voxel_send_mode = fields.Selection( + string="Send mode", + selection=[ + ("auto", "On validate"), + ("fixed", "At fixed time"), + ("delayed", "With delay"), + ], + default="auto", + ) + voxel_sent_time = fields.Float(string="Sent time") + voxel_delay_time = fields.Float(string="Delay time") + voxel_login_ids = fields.One2many( + comodel_name="voxel.login", + inverse_name="company_id", + string="Voxel logins", + ) + + def _get_voxel_report_eta(self): + if self.voxel_send_mode == "fixed": + tz = self.env.context.get("tz", self.env.user.partner_id.tz) + offset = datetime.now(pytz.timezone(tz)).strftime("%z") if tz else "+00" + hour_diff = int(offset[:3]) + hour, minute = divmod(self.voxel_sent_time * 60, 60) + hour = int(hour - hour_diff) + minute = int(minute) + now = datetime.now() + if now.hour > hour or (now.hour == hour and now.minute > minute): + now += timedelta(days=1) + now = now.replace(hour=hour, minute=minute) + return now + elif self.voxel_send_mode == "delayed": + return datetime.now() + timedelta(hours=self.voxel_delay_time) + else: + return None diff --git a/edi_voxel_oca/models/res_config_settings.py b/edi_voxel_oca/models/res_config_settings.py new file mode 100644 index 0000000000..19d35f17d6 --- /dev/null +++ b/edi_voxel_oca/models/res_config_settings.py @@ -0,0 +1,17 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + voxel_send_mode = fields.Selection( + related="company_id.voxel_send_mode", readonly=False + ) + voxel_sent_time = fields.Float(related="company_id.voxel_sent_time", readonly=False) + voxel_delay_time = fields.Float( + related="company_id.voxel_delay_time", readonly=False + ) diff --git a/edi_voxel_oca/models/res_partner.py b/edi_voxel_oca/models/res_partner.py new file mode 100644 index 0000000000..fcc445aa0e --- /dev/null +++ b/edi_voxel_oca/models/res_partner.py @@ -0,0 +1,22 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + voxel_enabled = fields.Boolean(string="Enable Voxel") + + def _commercial_fields(self): + return super()._commercial_fields() + ["voxel_enabled"] + + def _get_voxel_vat(self): + """Rip initial ES prefix if exists.""" + self.ensure_one() + vat = self.vat or "" + if vat.startswith("ES"): + return vat[2:] + return vat diff --git a/edi_voxel_oca/models/uom_uom.py b/edi_voxel_oca/models/uom_uom.py new file mode 100644 index 0000000000..7dda53caba --- /dev/null +++ b/edi_voxel_oca/models/uom_uom.py @@ -0,0 +1,26 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + +VOXEL_CODE = [ + ("Unidades", "Units"), + ("Kgs", "Kgs"), + ("Lts", "Liters"), + ("Lbs", "Lbs"), + ("Cajas", "Boxes"), + ("Bultos", "Packages"), + ("Palets", "Pallets"), + ("Horas", "Hours"), + ("Metros", "Meters"), + ("MetrosCuadrados", "Square meters"), + ("Contenedores", "Containers"), + ("Otros", "Others"), +] + + +class UoM(models.Model): + _inherit = "uom.uom" + + voxel_code = fields.Selection(selection=VOXEL_CODE) diff --git a/edi_voxel_oca/models/voxel_login.py b/edi_voxel_oca/models/voxel_login.py new file mode 100644 index 0000000000..eca58a4081 --- /dev/null +++ b/edi_voxel_oca/models/voxel_login.py @@ -0,0 +1,16 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class VoxelLogin(models.Model): + _name = "voxel.login" + _description = "Voxel login" + + name = fields.Char(required=True) + url = fields.Char(string="URL", required=True) + user = fields.Char(required=True) + password = fields.Char(required=True) + company_id = fields.Many2one(comodel_name="res.company", string="Company") diff --git a/edi_voxel_oca/models/voxel_mixin.py b/edi_voxel_oca/models/voxel_mixin.py new file mode 100644 index 0000000000..df72f91719 --- /dev/null +++ b/edi_voxel_oca/models/voxel_mixin.py @@ -0,0 +1,301 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2024, 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from datetime import datetime +from urllib.parse import urljoin + +import requests +from lxml import etree + +from odoo import _, api, exceptions, fields, models +from odoo.modules.registry import Registry + +_logger = logging.getLogger(__name__) + +try: + from odoo.addons.queue_job.job import job +except ImportError: + _logger.debug("Can not `import queue_job`.") + import functools + + def empty_decorator_factory(*argv, **kwargs): + return functools.partial + + job = empty_decorator_factory + + +class VoxelMixin(models.AbstractModel): + _name = "voxel.mixin" + _description = "Voxel mixin" + + voxel_state = fields.Selection( + selection=[ + ("not_sent", "Not sent"), + ("sent", "Sent not verified"), + ("sent_errors", "Sending error"), + ("accepted", "Sent and accepted"), + ("processing_error", "Processing error"), + ("cancelled", "Cancelled"), + ], + string="Voxel send state", + default="not_sent", + readonly=True, + copy=False, + help="Indicates the status of sending report to Voxel", + ) + voxel_xml_report = fields.Text(string="XML Report", readonly=True) + voxel_filename = fields.Char(readonly=True) + processing_error = fields.Text(readonly=True) + + # Export methods + # -------------- + def enqueue_voxel_report(self, report_name): + eta = self.company_id._get_voxel_report_eta() + queue_obj = self.env["queue.job"].sudo() + for record in self.sudo(): + # Look first if there's a failing job. If so, retry that one + failing_job = record.voxel_job_ids.filtered(lambda x: x.state == "failed")[ + :1 + ] + if failing_job: + failing_job.voxel_requeue_sudo() + continue + # If not, create a new one + new_delay = ( + record.with_context(company_id=self.company_id.id) + .with_delay(eta=eta) + ._get_and_send_voxel_report(report_name) + ) + job = queue_obj.search([("uuid", "=", new_delay.uuid)], limit=1) + record.voxel_job_ids |= job + + def _get_and_send_voxel_report(self, report_name): + self.ensure_one() + report = self.env.ref(report_name) + report_xml = report._render_qweb_xml(self.ids, {})[0] + # Remove blank spaces + tree = etree.fromstring(report_xml, etree.XMLParser(remove_blank_text=True)) + clean_report_xml = etree.tostring(tree, xml_declaration=True, encoding="UTF-8") + file_name = self._get_voxel_filename() + self._send_voxel_report("Outbox", file_name, clean_report_xml) + self.write( + { + "voxel_state": "sent", + "voxel_filename": file_name, + "voxel_xml_report": report_xml, + } + ) + + # export error detection methods + # ------------------------------ + def _cron_update_voxel_export_status(self): + for company in self.env["res.company"].search([]): + if company.voxel_enabled and self.get_voxel_login(company): + self._update_voxel_export_status(company) + + def _update_voxel_export_status(self, company): + sent_docs = self.search([("voxel_state", "=", "sent")]) + if not sent_docs: + return + queue_obj = self.env["queue.job"].sudo() + # Determine processed documents + filenames = self._list_voxel_document_filenames("Outbox", company) + processed = sent_docs.filtered(lambda r: r.voxel_filename not in filenames) + # Determine documents with errors + filenames = self._list_voxel_document_filenames("Error", company) + with_errors = processed.filtered(lambda r: r.voxel_filename in filenames) + doc_dict = {} + for doc in with_errors: + if doc.voxel_filename: + doc_dict[doc.voxel_filename] = doc + for filename in filenames: + if filename.endswith(".log"): + xml_file_name = filename[:-4] + ".xml" + if xml_file_name in doc_dict: + document = doc_dict[xml_file_name] + # Look first if there's a job for the current filename. + # If not, create it + file_job = queue_obj.search( + [("channel", "=", "root.voxel_status")] + ).filtered(lambda r: r.args == [filename, company])[:1] + if not file_job: + error_msg = ( + document.with_context(company_id=company.id) + .with_delay() + ._update_error_status(company, filename) + ) + # search queue job to add it to voxel job list + document.voxel_job_ids |= queue_obj.search( + [("uuid", "=", error_msg.uuid)], limit=1 + ) + # Update state of accepted documents + (processed - with_errors).write({"voxel_state": "accepted"}) + + def _update_error_status(self, company, filename): + processing_error_log = self._read_voxel_document( + "Error", company, filename, "ISO-8859-1" + ) + # Update state of documents with errors + self.write( + { + "processing_error": processing_error_log, + "voxel_state": "processing_error", + } + ) + # Delete error files from Voxel + self._delete_voxel_document("Error", filename, company) + self._delete_voxel_document("Error", filename[:-4] + ".xml", company) + self._delete_voxel_document("Error", filename[:-4] + ".utlog", company) + + # Import methods + # -------------- + def enqueue_import_voxel_documents(self, company): + queue_job_obj = self.env["queue.job"] + # list document names + voxel_filenames = self._list_voxel_document_filenames("Inbox", company) + # iterate the list to import documents one by one + for voxel_filename in voxel_filenames: + # Look first if there's a job for the current filename. + # If not, create it + file_job = queue_job_obj.search( + [("channel", "=", "root.voxel_import")] + ).filtered(lambda r: r.args == [voxel_filename, company])[:1] + if not file_job: + self.with_context( + company_id=company.id + ).with_delay()._import_voxel_document(voxel_filename, company) + + def _import_voxel_document(self, voxel_filename, company): + content = self._read_voxel_document("Inbox", company, voxel_filename) + # call method that parse and create the document from the content + doc = self.create_document_from_xml(content, voxel_filename, company) + if doc: + # write file content in the created object + doc.write({"voxel_xml_report": content, "voxel_filename": voxel_filename}) + # Delete file from Voxel + self._delete_voxel_document("Inbox", voxel_filename, company) + + def create_document_from_xml(self, xml_content, voxel_filename, company): + """This method must be overwritten by the model that use + `enqueue_import_voxel_documents` method""" + return False + + # API request methods + # -------------------- + def _request_to_voxel( + self, request_method, folder, company=None, voxel_filename=None, data=None + ): + login = self.get_voxel_login(company) + if not login: + raise Exception + url = urljoin(login.url, folder) + url += url.endswith("/") and "" or "/" + response = request_method( + url=urljoin(url, voxel_filename), + auth=(login.user, login.password), + data=data, + ) + _logger.debug("Voxel request response: %s", str(response)) + if response.status_code != 200: + response.raise_for_status() + return response + + def _send_voxel_report(self, folder, file_name, file_data): + try: + self._request_to_voxel( + requests.put, folder, voxel_filename=file_name, data=file_data + ) + except Exception: + new_cr = Registry(self.env.cr.dbname).cursor() + env = api.Environment(new_cr, self.env.uid, self.env.context) + record = env[self._name].browse(self.id) + record.voxel_state = "sent_errors" + new_cr.commit() + new_cr.close() + raise + + def _list_voxel_document_filenames(self, folder, company): + try: + response = self._request_to_voxel(requests.get, folder, company) + except Exception as exc: + raise Exception( + "Error reading '{}' folder from Voxel".format(folder) + ) from exc + # if no error, return list of documents file names + content = response.content + return content and content.decode("utf-8").split("\n") or [] + + def _read_voxel_document(self, folder, company, filename, encoding="utf-8"): + try: + response = self._request_to_voxel(requests.get, folder, company, filename) + except Exception as exc: + raise Exception( + "Error reading document {} from folder {}".format(filename, folder) + ) from exc + # Getting xml content with utf8 there are characters that can not + # be decoded, so 'ISO-8859-1' is used + return response.content.decode(encoding) + + def _delete_voxel_document(self, folder, voxel_filename, company): + try: + self._request_to_voxel(requests.delete, folder, company, voxel_filename) + except Exception as exc: + raise Exception( + "Error deleting document {} from folder {}".format( + voxel_filename, folder + ) + ) from exc + + # auxiliary methods + # ----------------- + def _get_voxel_filename(self): + self.ensure_one() + document_type = self.get_document_type() + date_time_seq = datetime.now().strftime("%Y%m%d_%H%M%S_%f")[:-3] + return "{}_{}.xml".format(document_type, date_time_seq) + + def _cancel_voxel_jobs(self): + # Remove not started jobs + not_started_jobs = self.env["queue.job"] + for queue in self.mapped("voxel_job_ids"): + if queue.state == "started": + raise exceptions.Warning( + _( + "This operation cannot be performed because there are " + "jobs running therefore cannot be unlinked." + ) + ) + else: + not_started_jobs |= queue + not_started_jobs.unlink() + # set voxel state to cancelled + self.write({"voxel_state": "cancelled"}) + + def get_voxel_login(self, company=None): + """This method must be overwritten by the model that inherit from + voxel.mixin""" + return self.env["voxel.login"] + + def _get_customer_product_sku(self, product, partner): + """Look for an entry for specific contact (sending/invoicing contact), + and if not found, look for the commercial partner. + """ + domain = [ + "|", + ("product_id", "=", product.id), + "&", + ("product_tmpl_id", "=", product.product_tmpl_id.id), + ("product_id", "=", False), + ] + customerinfo = self.env["product.customerinfo"].search( + [("name", "=", partner.id)] + domain, + order="product_id, sequence", + ) + if not customerinfo: + customerinfo = self.env["product.customerinfo"].search( + [("name", "=", partner.commercial_partner_id.id)] + domain, + order="product_id, sequence", + ) + return customerinfo[:1].product_code diff --git a/edi_voxel_oca/readme/CONTRIBUTORS.rst b/edi_voxel_oca/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..4fc41ecb83 --- /dev/null +++ b/edi_voxel_oca/readme/CONTRIBUTORS.rst @@ -0,0 +1,8 @@ +* `Tecnativa `_: + + * Ernesto Tejeda + * Pedro M. Baeza + +* `Guavana `_: + + * Leonardo J. Caballero G. diff --git a/edi_voxel_oca/readme/DESCRIPTION.rst b/edi_voxel_oca/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..2e6161c937 --- /dev/null +++ b/edi_voxel_oca/readme/DESCRIPTION.rst @@ -0,0 +1,13 @@ +This is a base module that allows you to send and receive documents +such as Invoices, Sales Orders, Delivery Orders in XML format using +the baVel electronic platform belonging to Voxel Group. + +Voxel Group is a company that offers leading solutions for B2B payments, +eInvoicing, VAT refund and supply chain via its baVel Platform. For more +information visit `https://www.voxelgroup.net/ `_. + +This module doesn't do anything useful by itself, but it is used by other modules: + +* *edi_voxel_account_invoice* to send invoices to Voxel. +* *edi_voxel_stock_picking* to send delivery orders to Voxel. +* *edi_voxel_sale_order_import* to import a sale order received from Voxel. diff --git a/edi_voxel_oca/security/ir.model.access.csv b/edi_voxel_oca/security/ir.model.access.csv new file mode 100644 index 0000000000..3a863c4e88 --- /dev/null +++ b/edi_voxel_oca/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_queue_job_voxel,access_queue_job voxel,queue_job.model_queue_job,group_voxel_manager,1,0,0,0 +access_voxel_login,access_voxel_login,model_voxel_login,group_voxel_manager,1,1,1,1 diff --git a/edi_voxel_oca/security/voxel_security.xml b/edi_voxel_oca/security/voxel_security.xml new file mode 100644 index 0000000000..48574e67e8 --- /dev/null +++ b/edi_voxel_oca/security/voxel_security.xml @@ -0,0 +1,30 @@ + + + + + Voxel manager + + + + + Queue job Voxel visibility + + ['|', ('channel', '=', 'root.voxel_export'), ('channel', '=', 'root.voxel_import')] + + + + Queue job manager + + [(1, '=', 1)] + + + + Voxel login multi-company + + ['|',('company_id','=',False),('company_id','in',company_ids)] + + diff --git a/edi_voxel_oca/static/description/icon.png b/edi_voxel_oca/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/edi_voxel_oca/static/description/icon.png differ diff --git a/edi_voxel_oca/static/description/index.html b/edi_voxel_oca/static/description/index.html new file mode 100644 index 0000000000..925e2ebfa0 --- /dev/null +++ b/edi_voxel_oca/static/description/index.html @@ -0,0 +1,443 @@ + + + + + +Voxel + + + +
+

Voxel

+ + +

Production/Stable License: AGPL-3 OCA/edi Translate me on Weblate Try me on Runboat

+

This is a base module that allows you to send and receive documents +such as Invoices, Sales Orders, Delivery Orders in XML format using +the baVel electronic platform belonging to Voxel Group.

+

Voxel Group is a company that offers leading solutions for B2B payments, +eInvoicing, VAT refund and supply chain via its baVel Platform. For more +information visit https://www.voxelgroup.net/.

+

This module doesn’t do anything useful by itself, but it is used by other modules:

+
    +
  • edi_voxel_account_invoice to send invoices to Voxel.
  • +
  • edi_voxel_stock_picking to send delivery orders to Voxel.
  • +
  • edi_voxel_sale_order_import to import a sale order received from Voxel.
  • +
+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
  • Guavana
  • +
+
+
+

Contributors

+
    +
  • Tecnativa:
      +
    • Ernesto Tejeda
    • +
    • Pedro M. Baeza
    • +
    +
  • +
  • Guavana:
      +
    • Leonardo J. Caballero G.
    • +
    +
  • +
+
+
+

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/edi project on GitHub.

+

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

+
+
+
+ + diff --git a/edi_voxel_oca/tests/__init__.py b/edi_voxel_oca/tests/__init__.py new file mode 100644 index 0000000000..af02150669 --- /dev/null +++ b/edi_voxel_oca/tests/__init__.py @@ -0,0 +1,4 @@ +from . import test_queue_job +from . import test_res_company +from . import test_res_partner +from . import test_voxel_mixin diff --git a/edi_voxel_oca/tests/test_queue_job.py b/edi_voxel_oca/tests/test_queue_job.py new file mode 100644 index 0000000000..9452b825fa --- /dev/null +++ b/edi_voxel_oca/tests/test_queue_job.py @@ -0,0 +1,35 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestQueueJob(TransactionCase): + def setUp(self): + super(TestQueueJob, self).setUp() + self.queue_job = ( + self.env["queue.job"] + .with_delay() + .create( + { + "name": "Test Job", + "state": "failed", + } + ) + ) + + def test_voxel_do_now(self): + self.queue_job.voxel_do_now() + self.assertFalse(self.queue_job.eta, "ETA should be set to False") + + def test_voxel_cancel_now(self): + self.queue_job.voxel_cancel_now() + self.assertFalse( + self.queue_job.exists(), + "Job should be unlinked if in pending, enqueued, or failed state", + ) + + def test_voxel_requeue_sudo(self): + self.queue_job.voxel_requeue_sudo() + self.assertEqual(self.queue_job.state, "enqueued", "Job should be requeued") diff --git a/edi_voxel_oca/tests/test_res_company.py b/edi_voxel_oca/tests/test_res_company.py new file mode 100644 index 0000000000..fd54d6c83e --- /dev/null +++ b/edi_voxel_oca/tests/test_res_company.py @@ -0,0 +1,50 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from datetime import datetime, timedelta + +import pytz + +from odoo.tests.common import TransactionCase + + +class TestResCompany(TransactionCase): + def setUp(self): + super(TestResCompany, self).setUp() + self.company = self.env["res.company"].create( + { + "name": "Test Company", + "voxel_enabled": True, + "voxel_send_mode": "fixed", + "voxel_sent_time": 11.0, # 11:00 AM + "voxel_delay_time": 2.0, + } + ) + + def test_get_voxel_report_eta_auto(self): + self.company.voxel_send_mode = "auto" + eta = self.company._get_voxel_report_eta() + self.assertIsNone(eta, "ETA should be None for auto send mode") + + def test_get_voxel_report_eta_fixed(self): + tz = pytz.timezone(self.env.user.partner_id.tz or "UTC") + now = datetime.now(tz) + expected_eta = now.replace(hour=11, minute=0, second=0, microsecond=0) + if now.hour > 11 or (now.hour == 11 and now.minute > 0): + expected_eta += timedelta(days=1) + eta = self.company._get_voxel_report_eta() + eta = eta.replace(second=0, microsecond=0) # Ignore seconds and microseconds + self.assertEqual(eta, expected_eta, "ETA should match the expected fixed time") + + def test_get_voxel_report_eta_delayed(self): + self.company.voxel_send_mode = "delayed" + expected_eta = datetime.now() + timedelta(hours=2) + eta = self.company._get_voxel_report_eta() + self.assertIsNotNone(eta, "ETA should not be None for delayed send mode") + self.assertAlmostEqual( + eta, + expected_eta, + msg="ETA should be 2 hours from now for delayed send mode", + delta=timedelta(seconds=1), + ) diff --git a/edi_voxel_oca/tests/test_res_partner.py b/edi_voxel_oca/tests/test_res_partner.py new file mode 100644 index 0000000000..1fa9a87801 --- /dev/null +++ b/edi_voxel_oca/tests/test_res_partner.py @@ -0,0 +1,36 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestResPartner(TransactionCase): + def setUp(self): + super(TestResPartner, self).setUp() + self.partner = self.env["res.partner"].create( + { + "name": "Test Partner", + "vat": "ESX12345678", # Provide a valid VAT number + "voxel_enabled": True, + } + ) + + def test_commercial_fields(self): + commercial_fields = self.partner._commercial_fields() + self.assertIn( + "voxel_enabled", + commercial_fields, + "voxel_enabled should be in the commercial fields", + ) + + def test_get_voxel_vat_with_prefix(self): + vat = self.partner._get_voxel_vat() + self.assertEqual(vat, "X12345678", "VAT should be stripped of the 'ES' prefix") + + def test_get_voxel_vat_without_prefix(self): + self.partner.vat = "12345678" + vat = self.partner._get_voxel_vat() + self.assertEqual( + vat, "12345678", "VAT should remain unchanged if no 'ES' prefix" + ) diff --git a/edi_voxel_oca/tests/test_voxel_mixin.py b/edi_voxel_oca/tests/test_voxel_mixin.py new file mode 100644 index 0000000000..53970b3d22 --- /dev/null +++ b/edi_voxel_oca/tests/test_voxel_mixin.py @@ -0,0 +1,111 @@ +# Copyright 2019 Tecnativa - Ernesto Tejeda +# Copyright 2025 Guavana - Leonardo J. Caballero G. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from unittest.mock import MagicMock, patch + +from odoo.exceptions import AccessError +from odoo.tests.common import TransactionCase + + +class TestVoxelMixin(TransactionCase): + def setUp(self): + super(TestVoxelMixin, self).setUp() + self.company = self.env["res.company"].create( + { + "name": "Test Company", + "voxel_enabled": True, + } + ) + voxel_xml_report_msg = ( + "Error reading document INV_20250131_200845_553.xml from folder Inbox" + ) + processing_error_msg = ( + "Processing error: Error reading document " + "INV_20250131_200845_553.xml from folder Inbox" + ) + self.mixin = self.env["voxel.mixin"].create( + { + "voxel_state": "not_sent", + "voxel_xml_report": voxel_xml_report_msg, + "voxel_filename": "INV_20250131_200845_553.xml", + "processing_error": processing_error_msg, + } + ) + + @patch("odoo.addons.edi_voxel_oca.models.voxel_mixin.requests.put") + def test_send_voxel_report_success(self, mock_put): + mock_put.return_value.status_code = 200 + self.mixin._send_voxel_report( + "Outbox", "INV_20241231_200845_553.xml", b"" + ) + self.assertEqual(self.mixin.voxel_state, "sent", "Voxel state should be 'sent'") + + @patch("odoo.addons.edi_voxel_oca.models.voxel_mixin.requests.put") + def test_send_voxel_report_failure(self, mock_put): + mock_put.return_value.status_code = 500 + with self.assertRaises(AccessError) as context: + self.mixin.with_delay()._send_voxel_report( + "Outbox", "INV_20241231_200845_553.xml", b"" + ) + self.assertTrue( + "Queue jobs must be created by calling 'with_delay()'" + in str(context.exception) + ) + self.assertEqual( + self.mixin.voxel_state, "sent_errors", "Voxel state should be 'sent_errors'" + ) + + @patch("odoo.addons.edi_voxel_oca.models.voxel_mixin.requests.get") + def test_list_voxel_document_filenames(self, mock_get): + mock_get.return_value.status_code = 200 + mock_get.return_value.content = ( + b"INV_20250113_200845_555.xml\nINV_20250113_200847_557.xml\n" + ) + filenames = self.mixin._list_voxel_document_filenames("Outbox", self.company) + self.assertEqual( + filenames, + ["INV_20250113_200845_555.xml", "INV_20250113_200847_557.xml"], + "Filenames should match the expected list", + ) + + @patch("odoo.addons.edi_voxel_oca.models.voxel_mixin.requests.get") + def test_read_voxel_document(self, mock_get): + mock_get.return_value.status_code = 200 + mock_get.return_value.content = b"" + content = self.mixin._read_voxel_document( + "Inbox", self.company, "INV_20241231_200845_553.xml" + ) + self.assertEqual( + content, "", "Content should match the expected XML" + ) + + @patch("odoo.addons.edi_voxel_oca.models.voxel_mixin.requests.delete") + def test_delete_voxel_document(self, mock_delete): + mock_delete.return_value.status_code = 200 + self.mixin._delete_voxel_document( + "Inbox", "INV_20241231_200845_553.xml", self.company + ) + mock_delete.assert_called_once() + + def test_get_voxel_filename(self): + self.mixin.get_document_type = MagicMock(return_value="INV") + filename = self.mixin._get_voxel_filename() + self.assertTrue( + filename.startswith("INV_"), "Filename should start with 'INV_'" + ) + self.assertTrue(filename.endswith(".xml"), "Filename should end with '.xml'") + + def test_cancel_voxel_jobs(self): + job = self.env["queue.job"].create( + { + "name": "Test Job", + "state": "pending", + } + ) + self.mixin.voxel_job_ids = [(4, job.id)] + self.mixin._cancel_voxel_jobs() + self.assertEqual( + self.mixin.voxel_state, "cancelled", "Voxel state should be 'cancelled'" + ) + self.assertFalse(job.exists(), "Job should be unlinked") diff --git a/edi_voxel_oca/views/account_tax_views.xml b/edi_voxel_oca/views/account_tax_views.xml new file mode 100644 index 0000000000..11ed4d6351 --- /dev/null +++ b/edi_voxel_oca/views/account_tax_views.xml @@ -0,0 +1,20 @@ + + + + + account.tax.form.inherit.voxel + account.tax + + + + + + + + diff --git a/edi_voxel_oca/views/product_uom_views.xml b/edi_voxel_oca/views/product_uom_views.xml new file mode 100644 index 0000000000..0f2d59c70f --- /dev/null +++ b/edi_voxel_oca/views/product_uom_views.xml @@ -0,0 +1,20 @@ + + + + + uom.uom.form.inherit + uom.uom + + + + + + + + diff --git a/edi_voxel_oca/views/res_company_view.xml b/edi_voxel_oca/views/res_company_view.xml new file mode 100644 index 0000000000..b3f19e2ae4 --- /dev/null +++ b/edi_voxel_oca/views/res_company_view.xml @@ -0,0 +1,58 @@ + + + + + res.company.voxel.form + res.company + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/edi_voxel_oca/views/res_config_settings_views.xml b/edi_voxel_oca/views/res_config_settings_views.xml new file mode 100644 index 0000000000..acbe424152 --- /dev/null +++ b/edi_voxel_oca/views/res_config_settings_views.xml @@ -0,0 +1,82 @@ + + + + + res.config.settings.view.form.voxel + res.config.settings + + + +

Voxel

+
+
+
+ Send mode + +
+ Choose the send mode for documents to Voxel +
+
+
+
+
+
+
+
+
+
+
+
+
+ Web Sevice credentials + +
+ Set credentials for connection to Voxel using Web Service +
+
+
+
+
+ + + + diff --git a/edi_voxel_oca/views/res_partner_views.xml b/edi_voxel_oca/views/res_partner_views.xml new file mode 100644 index 0000000000..70962d6477 --- /dev/null +++ b/edi_voxel_oca/views/res_partner_views.xml @@ -0,0 +1,20 @@ + + + + + res.partner.voxel.enabled + res.partner + + + + + + + + diff --git a/edi_voxel_oca/views/template_voxel_report.xml b/edi_voxel_oca/views/template_voxel_report.xml new file mode 100644 index 0000000000..1cef4eda01 --- /dev/null +++ b/edi_voxel_oca/views/template_voxel_report.xml @@ -0,0 +1,42 @@ + + + + + diff --git a/edi_voxel_oca/views/voxel_login_views.xml b/edi_voxel_oca/views/voxel_login_views.xml new file mode 100644 index 0000000000..c7bd5d46fb --- /dev/null +++ b/edi_voxel_oca/views/voxel_login_views.xml @@ -0,0 +1,26 @@ + + + + + voxel.login.view.form + voxel.login + +
+ + + + + + + + + + + + +
+
+
+
diff --git a/setup/edi_voxel_oca/odoo/addons/edi_voxel_oca b/setup/edi_voxel_oca/odoo/addons/edi_voxel_oca new file mode 120000 index 0000000000..1fcb009ce1 --- /dev/null +++ b/setup/edi_voxel_oca/odoo/addons/edi_voxel_oca @@ -0,0 +1 @@ +../../../../edi_voxel_oca \ No newline at end of file diff --git a/setup/edi_voxel_oca/setup.py b/setup/edi_voxel_oca/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/edi_voxel_oca/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)