diff --git a/bc3_importer/README.rst b/bc3_importer/README.rst new file mode 100644 index 0000000..8c7d3f1 --- /dev/null +++ b/bc3_importer/README.rst @@ -0,0 +1,78 @@ +================== +BC3 files importer +================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:6b05fd6ca153a4f3037ca157603586c4afc51598b639d7b6b0ba4e426f27e40d + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fvertical--construction-lightgray.png?logo=github + :target: https://github.com/OCA/vertical-construction/tree/17.0/bc3_importer + :alt: OCA/vertical-construction +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/vertical-construction-17-0/vertical-construction-17-0-bc3_importer + :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/vertical-construction&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Importer of quotations in bc3 format. + +**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 +------- + +* Binhex + +Contributors +------------ + +- `Binhex `__: + + - Zuzanna Elzbieta Szalaty Szalaty + +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/vertical-construction `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/bc3_importer/__init__.py b/bc3_importer/__init__.py new file mode 100644 index 0000000..9b42961 --- /dev/null +++ b/bc3_importer/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/bc3_importer/__manifest__.py b/bc3_importer/__manifest__.py new file mode 100644 index 0000000..dac9010 --- /dev/null +++ b/bc3_importer/__manifest__.py @@ -0,0 +1,22 @@ +{ + "name": "BC3 files importer", + "author": "Binhex, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/vertical-construction", + "category": "BC3", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "depends": ["project", "sale_management"], + "data": [ + "security/bc3_file_security.xml", + "security/ir.model.access.csv", + "wizard/bc3_import_wizard_views.xml", + "views/bc3_version_views.xml", + "data/bc3_version_data.xml", + "views/sale_order_views.xml", + "data/uom_data.xml", + "data/product_data.xml", + ], + "external_dependencies": { + "python": ["iteration_utilities", "chardet"], + }, +} diff --git a/bc3_importer/data/bc3_version_data.xml b/bc3_importer/data/bc3_version_data.xml new file mode 100644 index 0000000..347da23 --- /dev/null +++ b/bc3_importer/data/bc3_version_data.xml @@ -0,0 +1,259 @@ + + + + FIEBDC-3-2020v2 + + + + 1 + + False + + + + 2 + + False + + + + 3 + + True + + + + 4 + + False + + + + 5 + + False + + + + 6 + + True + + + + 7 + + False + + + + 8 + + False + + + + 9 + + False + + + + 10 + + False + + + + 11 + + False + + + + 12 + + False + + + + v + ~V | [ PROPIEDAD_ARCHIVO ] | VERSION_FORMATO [ \ DDMMAAAA ] | [ +PROGRAMA_EMISION ] | [ CABECERA ] \ { ROTULO_IDENTIFICACION \ } | [ +JUEGO_CARACTERES ] | [ COMENTARIO ] | [ TIPO INFORMACIÓN ] | [ NÚMERO +CERTIFICACIÓN ] | [ FECHA CERTIFICACIÓN ] | [ URL_BASE ] | + + + + + + + 1 + + False + + + + 2 + + True + + + + 3 + + False + + + + 4 + + False + + + + 5 + + False + + + + 6 + False + + + 7 + + False + + + + c + ~C | CODIGO { \ CODIGO } | [ UNIDAD ] | [ RESUMEN ] | { PRECIO \ } | { FECHA \ } | [ TIPO ] | + + + + + + + 1 + + False + + + 2 + + False + + True + + + + 3 + True + + + + + 4 + + True + + + + + 5 + False + + + 6 + True + + + 7 + True + + + 8 + + True + + + + d + ~D | CODIGO_PADRE | < CODIGO_HIJO \ [ FACTOR ] \ [ RENDIMIENTO ] \ > | < CODIGO_HIJO \ [ FACTOR ] \ [ RENDIMIENTO ] \ {CODIGO_PORCENTAJE ; } \ > | + + + True + + + + + 1 + + True + + + + 2 + + + + + t + ~T | CODIGO_CONCEPTO | TEXTO_DESCRIPTIVO | + + + True + + + + + + + + + + + + + + + + diff --git a/bc3_importer/data/product_data.xml b/bc3_importer/data/product_data.xml new file mode 100644 index 0000000..3cdac78 --- /dev/null +++ b/bc3_importer/data/product_data.xml @@ -0,0 +1,99 @@ + + + + BC3 Template Product (Units) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Template Product (Meter) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Template Product (Square meter) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Template Product (Cubic meter) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Template Product (g) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Template Product (L) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Product (Units) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Product (Meter) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Product (Square meter) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Product (Cubic meter) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Product (g) + + + BC3 product that will be used if imported product does not exist. + + + BC3 Product (L) + + + BC3 product that will be used if imported product does not exist. + + diff --git a/bc3_importer/data/uom_data.xml b/bc3_importer/data/uom_data.xml new file mode 100644 index 0000000..fe22881 --- /dev/null +++ b/bc3_importer/data/uom_data.xml @@ -0,0 +1,9 @@ + + + + + m2 + + bigger + + diff --git a/bc3_importer/i18n/bc3_importer.pot b/bc3_importer/i18n/bc3_importer.pot new file mode 100644 index 0000000..4308852 --- /dev/null +++ b/bc3_importer/i18n/bc3_importer.pot @@ -0,0 +1,540 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * bc3_importer +# +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: bc3_importer +#: model:res.groups,name:bc3_importer.group_bc3_manager +msgid "Administrator" +msgstr "" + +#. module: bc3_importer +#: model:ir.module.category,name:bc3_importer.module_bc3_importer_bc3 +#: model:ir.ui.menu,name:bc3_importer.bc3_files +#: model:ir.ui.menu,name:bc3_importer.bc3_menuitem +msgid "BC3" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.view_sales_order_bc3 +msgid "BC3 Info" +msgstr "" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_orders_show +msgid "BC3 Orders" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_cubic_meter_product_template +msgid "BC3 Product (Cubic meter)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_l_product_template +msgid "BC3 Product (L)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_meter_product_template +msgid "BC3 Product (Meter)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_square_meter_product_template +msgid "BC3 Product (Square meter)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_units_product_template +msgid "BC3 Product (Units)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_g_product_template +msgid "BC3 Product (g)" +msgstr "" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.action_quotations_bc3 +#: model:ir.ui.menu,name:bc3_importer.bc3_quotations_show +msgid "BC3 Quotations" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_cubic_meter +msgid "BC3 Template Product (Cubic meter)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_l +msgid "BC3 Template Product (L)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_meter +msgid "BC3 Template Product (Meter)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_square_meter +msgid "BC3 Template Product (Square meter)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_units +msgid "BC3 Template Product (Units)" +msgstr "" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_g +msgid "BC3 Template Product (g)" +msgstr "" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_action +#: model:ir.model,name:bc3_importer.model_bc3_version +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "BC3 Version" +msgstr "" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_version_register +msgid "BC3 Version Register" +msgstr "" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_version_register_rule +msgid "BC3 Version Register Rule" +msgstr "" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_version_show +msgid "BC3 Versions" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__bc3_file +msgid "BC3 file" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__bc3_file_name +msgid "BC3 file name" +msgstr "" + +#. module: bc3_importer +#: model:product.template,description_sale:bc3_importer.product_product_product_cubic_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_g_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_l_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_square_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_template_cubic_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_g +#: model:product.template,description_sale:bc3_importer.product_product_product_template_l +#: model:product.template,description_sale:bc3_importer.product_product_product_template_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_square_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_units +#: model:product.template,description_sale:bc3_importer.product_product_product_units_product_template +msgid "BC3 product that will be used if imported product does not exist." +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3 +msgid "BC3 sale order" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_base_url +msgid "Base url" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_import_wizard_form +msgid "Cancel" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_certification_date +msgid "Certification date" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_certification_number +msgid "Certification number" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_character_set +msgid "Character set" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__is_child +msgid "Child" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order_line__bc3_code +msgid "Code" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_comment +msgid "Comment" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.action_quotations_bc3 +msgid "Create a new quotation, the first step of a new sale!" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_products +msgid "Create non-existent products" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__create_uid +msgid "Created by" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__create_date +msgid "Created on" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__partner_id +msgid "Customer/Vendor" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__product_id +msgid "Default product" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Description" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__display_name +msgid "Display Name" +msgstr "" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Dynamic Product " +msgstr "" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/models/bc3_version.py:0 +#, python-format +msgid "Error in register description or not enough rules" +msgstr "" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Error parsing the file" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__field_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__field_ids +msgid "Field" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_file_property +msgid "File property" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_header +msgid "Header" +msgstr "" + +#. module: bc3_importer +#: model:ir.module.category,description:bc3_importer.module_bc3_importer_bc3 +msgid "Helps you handle your bc3 files, versions and registers." +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__id +msgid "ID" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_identifying_label +msgid "Identifying label" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_import_wizard_form +msgid "Import" +msgstr "" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_files_import +msgid "Import BC3" +msgstr "" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_import_wizard_action +msgid "Import BC3 File" +msgstr "" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_import_wizard +msgid "Import BC3 file" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_information_type +msgid "Information Type" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule____last_update +msgid "Last Modified on" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__write_date +msgid "Last Updated on" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__model_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__model_id +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Model" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__name +msgid "Name" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_action +msgid "No bc3 version found. Let's create one!" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_register_action +msgid "No register found. Let's create one!" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_register_rule_action +msgid "No register rule found. Let's create one!" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.action_quotations_bc3 +msgid "" +"Once the quotation is confirmed by the customer, it becomes a sales " +"order.
You will be able to create an invoice and collect the payment." +msgstr "" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Parsing error, missing data" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__primary_key +msgid "Primary key" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_program +msgid "Program" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__project_id +msgid "Project" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__register_id +msgid "Register" +msgstr "" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_register_rule_action +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_rule_form_view +msgid "Register Rule" +msgstr "" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/models/bc3_version.py:0 +#, python-format +msgid "Register name should unique" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__register_ids +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "Registers" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__regular_expression +msgid "Regular expression" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__description +msgid "Rule Description" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__rule_ids +msgid "Rule Lines" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Rules" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__sale_id +msgid "Sale Order" +msgstr "" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_sale_order_line +msgid "Sales Order Line" +msgstr "" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.action_orders_bc3 +msgid "Sales Orders" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,help:bc3_importer.field_bc3_import_wizard__product_id +msgid "Select a product which will be used in the BC3 file." +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__sequence +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__sequence +msgid "Sequence" +msgstr "" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Show Sale Order" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__edit_existent +msgid "The register may edit existent records" +msgstr "" + +#. module: bc3_importer +#: model:res.groups,name:bc3_importer.group_bc3_user +msgid "User" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__version_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__version_id +msgid "Version" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_version_format +msgid "Version / Format" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.view_sales_order_bc3 +msgid "Version Information" +msgstr "" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_register_action +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Version Register" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_version_date +msgid "Version date" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "e.g. FIEBDC-3-2020v2" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "e.g. ~K" +msgstr "" + +#. module: bc3_importer +#: model:uom.uom,name:bc3_importer.product_uom_square_meter +msgid "m2" +msgstr "" diff --git a/bc3_importer/i18n/es.po b/bc3_importer/i18n/es.po new file mode 100644 index 0000000..cd185e3 --- /dev/null +++ b/bc3_importer/i18n/es.po @@ -0,0 +1,551 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * bc3_importer +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0-20231106\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-30 10:14+0000\n" +"PO-Revision-Date: 2024-09-30 12:33+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: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.5\n" + +#. module: bc3_importer +#: model:res.groups,name:bc3_importer.group_bc3_manager +msgid "Administrator" +msgstr "" + +#. module: bc3_importer +#: model:ir.module.category,name:bc3_importer.module_bc3_importer_bc3 +#: model:ir.ui.menu,name:bc3_importer.bc3_files +#: model:ir.ui.menu,name:bc3_importer.bc3_menuitem +msgid "BC3" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.view_sales_order_bc3 +msgid "BC3 Info" +msgstr "" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_orders_show +msgid "BC3 Orders" +msgstr "Pedidos BC3" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_cubic_meter_product_template +msgid "BC3 Product (Cubic meter)" +msgstr "Producto BC3 (metro cúbico)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_l_product_template +msgid "BC3 Product (L)" +msgstr "Producto BC3 (L)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_meter_product_template +msgid "BC3 Product (Meter)" +msgstr "Producto BC3 (Metro)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_square_meter_product_template +msgid "BC3 Product (Square meter)" +msgstr "BC3 Producto (metro cuadrado)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_units_product_template +msgid "BC3 Product (Units)" +msgstr "BC3 Producto (Unidades)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_g_product_template +msgid "BC3 Product (g)" +msgstr "BC3 Producto (g)" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.action_quotations_bc3 +#: model:ir.ui.menu,name:bc3_importer.bc3_quotations_show +msgid "BC3 Quotations" +msgstr "Presupuestos BC3" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_cubic_meter +msgid "BC3 Template Product (Cubic meter)" +msgstr "Plantilla BC3 Producto (metro cúbico)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_l +msgid "BC3 Template Product (L)" +msgstr "Plantilla BC3 Producto (L)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_meter +msgid "BC3 Template Product (Meter)" +msgstr "Plantilla BC3 Producto (Metro)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_square_meter +msgid "BC3 Template Product (Square meter)" +msgstr "Plantilla BC3 Producto (metro cuadrado)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_units +msgid "BC3 Template Product (Units)" +msgstr "Cuenta de gastos en plantilla producto" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_g +msgid "BC3 Template Product (g)" +msgstr "Plantilla BC3 Producto (g)" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_action +#: model:ir.model,name:bc3_importer.model_bc3_version +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "BC3 Version" +msgstr "Versión BC3" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_version_register +msgid "BC3 Version Register" +msgstr "Registro de versión BC3" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_version_register_rule +msgid "BC3 Version Register Rule" +msgstr "Regla de registro de la versión BC3" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_version_show +msgid "BC3 Versions" +msgstr "Versiones BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__bc3_file +msgid "BC3 file" +msgstr "Archivo BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__bc3_file_name +msgid "BC3 file name" +msgstr "Nombre del archivo BC3" + +#. module: bc3_importer +#: model:product.template,description_sale:bc3_importer.product_product_product_cubic_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_g_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_l_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_square_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_template_cubic_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_g +#: model:product.template,description_sale:bc3_importer.product_product_product_template_l +#: model:product.template,description_sale:bc3_importer.product_product_product_template_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_square_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_units +#: model:product.template,description_sale:bc3_importer.product_product_product_units_product_template +msgid "BC3 product that will be used if imported product does not exist." +msgstr "Producto BC3 que se utilizará si no existe el producto importado." + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3 +msgid "BC3 sale order" +msgstr "Pedido de venta BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_base_url +msgid "Base url" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_import_wizard_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_certification_date +msgid "Certification date" +msgstr "Fecha de certificación" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_certification_number +msgid "Certification number" +msgstr "Número de certificación" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_character_set +msgid "Character set" +msgstr "Conjunto de caracteres" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__is_child +msgid "Child" +msgstr "Hijo" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order_line__bc3_code +msgid "Code" +msgstr "Código" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_comment +msgid "Comment" +msgstr "Comentario" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.action_quotations_bc3 +msgid "Create a new quotation, the first step of a new sale!" +msgstr "Crear un nuevo presupuesto, ¡el primer paso de una nueva venta!" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_products +msgid "Create non-existent products" +msgstr "Crear productos no existentes" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__partner_id +msgid "Customer/Vendor" +msgstr "Cliente/Proveedor" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__product_id +msgid "Default product" +msgstr "Producto por defecto" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Description" +msgstr "Descripción" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Dynamic Product " +msgstr "Producto dinámico " + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/models/bc3_version.py:0 +#, python-format +msgid "Error in register description or not enough rules" +msgstr "Error en la descripción del registro o reglas insuficientes" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Error parsing the file" +msgstr "Error al analizar el archivo" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__field_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__field_ids +msgid "Field" +msgstr "Campo" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_file_property +msgid "File property" +msgstr "Propiedad del archivo" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_header +msgid "Header" +msgstr "Encabezado" + +#. module: bc3_importer +#: model:ir.module.category,description:bc3_importer.module_bc3_importer_bc3 +msgid "Helps you handle your bc3 files, versions and registers." +msgstr "Le ayuda a manejar sus archivos bc3, versiones y registros." + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__id +msgid "ID" +msgstr "" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_identifying_label +msgid "Identifying label" +msgstr "Etiqueta identificativa" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_import_wizard_form +msgid "Import" +msgstr "Importar" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_files_import +msgid "Import BC3" +msgstr "Importar BC3" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_import_wizard_action +msgid "Import BC3 File" +msgstr "Importar archivo BC3" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_import_wizard +msgid "Import BC3 file" +msgstr "Importar archivo BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_information_type +msgid "Information Type" +msgstr "Tipo de información" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__model_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__model_id +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Model" +msgstr "Modelo" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__name +msgid "Name" +msgstr "Nombre" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_action +msgid "No bc3 version found. Let's create one!" +msgstr "No se ha encontrado ninguna versión de bc3. ¡Vamos a crear una!" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_register_action +msgid "No register found. Let's create one!" +msgstr "No se ha encontrado ningún registro. ¡Vamos a crear uno!" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_register_rule_action +msgid "No register rule found. Let's create one!" +msgstr "No se ha encontrado ninguna regla de registro. Creemos una." + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.action_quotations_bc3 +msgid "" +"Once the quotation is confirmed by the customer, it becomes a sales order." +"
You will be able to create an invoice and collect the payment." +msgstr "" +"Una vez que el presupuesto es confirmado por el cliente, se convierte en un " +"pedido de venta.
Podrás crear una factura y cobrar el pago." + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Parsing error, missing data" +msgstr "Error de análisis sintáctico, faltan datos" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__primary_key +msgid "Primary key" +msgstr "Clave principal" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_program +msgid "Program" +msgstr "Programa" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__project_id +msgid "Project" +msgstr "Proyecto" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__register_id +msgid "Register" +msgstr "Registro" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_register_rule_action +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_rule_form_view +msgid "Register Rule" +msgstr "Regla de registro" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/models/bc3_version.py:0 +#, python-format +msgid "Register name should unique" +msgstr "El nombre de registro debe ser único" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__register_ids +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "Registers" +msgstr "Registros" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__regular_expression +msgid "Regular expression" +msgstr "Expresión regular" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__description +msgid "Rule Description" +msgstr "Descripción de la regla" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__rule_ids +msgid "Rule Lines" +msgstr "Líneas de la regla" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Rules" +msgstr "Reglas" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__sale_id +msgid "Sale Order" +msgstr "Pedido de venta" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_sale_order +msgid "Sales Order" +msgstr "Pedido de venta" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_sale_order_line +msgid "Sales Order Line" +msgstr "Línea de pedido de venta" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.action_orders_bc3 +msgid "Sales Orders" +msgstr "Pedidos de ventas" + +#. module: bc3_importer +#: model:ir.model.fields,help:bc3_importer.field_bc3_import_wizard__product_id +msgid "Select a product which will be used in the BC3 file." +msgstr "Seleccione el producto que se utilizará en el archivo BC3." + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__sequence +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__sequence +msgid "Sequence" +msgstr "Secuencia" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Show Sale Order" +msgstr "Mostrar pedido de venta" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__edit_existent +msgid "The register may edit existent records" +msgstr "El registro puede editar registros existentes" + +#. module: bc3_importer +#: model:res.groups,name:bc3_importer.group_bc3_user +msgid "User" +msgstr "Usuario" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__version_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__version_id +msgid "Version" +msgstr "Versión BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_version_format +msgid "Version / Format" +msgstr "Versión / Formato" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.view_sales_order_bc3 +msgid "Version Information" +msgstr "Información sobre la versión" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_register_action +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Version Register" +msgstr "Registro de versiones" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_version_date +msgid "Version date" +msgstr "Fecha de la versión" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "e.g. FIEBDC-3-2020v2" +msgstr "" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "e.g. ~K" +msgstr "" + +#. module: bc3_importer +#: model:uom.uom,name:bc3_importer.product_uom_square_meter +msgid "m2" +msgstr "" + +#~ msgid "Date" +#~ msgstr "Fecha" + +#~ msgid "Units" +#~ msgstr "Unidades" diff --git a/bc3_importer/i18n/it.po b/bc3_importer/i18n/it.po new file mode 100644 index 0000000..f880dbb --- /dev/null +++ b/bc3_importer/i18n/it.po @@ -0,0 +1,545 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * bc3_importer +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-10-14 10:06+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: bc3_importer +#: model:res.groups,name:bc3_importer.group_bc3_manager +msgid "Administrator" +msgstr "Amministratore" + +#. module: bc3_importer +#: model:ir.module.category,name:bc3_importer.module_bc3_importer_bc3 +#: model:ir.ui.menu,name:bc3_importer.bc3_files +#: model:ir.ui.menu,name:bc3_importer.bc3_menuitem +msgid "BC3" +msgstr "BC3" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.view_sales_order_bc3 +msgid "BC3 Info" +msgstr "Informazioni BC3" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_orders_show +msgid "BC3 Orders" +msgstr "Ordini BC3" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_cubic_meter_product_template +msgid "BC3 Product (Cubic meter)" +msgstr "Prodotto BC3 (metri cubi)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_l_product_template +msgid "BC3 Product (L)" +msgstr "Prodotto BC3 (litri)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_meter_product_template +msgid "BC3 Product (Meter)" +msgstr "Prodotto BC3 (metri)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_square_meter_product_template +msgid "BC3 Product (Square meter)" +msgstr "Prodotto BC3 (metri quadri)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_units_product_template +msgid "BC3 Product (Units)" +msgstr "Prodotto BC3 (unità)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_g_product_template +msgid "BC3 Product (g)" +msgstr "Prodotto BC3 (grammi)" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.action_quotations_bc3 +#: model:ir.ui.menu,name:bc3_importer.bc3_quotations_show +msgid "BC3 Quotations" +msgstr "Preventivi BC3" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_cubic_meter +msgid "BC3 Template Product (Cubic meter)" +msgstr "Modello prodotto BC3 (metri cubi)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_l +msgid "BC3 Template Product (L)" +msgstr "Modello prodotto BC3 (litri)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_meter +msgid "BC3 Template Product (Meter)" +msgstr "Modello prodotto BC3 (metri)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_square_meter +msgid "BC3 Template Product (Square meter)" +msgstr "Modello prodotto BC3 (metri quadri)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_units +msgid "BC3 Template Product (Units)" +msgstr "Modello prodotto BC3 (unità)" + +#. module: bc3_importer +#: model:product.template,name:bc3_importer.product_product_product_template_g +msgid "BC3 Template Product (g)" +msgstr "Modello prodotto BC3 (grammi)" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_action +#: model:ir.model,name:bc3_importer.model_bc3_version +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "BC3 Version" +msgstr "Versione BC3" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_version_register +msgid "BC3 Version Register" +msgstr "Registrazione versione BC3" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_version_register_rule +msgid "BC3 Version Register Rule" +msgstr "Regola registrazione versione BC3" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_version_show +msgid "BC3 Versions" +msgstr "Versioni BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__bc3_file +msgid "BC3 file" +msgstr "File BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__bc3_file_name +msgid "BC3 file name" +msgstr "Nome file BC3" + +#. module: bc3_importer +#: model:product.template,description_sale:bc3_importer.product_product_product_cubic_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_g_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_l_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_square_meter_product_template +#: model:product.template,description_sale:bc3_importer.product_product_product_template_cubic_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_g +#: model:product.template,description_sale:bc3_importer.product_product_product_template_l +#: model:product.template,description_sale:bc3_importer.product_product_product_template_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_square_meter +#: model:product.template,description_sale:bc3_importer.product_product_product_template_units +#: model:product.template,description_sale:bc3_importer.product_product_product_units_product_template +msgid "BC3 product that will be used if imported product does not exist." +msgstr "Prodotto BC3 che verrà utilizzato se il prodotto importato non esiste." + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3 +msgid "BC3 sale order" +msgstr "Ordine vendita BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_base_url +msgid "Base url" +msgstr "URL base" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_import_wizard_form +msgid "Cancel" +msgstr "Annulla" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_certification_date +msgid "Certification date" +msgstr "Data certificazione" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_certification_number +msgid "Certification number" +msgstr "Numero certificazione" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_character_set +msgid "Character set" +msgstr "Set caratteri" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__is_child +msgid "Child" +msgstr "Figlio" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order_line__bc3_code +msgid "Code" +msgstr "Codice" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_comment +msgid "Comment" +msgstr "Commento" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.action_quotations_bc3 +msgid "Create a new quotation, the first step of a new sale!" +msgstr "Crea un nuovo preventivo, il primo passo di una nuova vendita!" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_products +msgid "Create non-existent products" +msgstr "Crea prodotti non esistenti" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__create_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__create_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__partner_id +msgid "Customer/Vendor" +msgstr "Cliente/venditore" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__product_id +msgid "Default product" +msgstr "Prodotto predefinito" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Description" +msgstr "Descrizione" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__display_name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Dynamic Product " +msgstr "Prodotto dinamico " + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/models/bc3_version.py:0 +#, python-format +msgid "Error in register description or not enough rules" +msgstr "Errore nella descrizione registrazione o regole non sufficienti" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Error parsing the file" +msgstr "Errore nell'elaborare il file" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__field_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__field_ids +msgid "Field" +msgstr "Campo" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_file_property +msgid "File property" +msgstr "Proprietà file" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_header +msgid "Header" +msgstr "Intestazione" + +#. module: bc3_importer +#: model:ir.module.category,description:bc3_importer.module_bc3_importer_bc3 +msgid "Helps you handle your bc3 files, versions and registers." +msgstr "Aiuta la gestione dei file, versioni e registrazioni BC3." + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__id +msgid "ID" +msgstr "ID" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_identifying_label +msgid "Identifying label" +msgstr "Etichetta identificazione" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_import_wizard_form +msgid "Import" +msgstr "Importa" + +#. module: bc3_importer +#: model:ir.ui.menu,name:bc3_importer.bc3_files_import +msgid "Import BC3" +msgstr "Importa BC3" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_import_wizard_action +msgid "Import BC3 File" +msgstr "Importa file BC3" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_bc3_import_wizard +msgid "Import BC3 file" +msgstr "Importa file BC3" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_information_type +msgid "Information Type" +msgstr "Tipo informazione" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register____last_update +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__write_uid +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__write_date +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__model_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__model_id +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Model" +msgstr "Modello" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__name +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__name +msgid "Name" +msgstr "Nome" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_action +msgid "No bc3 version found. Let's create one!" +msgstr "Nessuna versione BC3 trovata. Creiamone una!" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_register_action +msgid "No register found. Let's create one!" +msgstr "Nessuna registrazione trovata. Creiamone una!" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.bc3_version_register_rule_action +msgid "No register rule found. Let's create one!" +msgstr "Nessuna regola registrazione trovata. Creiamone una!" + +#. module: bc3_importer +#: model_terms:ir.actions.act_window,help:bc3_importer.action_quotations_bc3 +msgid "" +"Once the quotation is confirmed by the customer, it becomes a sales " +"order.
You will be able to create an invoice and collect the payment." +msgstr "" +"Una volta che il preventivo è confermato dal cliente, diventa un ordine di " +"vendita.
Si potrà creare una fattura e registrare i pagamenti." + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Parsing error, missing data" +msgstr "Errore elaborazione, dati mancanti" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__primary_key +msgid "Primary key" +msgstr "Chiave primaria" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_program +msgid "Program" +msgstr "Programma" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__project_id +msgid "Project" +msgstr "Progetto" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__register_id +msgid "Register" +msgstr "Registro" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_register_rule_action +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_rule_form_view +msgid "Register Rule" +msgstr "Regola registro" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/models/bc3_version.py:0 +#, python-format +msgid "Register name should unique" +msgstr "Il nome registro deve essere univoco" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version__register_ids +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "Registers" +msgstr "Registri" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__regular_expression +msgid "Regular expression" +msgstr "Espressione regolare" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__description +msgid "Rule Description" +msgstr "Descrizione regola" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__rule_ids +msgid "Rule Lines" +msgstr "Righe regola" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Rules" +msgstr "Regole" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__sale_id +msgid "Sale Order" +msgstr "Ordine di vendita" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_sale_order +msgid "Sales Order" +msgstr "Ordine di vendita" + +#. module: bc3_importer +#: model:ir.model,name:bc3_importer.model_sale_order_line +msgid "Sales Order Line" +msgstr "Riga ordine di vendita" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.action_orders_bc3 +msgid "Sales Orders" +msgstr "Ordini di vendita" + +#. module: bc3_importer +#: model:ir.model.fields,help:bc3_importer.field_bc3_import_wizard__product_id +msgid "Select a product which will be used in the BC3 file." +msgstr "Selezionare un prodotto che verrà utilizzato nel file BC3." + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__sequence +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register_rule__sequence +msgid "Sequence" +msgstr "Sequenza" + +#. module: bc3_importer +#. odoo-python +#: code:addons/bc3_importer/wizard/bc3_import_wizard.py:0 +#, python-format +msgid "Show Sale Order" +msgstr "Visualizza ordine di vendita" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__edit_existent +msgid "The register may edit existent records" +msgstr "La registrazione può modificare i record esistenti" + +#. module: bc3_importer +#: model:res.groups,name:bc3_importer.group_bc3_user +msgid "User" +msgstr "Utente" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_import_wizard__version_id +#: model:ir.model.fields,field_description:bc3_importer.field_bc3_version_register__version_id +msgid "Version" +msgstr "Versione" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_version_format +msgid "Version / Format" +msgstr "Versione / formato" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.view_sales_order_bc3 +msgid "Version Information" +msgstr "Informazioni versione" + +#. module: bc3_importer +#: model:ir.actions.act_window,name:bc3_importer.bc3_version_register_action +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "Version Register" +msgstr "Registrazione versione" + +#. module: bc3_importer +#: model:ir.model.fields,field_description:bc3_importer.field_sale_order__bc3_version_date +msgid "Version date" +msgstr "Data versione" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_form_view +msgid "e.g. FIEBDC-3-2020v2" +msgstr "es. FIEBDC-3-2020v2" + +#. module: bc3_importer +#: model_terms:ir.ui.view,arch_db:bc3_importer.bc3_version_register_form_view +msgid "e.g. ~K" +msgstr "es. ~K" + +#. module: bc3_importer +#: model:uom.uom,name:bc3_importer.product_uom_square_meter +msgid "m2" +msgstr "m2" diff --git a/bc3_importer/models/__init__.py b/bc3_importer/models/__init__.py new file mode 100644 index 0000000..51d3907 --- /dev/null +++ b/bc3_importer/models/__init__.py @@ -0,0 +1,2 @@ +from . import bc3_version +from . import sale_order diff --git a/bc3_importer/models/bc3_version.py b/bc3_importer/models/bc3_version.py new file mode 100644 index 0000000..274f90d --- /dev/null +++ b/bc3_importer/models/bc3_version.py @@ -0,0 +1,165 @@ +import logging +import re + +from iteration_utilities import duplicates + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + +_logger = logging.getLogger(__name__) + + +class Bc3Version(models.Model): + _name = "bc3.version" + _description = "BC3 Version" + _order = "name" + name = fields.Char(required=True) + register_ids = fields.One2many( + "bc3.version.register", "version_id", string="Registers" + ) + + @api.constrains("register_ids") + def _check_registers(self): + for record in self: + if record.register_ids: + register_name = record.register_ids.mapped("name") + if len(list(duplicates(register_name))) > 0: + raise ValidationError(_("Register name should unique")) + + +class Bc3VersionRegister(models.Model): + _name = "bc3.version.register" + _description = "BC3 Version Register" + _order = "name" + name = fields.Selection( + selection=[ + ("v", "~V"), + ("k", "~K"), + ("c", "~C"), + ("d", "~D"), + ("t", "~T"), + ("g", "~G"), + ("f", "~F"), + ], + required=True, + ) + description = fields.Text("Rule Description") + rule_ids = fields.One2many( + "bc3.version.register.rule", "register_id", string="Rule Lines" + ) + version_id = fields.Many2one("bc3.version", string="Version", ondelete="cascade") + model_id = fields.Many2one( + "ir.model", + "Model", + required=True, + ondelete="cascade", + domain=[ + "|", + "|", + ("model", "=", "sale.order"), + ("model", "=", "sale.order.line"), + ("model", "=", "product.product"), + ], + ) + edit_existent = fields.Boolean("The register may edit existent records") + + @api.onchange("description", "rule_ids") + def get_regular_expression(self): + if self.description and self.rule_ids: + self.description[0].lower() + register_line = self.description[1:].rstrip().strip().split("|") + register_line.pop(0) + len_rule_child = len(self.rule_ids.filtered(lambda x: not x.is_child)) + if len(register_line) > len_rule_child: + del register_line[-1] + if not len(register_line) == len( + self.rule_ids.filtered(lambda x: not x.is_child) + ): + raise ValidationError( + _("Error in register description or not enough rules") + ) + i = 0 + for rule in self.rule_ids.filtered(lambda x: not x.is_child): + rule.generate_regular_expression(register_line[i]) + i += 1 + + +class Bc3VersionRegisterRule(models.Model): + _name = "bc3.version.register.rule" + _description = "BC3 Version Register Rule" + _order = "sequence" + + sequence = fields.Integer() + model_id = fields.Many2one("ir.model", ondelete="cascade") + field_id = fields.Many2one( + "ir.model.fields", + "Field", + domain=[ + ("model_id", "=", model_id), + ( + "ttype", + "not in", + [ + "many2one_reference", + "reference", + "serialized", + "job_serialized", + "selection", + ], + ), + ], + ondelete="cascade", + ) + register_id = fields.Many2one( + "bc3.version.register", string="Register", ondelete="cascade" + ) + is_child = fields.Boolean("Child") + regular_expression = fields.Char("Regular expression") + primary_key = fields.Boolean("Primary key") + field_ids = fields.Many2many( + "ir.model.fields", + string="Field", + domain=[ + ( + "ttype", + "not in", + [ + "many2one_reference", + "reference", + "serialized", + "job_serialized", + "selection", + ], + ), + ], + ondelete="cascade", + ) + + def generate_regular_expression(self, line): + code = line + code = code.replace(" ", "").replace("\\", "\\\\?") + pattern3 = r"[^<>\\\[\]{}?]+" + replacement2 = r'([à-ü-À-Üa-zA-Z0-9_.+#;,":/\ \-\%\²\³\=\€\ª\º]+)' + html = re.sub(pattern3, replacement2, code) + pattern6 = r"\{" + replacement6 = "(" + pattern7 = r"\}" + replacement7 = ")*" + html = re.sub(pattern6, replacement6, html) + html = re.sub(pattern7, replacement7, html) + pattern8 = r"\(\\.*\)\*" + replacement8 = '(\\?[à-ü-À-Üa-zA-Z0-9_+.#;,":/\\ \\-\\%\\²\\³\\=\\€\\ª\\º]+)*' + html = re.sub(pattern8, replacement8, html) + html = html.replace("(\\?", "(\\\\?") + pattern9 = r"\[\([^?]*\)\]" + replacement9 = '([à-ü-À-Üa-zA-Z0-9_+.#,:";/\\ \\-\\%\\²\\³\\=\\€\\ª\\º]+)*' + html = re.sub(pattern9, replacement9, html) + pattern10 = r"\[\\.*\+\)\]" + replacement10 = '(\\?[à-ü-À-Üa-zA-Z0-9_+.#,:";/\\ \\-\\%\\²\\³\\=\\€\\ª\\º]+)*' + html = re.sub(pattern10, replacement10, html) + html = html.replace("(\\?", "(\\\\?") + pattern11 = r"\(\(.*\+\)\\\\\?\)\*" + replacement11 = r'([à-ü-À-Üa-zA-Z0-9_+.#,:";/\ \-\%\²\³\=\€\ª\º]+\\\\?)*' + html = re.sub(pattern11, replacement11, html) + html = html.replace("<", "").replace(">", "") + self.regular_expression = html diff --git a/bc3_importer/models/sale_order.py b/bc3_importer/models/sale_order.py new file mode 100644 index 0000000..8ead1d8 --- /dev/null +++ b/bc3_importer/models/sale_order.py @@ -0,0 +1,23 @@ +from odoo import fields, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + bc3 = fields.Boolean("BC3 sale order") + bc3_file_property = fields.Char("File property") + bc3_version_format = fields.Char("Version / Format") + bc3_version_date = fields.Date("Version date") + bc3_program = fields.Char("Program") + bc3_header = fields.Char("Header") + bc3_identifying_label = fields.Char("Identifying label") + bc3_character_set = fields.Char("Character set") + bc3_comment = fields.Text("Comment") + bc3_information_type = fields.Char("Information Type") + bc3_certification_number = fields.Char("Certification number") + bc3_certification_date = fields.Date("Certification date") + bc3_base_url = fields.Char("Base url") + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + bc3_code = fields.Char("Code") diff --git a/bc3_importer/pyproject.toml b/bc3_importer/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/bc3_importer/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/bc3_importer/readme/CONTRIBUTORS.md b/bc3_importer/readme/CONTRIBUTORS.md new file mode 100644 index 0000000..3c6c785 --- /dev/null +++ b/bc3_importer/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- [Binhex](https://binhex.cloud): + + > - Zuzanna Elzbieta Szalaty Szalaty \ diff --git a/bc3_importer/readme/DESCRIPTION.md b/bc3_importer/readme/DESCRIPTION.md new file mode 100644 index 0000000..0bc2c0f --- /dev/null +++ b/bc3_importer/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Importer of quotations in bc3 format. diff --git a/bc3_importer/security/bc3_file_security.xml b/bc3_importer/security/bc3_file_security.xml new file mode 100644 index 0000000..820b271 --- /dev/null +++ b/bc3_importer/security/bc3_file_security.xml @@ -0,0 +1,27 @@ + + + + BC3 + + Helps you handle your bc3 files, versions and registers. + 10 + + + + User + + + + + + Administrator + + + + + diff --git a/bc3_importer/security/ir.model.access.csv b/bc3_importer/security/ir.model.access.csv new file mode 100644 index 0000000..313adac --- /dev/null +++ b/bc3_importer/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_bc3_import_wizard,bc3.import.wizard,model_bc3_import_wizard,bc3_importer.group_bc3_user,1,0,0,0 +access_bc3_version,bc3.version,model_bc3_version,bc3_importer.group_bc3_user,1,0,0,0 +access_bc3_version_register,bc3.version.register,model_bc3_version_register,bc3_importer.group_bc3_user,1,0,0,0 +access_bc3_version_register_rule,bc3.version.register.rule,model_bc3_version_register_rule,bc3_importer.group_bc3_user,1,0,0,0 +access_bc3_import_wizard_manager,bc3.import.wizard.manager,model_bc3_import_wizard,bc3_importer.group_bc3_manager,1,1,1,1 +access_bc3_version_manager,bc3.version-manager,model_bc3_version,bc3_importer.group_bc3_manager,1,1,1,1 +access_bc3_version_register_manager,bc3.version.register.manager,model_bc3_version_register,bc3_importer.group_bc3_manager,1,1,1,1 +access_bc3_version_register_rule_manager,bc3.version.register.rule.manager,model_bc3_version_register_rule,bc3_importer.group_bc3_manager,1,1,1,1 diff --git a/bc3_importer/static/description/icon.png b/bc3_importer/static/description/icon.png new file mode 100644 index 0000000..45b3422 Binary files /dev/null and b/bc3_importer/static/description/icon.png differ diff --git a/bc3_importer/static/description/index.html b/bc3_importer/static/description/index.html new file mode 100755 index 0000000..d000923 --- /dev/null +++ b/bc3_importer/static/description/index.html @@ -0,0 +1,429 @@ + + + + + +BC3 files importer + + + +
+

BC3 files importer

+ + +

Beta License: AGPL-3 OCA/vertical-construction Translate me on Weblate Try me on Runboat

+

Importer of quotations in bc3 format.

+

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

+
    +
  • Binhex
  • +
+
+
+

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

+

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

+
+
+
+ + diff --git a/bc3_importer/tests/__init__.py b/bc3_importer/tests/__init__.py new file mode 100644 index 0000000..ce1d18d --- /dev/null +++ b/bc3_importer/tests/__init__.py @@ -0,0 +1,2 @@ +from . import test_bc3_import_wizard +from . import test_bc3_version diff --git a/bc3_importer/tests/bc3_file_test.bc3 b/bc3_importer/tests/bc3_file_test.bc3 new file mode 100644 index 0000000..fb06cb6 --- /dev/null +++ b/bc3_importer/tests/bc3_file_test.bc3 @@ -0,0 +1,4 @@ +~V|SOFT S.A.|FIEBDC-3/2002|Presto 8.8||ANSI|\n' +'~K|\2\2\3\2\2\2\2\EUR\|0|\n' +'~C|%0.03||Medios Auxiliares|10|030223|0|\n' +'~C|A03B0010|m³|Hormigón aligerado de cemento y picón.|38.34|011222|3| diff --git a/bc3_importer/tests/test_bc3_import_wizard.py b/bc3_importer/tests/test_bc3_import_wizard.py new file mode 100644 index 0000000..c5986b2 --- /dev/null +++ b/bc3_importer/tests/test_bc3_import_wizard.py @@ -0,0 +1,33 @@ +import base64 +import os + +from odoo.addons.base.tests.common import BaseCommon + +__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + + +class TestBC3ImportWizard(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + with open(os.path.join(__location__, "bc3_file_test.bc3"), "rb") as file: + bc3_content = file.read() + cls.bc3_import_wizard = cls.env["bc3.import.wizard"].create( + { + "bc3_file": base64.b64encode(bc3_content), + "bc3_file_name": "test.bc3", + "project_id": cls.env.ref("project.project_project_1").id, + "version_id": cls.env.ref("bc3_importer.bc3_version_2020_v2").id, + "partner_id": cls.env.ref("base.res_partner_1").id, + "create_products": False, + "sale_id": cls.env.ref("sale.sale_order_1").id, + } + ) + + def test_do_action(self): + result = self.bc3_import_wizard.do_action() + self.assertEqual(result["res_model"], "sale.order", "Wrong model") + self.assertEqual(result["res_id"], self.bc3_import_wizard.sale_id.id) + self.assertEqual(result["view_mode"], "form") + self.assertEqual(result["target"], "current") + self.assertEqual(result["type"], "ir.actions.act_window") diff --git a/bc3_importer/tests/test_bc3_version.py b/bc3_importer/tests/test_bc3_version.py new file mode 100644 index 0000000..7e6d932 --- /dev/null +++ b/bc3_importer/tests/test_bc3_version.py @@ -0,0 +1,60 @@ +from odoo.exceptions import ValidationError +from odoo.addons.base.tests.common import BaseCommon + + +class TestBC3Version(BaseCommon): + def setUp(self): + super().setUp() + self.bc3_version = self.env["bc3.version"].create({"name": "Test Version"}) + self.bc3_version_register = self.env["bc3.version.register"].create( + { + "name": "v", + "description": "v|rule1|rule2|rule3", + "version_id": self.bc3_version.id, + "model_id": self.env.ref("base.model_res_partner").id, + } + ) + self.bc3_version_register_rule_1 = self.env["bc3.version.register.rule"].create( + { + "sequence": 1, + "model_id": self.env.ref("base.model_res_partner").id, + "field_id": self.env.ref("base.field_res_partner__name").id, + "register_id": self.bc3_version_register.id, + "is_child": False, + } + ) + self.bc3_version_register_rule_2 = self.env["bc3.version.register.rule"].create( + { + "sequence": 2, + "model_id": self.env.ref("base.model_res_partner").id, + "field_id": self.env.ref("base.field_res_partner__email").id, + "register_id": self.bc3_version_register.id, + "is_child": False, + } + ) + self.bc3_version_register_rule_3 = self.env["bc3.version.register.rule"].create( + { + "sequence": 3, + "model_id": self.env.ref("base.model_res_partner").id, + "field_id": self.env.ref("base.field_res_partner__phone").id, + "register_id": self.bc3_version_register.id, + "is_child": False, + } + ) + + def test_get_regular_expression_success(self): + self.bc3_version_register.get_regular_expression() + self.assertTrue(self.bc3_version_register_rule_1.regular_expression) + self.assertTrue(self.bc3_version_register_rule_2.regular_expression) + self.assertTrue(self.bc3_version_register_rule_3.regular_expression) + + def test_get_regular_expression_error_in_description(self): + self.bc3_version_register.description = "v|rule1" + with self.assertRaises(ValidationError): + self.bc3_version_register.get_regular_expression() + + def test_get_regular_expression_not_enough_rules(self): + self.bc3_version_register_rule_2.unlink() + self.bc3_version_register_rule_3.unlink() + with self.assertRaises(ValidationError): + self.bc3_version_register.get_regular_expression() diff --git a/bc3_importer/views/bc3_version_views.xml b/bc3_importer/views/bc3_version_views.xml new file mode 100644 index 0000000..768d2f7 --- /dev/null +++ b/bc3_importer/views/bc3_version_views.xml @@ -0,0 +1,161 @@ + + + + + BC3 Version + bc3.version + tree,form + +

+ No bc3 version found. Let's create one! +

+
+
+ + bc3.version.form + bc3.version + +
+ +
+

+ +

+
+ + + +
+
+
+
+ + bc3.version.tree + bc3.version + + + + + + + + + + + + Version Register + bc3.version.register + tree,form + +

+ No register found. Let's create one! +

+
+
+ + bc3.version.form.register + bc3.version.register + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + bc3.version.register.tree + bc3.version.register + + + + + + + + + Register Rule + bc3.version.register.rule + tree,form + +

+ No register rule found. Let's create one! +

+
+
+ + + bc3.version.register.rule.form + bc3.version.register.rule + +
+ + + + + + + + + + + +
+
+
+ + bc3.version.register.rule.tree + bc3.version.register.rule + + + + + + + +
diff --git a/bc3_importer/views/sale_order_views.xml b/bc3_importer/views/sale_order_views.xml new file mode 100644 index 0000000..b8478de --- /dev/null +++ b/bc3_importer/views/sale_order_views.xml @@ -0,0 +1,91 @@ + + + + BC3 Quotations + ir.actions.act_window + sale.order + + tree,kanban,form,calendar,pivot,graph,activity + + [('bc3', '=', True)] + {'default_bc3': 1} + +

+ Create a new quotation, the first step of a new sale! +

+ Once the quotation is confirmed by the customer, it becomes a sales order.
You will be able to create an invoice and collect the payment. +

+
+
+ + Sales Orders + ir.actions.act_window + sale.order + tree,form,calendar,graph,kanban,pivot + + [('state', 'not in', ('draft', 'sent', 'cancel'))] + {'default_bc3': 1} + + + sale.order.form + sale.order + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/bc3_importer/wizard/__init__.py b/bc3_importer/wizard/__init__.py new file mode 100644 index 0000000..2d79918 --- /dev/null +++ b/bc3_importer/wizard/__init__.py @@ -0,0 +1 @@ +from . import bc3_import_wizard diff --git a/bc3_importer/wizard/bc3_import_wizard.py b/bc3_importer/wizard/bc3_import_wizard.py new file mode 100644 index 0000000..7cfc90d --- /dev/null +++ b/bc3_importer/wizard/bc3_import_wizard.py @@ -0,0 +1,1052 @@ +import base64 +import os +import re +import tempfile +from datetime import datetime + +import chardet + +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError + +BC3_PRODUCTS = {} +created_product = False +parse_later = [] +lines = {} +erase_lines = [] + + +class BC3ImportWizard(models.TransientModel): + _name = "bc3.import.wizard" + _description = "Import BC3 file" + + @api.model + def _default_version(self): + return self.env.ref("bc3_importer.bc3_version_2020_v2") or self.env[ + "bc3.version" + ].search([], limit=1) + + bc3_file = fields.Binary(string="BC3 file", required=True) + bc3_file_name = fields.Char(string="BC3 file name") + project_id = fields.Many2one("project.project", string="Project") + version_id = fields.Many2one( + "bc3.version", string="Version", ondelete="cascade", default=_default_version + ) + partner_id = fields.Many2one( + comodel_name="res.partner", + string="Customer/Vendor", + store=True, + readonly=False, + ondelete="restrict", + domain="['|', ('parent_id','=', False), ('is_company','=', True)]", + check_company=True, + ) + company_id = fields.Many2one( + "res.company", + string="Company", + default = lambda self: self.env.company, + readonly=True + ) + create_products = fields.Boolean("Create non-existent products") + product_id = fields.Many2one( + "product.product", + string="Default product", + ondelete="cascade", + help="Select a product which will be used in the BC3 file.", + ) + sale_id = fields.Many2one("sale.order", "Sale Order") + sequence = fields.Integer() + + def do_action(self): + self.ensure_one() + self.get_uom_products() + self.sequence = 0 + self.sale_id = ( + self.env["sale.order"] + .create({"partner_id": self.partner_id.id, "bc3": True}) + .id + ) + # decode the base64 encoded data + data = base64.decodebytes(self.bc3_file) + # create a temporary file, and save the bc3 + fobj = tempfile.NamedTemporaryFile(delete=False) + fname = fobj.name + fobj.write(data) + fobj.close() + try: + rawdata = open(fname, "rb").read() + encoding = chardet.detect(rawdata)["encoding"] + file_content = list( + filter( + None, + open(fname, encoding=encoding, errors="replace").read().split("~"), + ) + ) + for f in file_content: + self._parse_register(f) + # do stuff here + finally: + # delete the file when done + os.unlink(fname) + seq = 0 + line_ids = [] + sorted_chapters = dict(sorted(lines.items())) + for key in sorted_chapters: + s = ( + self.env["sale.order.line"] + .sudo() + .search( + [("bc3_code", "=", key), ("order_id", "=", self.sale_id.id)], + limit=1, + ) + ) + if s and ( + (s.price_unit == 1 and s.product_uom_qty == 1) + or (s.price_unit == 0 and s.product_uom_qty == 1) + or ("%" in s.bc3_code) + or (s.price_unit == 1) + ): + s.sudo().unlink() + self.env["sale.order.line"].sudo().search( + [("id", "in", sorted_chapters[key])] + ).unlink() + elif s: + if s.id not in line_ids: + line_ids.append(s.id) + s.write({"sequence": seq}) + seq += 1 + for line in ( + self.env["sale.order.line"] + .sudo() + .search( + [ + ("order_id", "=", self.sale_id.id), + ("id", "in", sorted_chapters[key]), + ] + ) + .sorted("name") + ): + if line: + if ( + (line.price_unit == 1 and line.product_uom_qty == 1) + or (line.price_unit == 0 and line.product_uom_qty == 1) + or ("%" in line.bc3_code) + or (line.price_unit == 1) + or not line.price_subtotal + ): + line.sudo().unlink() + elif line.id not in line_ids: + line_ids.append(line.id) + line.sudo().write({"sequence": seq}) + seq += 1 + elif not s and key == "0": + for line in ( + self.env["sale.order.line"] + .sudo() + .search( + [ + ("order_id", "=", self.sale_id.id), + ("id", "in", sorted_chapters[key]), + ] + ) + .sorted("name") + ): + if line: + if ( + (line.price_unit == 1 and line.product_uom_qty == 1) + or (line.price_unit == 0 and line.product_uom_qty == 1) + or ("%" in line.bc3_code) + or (line.price_unit == 1) + ): + line.sudo().unlink() + else: + line_ids.append(line.id) + line.sudo().write({"sequence": seq}) + seq += 1 + for s in self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id)], order="sequence asc" + ): + if ( + (s.price_unit == 1 and s.product_uom_qty == 1) + or (s.price_unit == 0 and s.product_uom_qty == 1) + or (s.bc3_code and "%" in s.bc3_code) + or (s.price_unit == 1) + ) and not s.display_type: + s.sudo().unlink() + elif s.id not in line_ids and not s.display_type == "line_note": + s.sudo().unlink() + elif s.bc3_code not in lines and s.display_type == "line_section": + s.sudo().unlink() + elif s.display_type == "line_section": + next_sequence = ( + self.env["sale.order.line"] + .sudo() + .search( + [ + ("order_id", "=", self.sale_id.id), + ("display_type", "=", "line_section"), + ("sequence", ">", s.sequence), + ], + limit=1, + ) + ) + if next_sequence and next_sequence.sequence == s.sequence + 1: + s.sudo().unlink() + for c in erase_lines: + line = ( + self.env["sale.order.line"] + .sudo() + .search([("bc3_code", "=", c), ("order_id", "=", self.sale_id.id)]) + ) + if line and c not in lines: + line.sudo().unlink() + return { + "name": _("Show Sale Order"), + "type": "ir.actions.act_window", + "view_type": "form", + "view_mode": "form", + "res_model": "sale.order", + "views": [(self.env.ref("sale.view_order_form").id, "form")], + "view_id": self.env.ref("sale.view_order_form").id, + "target": "current", + "res_id": self.sale_id.id, + } + + def parse_line(self, line): + split_line = line.rstrip().strip().split("|") + return split_line + + @api.model + def _parse_register_sale_order( + self, parsed_line, rules, current_register, red=False + ): + if len(parsed_line) == len(rules): + i = 0 + for rule in rules: + if len(parsed_line[i]) == 1: + self.sale_id[rule.field_id.name] = self._parse_data( + parsed_line[i][0], rule.field_id.ttype + ) + elif len(parsed_line[i]) > 1: + if self.sale_id[rule.field_id.name]: + self.sale_id[rule.field_id.name] += self._parse_child_data( + parsed_line[i], rule.field_id.ttype + ) + else: + self.sale_id[rule.field_id.name] = self._parse_child_data( + parsed_line[i], rule.field_id.ttype + ) + i += 1 + return True + + # and "\\" not in line[i] + @api.model + def _parse_register_product_product(self, line, rules, current_register, red=False): + return True + + @api.model + def _search_create_product(self, code): + product = self.env["product.template"].search( + [("default_code", "ilike", code[0])], limit=1 + ) + if product: + return product + else: + if self.create_products: + code_temp = "" + if len(code) > 1: + for c in code: + code_temp += c + "-" + else: + code_temp = code + product = self.env["product.template"].create( + { + "name": _("Dynamic Product ") + code_temp, + "default_code": code_temp, + } + ) + else: + # Por defecto se ponen unidades + product = self.env.ref("bc3_importer.product_product_product_units") + return product + + @api.model + def _search_create_uom(self, name): + uom = False + if name == "m3" or name == "M3" or name == "m³": + uom = self.env.ref("uom.product_uom_cubic_meter").id or False + elif name == "m²" or name == "M2" or name == "m2": + uom = self.env.ref("bc3_importer.product_uom_square_meter").id or False + elif name == "ud": + uom = self.env.ref("uom.product_uom_unit").id or False + else: + uom = ( + self.env["uom.uom"] + .search( + [ + "|", + "|", + ("name", "ilike", name), + ("name", "ilike", name.upper()), + ("name", "ilike", name.lower()), + ], + limit=1, + ) + .id + or False + ) + return uom + + def _parse_repeats_line(self, existent_line, temp_line, sale_order_line): + create_line = False + if ( + existent_line + and not existent_line.id == sale_order_line.id + and not existent_line.display_type + and not sale_order_line.display_type + ): + if not self.line_in_any_dict(sale_order_line.id): + erase_lines.append(temp_line["bc3_code"]) + return + if existent_line and not existent_line.id == sale_order_line.id and lines: + if ( + not self.line_in_dict(existent_line.bc3_code, sale_order_line.id) + and sale_order_line.id not in self.sale_id.order_line.ids + ): + create_line = True + elif self.line_in_any_dict(sale_order_line.id): + create_line = True + if create_line: + sale_order_line = sale_order_line.copy( + { + "order_id": self.sale_id.id, + "price_unit": sale_order_line.price_unit, + } + ) + if ( + sale_order_line + and "price_unit" in temp_line + and float(temp_line["price_unit"]) == 1.0 + ): + temp_line["price_unit"] = sale_order_line.price_unit + sale_order_line.sudo().write(temp_line) + else: + if ( + "product_uom_qty" in temp_line + and float(temp_line["product_uom_qty"]) == 1.0 + and sale_order_line.product_uom_qty + and not sale_order_line.display_type + ): + temp_line["product_uom_qty"] = sale_order_line.product_uom_qty + elif not sale_order_line.product_uom_qty == 1: + temp_line["product_uom_qty"] = ( + float(temp_line["product_uom_qty"]) + + sale_order_line.product_uom_qty + ) + if ( + "price_unit" in temp_line + and float(temp_line["price_unit"]) == 1.0 + and not sale_order_line.display_type + ): + temp_line["price_unit"] = sale_order_line.price_unit + if "name" in temp_line and sale_order_line.name: + temp_line["name"] = sale_order_line.name + "-" + temp_line["name"] + if sale_order_line.display_type: + temp_line["product_uom_qty"] = 0 + temp_line["price_unit"] = 0 + sale_order_line.sudo().write(temp_line) + if ( + existent_line + and not existent_line.id == sale_order_line.id + and existent_line.display_type + and existent_line.display_type == "line_section" + ): + if existent_line.bc3_code in lines: + lines[existent_line.bc3_code].append(sale_order_line.id) + else: + lines[existent_line.bc3_code] = [sale_order_line.id] + + def _parse_repeats_line_product(self, temp_line, seq, existent_line): + product = self.env.ref("bc3_importer.product_product_product_units") + if "bc3_code" in temp_line: + temp_line["name"] = temp_line["bc3_code"] or product.default_code or "Line" + else: + temp_line["name"] = product.default_code or "Line" + temp_line["product_id"] = product.id + temp_line["product_uom"] = product.uom_id.id + temp_line["order_id"] = self.sale_id.id + temp_line["sequence"] = seq + if "price_unit" in temp_line and float(temp_line["price_unit"]) == 1.0: + s = self.env["sale.order.line"].search( + [ + ("order_id", "=", self.sale_id.id), + ("bc3_code", "=", temp_line["bc3_code"]), + ("price_unit", ">", 1), + ], + limit=1, + ) + if s: + temp_line["price_unit"] = s.price_unit + sale_order_line = self.env["sale.order.line"].create(temp_line) + if ( + existent_line + and not existent_line.id == sale_order_line.id + and existent_line.display_type + and existent_line.display_type == "line_section" + ): + if existent_line.bc3_code in lines: + lines[existent_line.bc3_code].append(sale_order_line.id) + else: + lines[existent_line.bc3_code] = [sale_order_line.id] + + def _parse_repeats( + self, rules, i, dependent_rules, parsed_line, line, parent_seq, existent_line + ): + if rules[i] in dependent_rules: + z = 0 + while z < len(parsed_line[i]): + j = i + counter = 0 + temp_line = {} + if parent_seq: + seq = parent_seq + 1 + # self.lines_reorder(seq) + else: + seq = self.sequence + self.sequence += 1 + while counter < len(dependent_rules[rules[i]]): + if len(parsed_line[j]) == 0: + temp_line[ + dependent_rules[rules[i]][counter]["field_id"]["name"] + ] = False + else: + temp_line[ + dependent_rules[rules[i]][counter]["field_id"]["name"] + ] = parsed_line[j][z] + j += 1 + counter += 1 + z += 1 + temp_line["sequence"] = seq + sale_order_line = False + if "bc3_code" in temp_line: + sale_order_line = self.env["sale.order.line"].search( + [ + ("order_id", "=", self.sale_id.id), + ("bc3_code", "=", temp_line["bc3_code"]), + ] + ) + if len(sale_order_line) > 1: + if existent_line: + chapter = existent_line.bc3_code + for s in sale_order_line: + if chapter in lines and s.id in lines[chapter]: + sale_order_line = s + else: + sale_order_line = False + if sale_order_line: + self._parse_repeats_line(existent_line, temp_line, sale_order_line) + else: + self._parse_repeats_line_product(temp_line, seq, existent_line) + + if line: + line = {} + + def _update_line(self, line, seq): + s = False + if "bc3_code" in line: + line["bc3_code"] = line["bc3_code"].replace("#", "") + s = self.env["sale.order.line"].search( + [ + ("order_id", "=", self.sale_id.id), + ("bc3_code", "=", line["bc3_code"].replace("#", "")), + ] + ) + if s: + for sale_order_line in s: + if sale_order_line.bc3_code in erase_lines: + erase_lines.remove(sale_order_line.bc3_code) + if ( + "product_uom_qty" in line + and sale_order_line.product_uom_qty + and not sale_order_line.display_type + ): + line["product_uom_qty"] = float(line["product_uom_qty"]) + float( + sale_order_line.product_uom_qty + ) + if ( + "price_unit" in line + and sale_order_line.price_unit + and sale_order_line.price_unit > 1 + and line["price_unit"] == 1 + and not sale_order_line.display_type + ): + line["price_unit"] = sale_order_line.price_unit + if "name" in line and sale_order_line.name: + if sale_order_line.name not in line["name"]: + line["name"] = sale_order_line.name + "- " + line["name"] + if sale_order_line.display_type: + line["product_uom_qty"] = 0 + line["price_unit"] = 0 + sale_order_line.sudo().write(line) + + else: + product = self.env.ref("bc3_importer.product_product_product_units") + + if "bc3_code" in line: + if "name" in line: + line["name"] = ( + line["bc3_code"] or product.default_code or "Line" + ) + line["name"] + else: + line["name"] = line["bc3_code"] or product.default_code or "Line" + else: + if "name" in line: + line["name"] = (product.default_code or "Line") + line["name"] + else: + line["name"] = product.default_code or "Line" + line["product_id"] = product.id + line["product_uom"] = product.uom_id.id + line["order_id"] = self.sale_id.id + line["sequence"] = seq + sale_order_line = self.env["sale.order.line"].create(line) + + def _parse_register_edit_sale_order_line( + self, parsed_line, rules, dependent_rules, rule_ids, current_register, red=False + ): + if len(parsed_line) == len(rules): + primary_key_id = parsed_line[0][0] + existent_line = self.search_line(primary_key_id.replace("#", "")) + parent_seq = False + # Está dentro de un capítulo + if existent_line: + parent_seq = existent_line.sequence + + elif "#" in primary_key_id and not existent_line: + existent_line = ( + self.env["sale.order.line"] + .sudo() + .create( + { + "name": primary_key_id.replace("#", ""), + "display_type": "line_section", + "bc3_code": primary_key_id.replace("#", ""), + "order_id": self.sale_id.id, + } + ) + ) + + i = 0 + seq = False + line = {} + while i < len(rules): + # Repetidos + if rules[i]["id"] in rule_ids: + self._parse_repeats( + rules, + i, + dependent_rules, + parsed_line, + line, + parent_seq, + existent_line, + ) + # Únicos + else: + if rules[i]["field_id"]["name"]: + if len(parsed_line[i]) > 0: + line[rules[i]["field_id"]["name"]] = parsed_line[i][0] + if parent_seq: + seq = parent_seq + 1 + # self.lines_reorder(seq) + else: + seq = self.sequence + self.sequence += 1 + line["sequence"] = seq + i += 1 + # Solo cuando actualiza un dato -> lo hago para todos + + if line: + self._update_line(line, seq) + + return + + @api.model + def search_seq_line(self, seq): + sale_order_line = self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id), ("bc3_code", "=", seq)], limit=1 + ) + return sale_order_line.sequence or False + + @api.model + def search_line(self, code): + code = code.replace("#", "") + a = self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id), ("bc3_code", "=", code)], limit=1 + ) + if not a: + a = self.env["sale.order.line"].search( + [ + ("order_id", "=", self.sale_id.id), + ("bc3_code", "=", code.split(".")[0]), + ], + limit=1, + ) + return a + + @api.model + def search_lines(self, code): + code = code.replace("#", "") + a = self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id), ("bc3_code", "=", code)] + ) + return a + + @api.model + def lines_reorder(self, seq): + sale_order_line = self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id), ("sequence", "=", seq)], limit=1 + ) + if sale_order_line: + for s in self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id), ("sequence", ">=", seq)] + ): + s.write({"sequence": s.sequence + 1}) + return + + def _parse_register_sale_order_line_sl( + self, rule, parsed_line, line, i, product_name, product + ): + if (not rule.field_id.relation) or ( + rule.field_id.relation and rule.field_id.relation == "product.template" + ): + if ( + not rule.field_id.name == "product_template_id" + and not rule.field_id.name == "categ_id" + ): + if len(parsed_line[i]) == 1 and parsed_line[i]: + line[rule.field_id.name] = self._parse_data( + parsed_line[i][0], rule.field_id.ttype + ) + elif len(parsed_line[i]) > 1: + if rule.field_id.name in line: + line[rule.field_id.name] += self._parse_child_data( + parsed_line[i], rule.field_id.ttype + ) + else: + line[rule.field_id.name] = self._parse_child_data( + parsed_line[i], rule.field_id.ttype + ) + elif rule.field_id.name == "product_template_id": + if len(parsed_line[i]) == 1 and parsed_line[i]: + product_name = self._parse_data( + parsed_line[i][0], rule.field_id.ttype + ) + elif rule.field_id.relation and rule.field_id.relation == "uom.uom": + if len(parsed_line[i]) == 1 and parsed_line[i]: + uom_id = int(self._search_create_uom(parsed_line[i][0])) + line[rule.field_id.name] = uom_id + if product and product.uom_id and not product.uom_id.id == uom_id: + if created_product: + product.uom_id = uom_id + else: + if uom_id in BC3_PRODUCTS: + product = BC3_PRODUCTS[uom_id] + else: + product = self.env.ref( + "bc3_importer.product_product_product_units" + ) + line["product_id"] = product.id + line["product_uom"] = product.uom_id.id + return product_name + + def _parse_line_t(self, line_t, line): + for t in line_t: + if t.display_type: + line["price_unit"] = 0.0 + line["product_id"] = False + line["product_uom_qty"] = 0.0 + line["product_uom"] = False + + if "display_type" in line and not t.display_type: + if not t.product_uom_qty > 1: + a = t.read(["sequence", "bc3_code"])[0] + a["order_id"] = self.sale_id.id + a.update(line) + t.unlink() + if "display_type" in a: + a["price_unit"] = 0.0 + a["product_id"] = False + a["product_uom_qty"] = 0.0 + a["product_uom"] = False + sale_order_line = self.env["sale.order.line"].create(a) + if ( + sale_order_line.display_type + and sale_order_line.display_type == "line_note" + ): + if "0" in lines: + lines["0"].append(sale_order_line.id) + else: + lines["0"] = [sale_order_line.id] + else: + line["display_type"] = False + t.write(line) + + else: + t.write(line) + if t.display_type and line_t.display_type == "line_note": + if "0" in lines: + lines["0"].append(line_t.id) + else: + lines["0"] = [line_t.id] + + @api.model + def _parse_register_sale_order_line( + self, parsed_line, rules, current_register, red=False + ): + product_name = "" + if len(parsed_line) == len(rules): + # Se busca el codigo del producto + if not len(parsed_line[0]) > 0: + return + if len(parsed_line[0]) > 0 and "%" in parsed_line[0][0]: + return + line_t = self.search_lines(parsed_line[0][0]) + product = self._search_create_product(parsed_line[0]) + if not line_t: + line = { + "name": product.default_code or parsed_line[0], + "product_id": product.id, + "product_uom_qty": 1, + "qty_delivered": 1, + "product_uom": product.uom_id.id, + "order_id": self.sale_id.id, + "sequence": self.sequence, + } + self.sequence += 1 + else: + line = {} + i = len(rules) - 1 + for rule in rules.sorted(key="sequence", reverse=True): + # Sale order line + if rule.model_id.model == "sale.order.line": + product_name = self._parse_register_sale_order_line_sl( + rule, parsed_line, line, i, product_name, product + ) + + elif rule.model_id.model == "product.template": + if len(parsed_line[i]) == 1: + line_type = int(self._parse_data(parsed_line[i][0], "char")) + if line_type == 0 and "##" in parsed_line[0][0]: + line["display_type"] = "line_note" + elif line_type == 0 and "#" in parsed_line[0][0]: + line["display_type"] = "line_section" + i -= 1 + line["name"] = "[" + line["bc3_code"] + "] " + product_name + if self.create_products: + product.name = product_name + if not line_t: + if "display_type" in line: + line["price_unit"] = 0.0 + line["product_id"] = False + line["product_uom_qty"] = 0.0 + line["product_uom"] = False + sale_order_line = self.env["sale.order.line"].create(line) + if ( + sale_order_line.display_type + and sale_order_line.display_type == "line_note" + ): + if "0" in lines: + lines["0"].append(sale_order_line.id) + else: + lines["0"] = [sale_order_line.id] + else: + self._parse_line_t(line_t, line) + return True + + @api.model + def _parse_data(self, data, field_type): + data = data.replace("\\", "").replace("#", "") + if field_type in ["char", "text"]: + return data + if field_type == "date": + # if odd -> 0 + if not len(data) % 2 == 0: + data += "0" + # AA + if len(data) == 2: + return datetime.strptime(data, "%y").date() + # MMAA + elif len(data) == 4: + return datetime.strptime(data, "%m%y").date() + # DDMMAA + elif len(data) == 6: + return datetime.strptime(data, "%d%m%y").date() + # DDMMAAAA + elif len(data) == 8: + return datetime.strptime(data, "%d%m%Y").date() + return data + return data + + @api.model + def _parse_child_data(self, data, field_type): + if field_type == "char" or field_type == "text": + result = "" + for d in data: + d = d.replace("\\", "").replace("\\\\", "") + result += d + ";" + return result + elif field_type == "float": + if len(data) > 0: + return float(data[-1].replace("\\", "")) + else: + return float(data.replace("\\", "")) + return data + + def _parse_register_data( + self, register_rules, register_line, current_register, model, render_func + ): + i = 0 + regular_expression = [] + parser_result = [] + for r in register_rules.filtered(lambda x: not x.is_child): + regular_expression.append(r.regular_expression) + if len(regular_expression) == len(register_line): + i = 0 + while i < len(regular_expression): + parser_result.append( + self._get_results( + regular_expression[i], register_line[i].replace("\n", "") + ) + ) + i += 1 + else: + raise ValidationError(_("Parsing error, missing data")) + if len(parser_result) > 0: + final_result = [] + for i in parser_result: + if len(i) > 1: + for j in i: + final_result.append(j) + elif not len(i) == 0: + final_result.append(i[0]) + else: + final_result.append([]) + if register_rules[0].register_id.edit_existent: + repeat_value_rule = {} + rule_ids = [] + temp_r = [] + for r in register_rules: + if r.field_ids: + for a in register_rules.filtered( + lambda rule: rule.field_id in r.field_ids + ): + temp_r.append(a) + temp_r.insert(0, r) + repeat_value_rule[r] = temp_r + rule_ids.append(r.id) + rule_ids += register_rules.filtered( + lambda rule: rule.field_id in r.field_ids + ).ids + + render_func = getattr(self, "_parse_register_edit_" + model, None) + if not render_func: + raise UserError(_("Error parsing the file")) + render_func( + final_result, + register_rules, + repeat_value_rule, + rule_ids, + current_register, + ) + return + else: + render_func(final_result, register_rules, current_register) + + def _parse_register(self, line): + register_type = line[0].lower() + current_register = register_type + register_line = ( + line[1:] + .rstrip() + .replace("�", "") + .replace("(", ",") + .replace(")", ",") + .replace("[", ",") + .replace("]", ",") + .strip() + .split("|") + ) + register_rules = ( + self.env["bc3.version.register"] + .search( + [ + ("name", "ilike", register_type), + ("version_id", "=", self.version_id.id), + ], + limit=1, + ) + .rule_ids + ) + + if ( + register_rules + and register_rules[0] + and register_rules[0].register_id.model_id + ): + model = register_rules[0].register_id.model_id.model.replace(".", "_") + register_line.pop(0) + if len(register_line) < len( + register_rules.filtered(lambda x: not x.is_child) + ): + for _i in range( + abs( + len(register_rules.filtered(lambda x: not x.is_child)) + - len(register_line) + ) + ): + register_line.append("") + elif len(register_line) > len( + register_rules.filtered(lambda x: not x.is_child) + ): + for _i in range( + abs( + len(register_rules.filtered(lambda x: not x.is_child)) + - len(register_line) + ) + ): + register_line.pop() + render_func = getattr(self, "_parse_register_" + model, None) + if not render_func: + raise UserError(_("Error parsing the file")) + + self._parse_register_data( + register_rules, register_line, current_register, model, render_func + ) + + # Parseo + def get_groups_matches(self, group_id, check_list, text, group_pattern): + # Hay que revisar las substring: + for a in check_list: + t = text[a[0] : a[1]] + matches = re.finditer(group_pattern[group_id]["expression"], t) + last_index = (0, 0) + for match in matches: + if match.lastindex: + for index in range(1, match.lastindex + 1): + group_pattern[str(group_id)]["groups"].insert( + 0, match.group(index) + ) + if not last_index[0] == match.span(index)[0]: + group_pattern[str(group_id)]["check"].append( + (last_index[0], match.span(index)[0]) + ) + group_pattern[str(group_id)]["check"].remove(a) + if len(group_pattern[group_id]["check"]) > 0: + self.get_groups_matches( + group_id, group_pattern[group_id]["check"], t, group_pattern + ) + else: + return True + + def _parse_matches(self, matches, group_pattern): + for match in matches: + # Recorro los grupos + # Empiezo en 1 porque el primer grupo es todo el match, no me interesa + last_index = (0, 0) + if match.lastindex: + if match.lastindex > 1: + for index in range(1, match.lastindex + 1): + if str(index) in group_pattern and match.group(index): + group_pattern[str(index)]["groups"].append( + match.group(index) + ) + # Es el primer grupo + if index == 1: + last_index = match.span(index) + else: + if not last_index[1] == match.span(index)[0]: + group_pattern[str(index)]["check"].append( + (last_index[1], match.span(index)[0]) + ) + last_index = match.span(index) + else: + for index in range(1, match.lastindex + 1): + if str(index) in group_pattern and match.group(index): + group_pattern[str(index)]["groups"].append( + match.group(index) + ) + if not last_index[1] == match.span(index)[0]: + group_pattern[str(index)]["check"].append( + (last_index[1], match.span(index)[0]) + ) + last_index = match.span(index) + return group_pattern + + def _get_results(self, pattern, text): + text = text.rstrip() + result = [] + if pattern: + pattern_2 = pattern.split("(") + group_pattern = {} + counter = 1 + for p in pattern_2: + if p: + group_pattern[str(counter)] = { + "expression": "(" + p, + "groups": [], + "check": [], + } + counter += 1 + matches = re.finditer(pattern, text) + group_pattern = self._parse_matches(matches, group_pattern) + + # Reviso los checks + for i in group_pattern: + if len(group_pattern[i]["check"]) > 0: + self.get_groups_matches( + i, group_pattern[i]["check"], text, group_pattern + ) + for i in group_pattern: + result.append(group_pattern[i]["groups"]) + return result + + @api.model + def get_uom_products(self): + BC3_PRODUCTS[ + self.env.ref("bc3_importer.product_product_product_units").uom_id.id + ] = self.env.ref("bc3_importer.product_product_product_units") + BC3_PRODUCTS[ + self.env.ref("bc3_importer.product_product_product_meter").uom_id.id + ] = self.env.ref("bc3_importer.product_product_product_meter") + BC3_PRODUCTS[ + self.env.ref("bc3_importer.product_product_product_square_meter").uom_id.id + ] = self.env.ref("bc3_importer.product_product_product_square_meter") + BC3_PRODUCTS[ + self.env.ref("bc3_importer.product_product_product_cubic_meter").uom_id.id + ] = self.env.ref("bc3_importer.product_product_product_cubic_meter") + BC3_PRODUCTS[ + self.env.ref("bc3_importer.product_product_product_g").uom_id.id + ] = self.env.ref("bc3_importer.product_product_product_g") + BC3_PRODUCTS[ + self.env.ref("bc3_importer.product_product_product_l").uom_id.id + ] = self.env.ref("bc3_importer.product_product_product_l") + + @api.model + def line_in_dict(self, code, line_id): + if code in lines and line_id in lines[code]: + return True + return False + + @api.model + def line_in_any_dict(self, line_id): + a = self.env["sale.order.line"].search( + [("order_id", "=", self.sale_id.id), ("id", "=", int(line_id))] + ) + if a: + if a in lines: + return True + else: + for d in lines: + if line_id in lines[d]: + return True + return False diff --git a/bc3_importer/wizard/bc3_import_wizard_views.xml b/bc3_importer/wizard/bc3_import_wizard_views.xml new file mode 100644 index 0000000..6f393c3 --- /dev/null +++ b/bc3_importer/wizard/bc3_import_wizard_views.xml @@ -0,0 +1,63 @@ + + + + bc3.import.wizard.wizard.form + bc3.import.wizard + +
+ + + + + + + + + + + + +
+
+
+
+
+ + Import BC3 File + bc3.import.wizard + form + new + + + + + +
diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..39acb10 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +# generated from manifests external_dependencies +chardet +iteration_utilities