diff --git a/excel_import_export/README.rst b/excel_import_export/README.rst new file mode 100644 index 00000000000..21d682dcdb9 --- /dev/null +++ b/excel_import_export/README.rst @@ -0,0 +1,260 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +========================== +Excel Import/Export/Report +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:2ff7fc0fdd66cd8a126f345d098845f65ac464b9531d37d76ac1acebb4b46860 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/19.0/excel_import_export + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-19-0/server-tools-19-0-excel_import_export + :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/server-tools&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +The module provide pre-built functions and wizards for developer to +build excel import / export / report with ease. + +Without having to code to create excel file, developer do, + +- Create menu, action, wizard, model, view a normal Odoo development. +- Design excel template using standard Excel application, e.g., colors, + fonts, formulas, etc. +- Instruct how the data will be located in Excel with simple dictionary + instruction or from Odoo UI. +- Odoo will combine instruction with excel template, and result in + final excel file. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +To install this module, you need to install following python library, +**xlrd, xlwt, openpyxl**. + +Then, simply install **excel_import_export**. + +For demo, install **excel_import_export_demo** + +Configuration +============= + +If you have existing templates from the version 16.0.1.2.0 or earlier, +you need to click 'REMOVE EXPORT ACTION' and then click 'ADD EXPORT +ACTION' in these templates for export actions to work as expected. + +Usage +===== + +Concepts +-------- + +This module contain pre-defined function and wizards to make exporting, +importing and reporting easy. + +At the heart of this module, there are 2 main methods + +- ``self.env['xlsx.export'].export_xlsx(...)`` +- ``self.env['xlsx.import'].import_xlsx(...)`` + +For reporting, also call export_xlsx(...) but through following method + +- ``self.env['xslx.report'].report_xlsx(...)`` + +After install this module, go to Settings > Technical > Excel +Import/Export > XLSX Templates, this is where the key component located. + +As this module provide tools, it is best to explain as use cases. For +example use cases, please install **excel_import_export_demo** + +Use Cases +--------- + +**Use Case 1:** Export/Import Excel on existing document + +This add export/import action menus in existing document (example - +excel_import_export_demo/import_export_sale_order) + +1. Create export action menu on document, with + res_model="export.xlsx.wizard" and src_model="", and + context['template_domain'] to locate the right template -- + actions.xml +2. Create import action menu on document, with + res_model="import.xlsx.wizard" and src_model="", and + context['template_domain'] to locate the right template -- action.xml +3. Create/Design Excel Template File (.xlsx), in the template, name the + underlining tab used for export/import -- .xlsx +4. Create instruction dictionary for export/import in xlsx.template + model -- templates.xml + +**Use Case 2:** Import Excel Files + +With menu wizard to create new documents (example - +excel_import_export_demo/import_sale_orders) + +1. Create report menu with search wizard, res_model="import.xlsx.wizard" + and context['template_domain'] to locate the right template -- + menu_action.xml +2. Create Excel Template File (.xlsx), in the template, name the + underlining tab used for import -- .xlsx +3. Create instruction dictionary for import in xlsx.template model -- + templates.xml + +**Use Case 3:** Create Excel Report + +This create report menu with criteria wizard. (example - +excel_import_export_demo/report_sale_order) + +1. Create report's menu, action, and add context['template_domain'] to + locate the right template for this report -- .xml +2. Create report's wizard for search criteria. The view inherits + ``excel_import_export.xlsx_report_view`` and mode="primary". In this + view, you only need to add criteria fields, the rest will reuse from + interited view -- +3. Create report model as models.Transient, then define search criteria + fields, and get reporing data into ``results`` field -- .py +4. Create/Design Excel Template File (.xlsx), in the template, name the + underlining tab used for report results -- .xlsx +5. Create instruction dictionary for report in xlsx.template model -- + templates.xml + +**Note:** + +Another option for reporting is to use report action +(report_type='excel'), I.e., + +.. code:: xml + + + Quotation / Order (.xlsx) + ir.model + 'sale.order' + 'sale.order' + + report + excel + + +By using report action, Odoo will find template using combination of +model and name, then do the export for the underlining record. Please +see example in excel_import_export_demo/report_action, which shows, + +1. Print excel from an active sale.order +2. Run partner list report based on search criteria. + +Easy Reporting Option +--------------------- + +Technically, this option is the same as "Create Excel Report" use case. +But instead of having to write XML / Python code like normally do, this +option allow user to create a report based on a model or view, all by +configuration only. + +1. Go to Settings > Technical> Excel Import/Export > XLSX Templates, and + create a new template for a report. +2. On the new template, select "Easy Reporting" option, then select + followings + + - Report Model, this can be data model or data view we want to get + the results from. + - Click upload your file and add the excel template (.xlsx) + - Click Save, system will create sample export line, user can add + more fields according to results model. + +3. Click Add Report Menu, the report menu will be created, user can + change its location. Now the report is ready to use. + +.. + + |image1| + +Note: Using easy reporting mode, system will used a common criteria +wizard. + + |image2| + +.. |image1| image:: https://raw.githubusercontent.com/OCA/server-tools/19.0/excel_import_export/static/description/xlsx_template.png +.. |image2| image:: https://raw.githubusercontent.com/OCA/server-tools/19.0/excel_import_export/static/description/common_wizard.png + +Known issues / Roadmap +====================== + +- Module extension e.g., excel_import_export_async, that add ability to + execute as async process. + +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 +------- + +* Ecosoft + +Contributors +------------ + +- Kitti Upariphutthiphong. (http://ecosoft.co.th) +- Saran Lim. (http://ecosoft.co.th) +- Do Anh Duy +- `Studio73, S.L. `__ + + - Pablo Cortés + +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. + +.. |maintainer-kittiu| image:: https://github.com/kittiu.png?size=40px + :target: https://github.com/kittiu + :alt: kittiu + +Current `maintainer `__: + +|maintainer-kittiu| + +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/excel_import_export/__init__.py b/excel_import_export/__init__.py new file mode 100644 index 00000000000..322f82834e6 --- /dev/null +++ b/excel_import_export/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from . import wizard +from . import models +from . import controllers diff --git a/excel_import_export/__manifest__.py b/excel_import_export/__manifest__.py new file mode 100644 index 00000000000..2e81aac13bd --- /dev/null +++ b/excel_import_export/__manifest__.py @@ -0,0 +1,30 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +{ + "name": "Excel Import/Export/Report", + "summary": "Base module for developing Excel import/export/report", + "version": "19.0.1.0.0", + "author": "Ecosoft,Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/server-tools", + "category": "Tools", + "depends": ["mail", "base_import"], + "external_dependencies": {"python": ["openpyxl"]}, + "data": [ + "security/ir.model.access.csv", + "wizard/export_xlsx_wizard.xml", + "wizard/import_xlsx_wizard.xml", + "wizard/report_xlsx_wizard.xml", + "views/xlsx_template_view.xml", + "views/xlsx_report.xml", + ], + "installable": True, + "development_status": "Beta", + "maintainers": ["kittiu"], + "assets": { + "web.assets_backend": [ + "/excel_import_export/static/src/js/report/action_manager_report.esm.js" + ] + }, +} diff --git a/excel_import_export/controllers/__init__.py b/excel_import_export/controllers/__init__.py new file mode 100644 index 00000000000..5e52ed2d0bd --- /dev/null +++ b/excel_import_export/controllers/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from . import report diff --git a/excel_import_export/controllers/report.py b/excel_import_export/controllers/report.py new file mode 100644 index 00000000000..9ab3788cdbd --- /dev/null +++ b/excel_import_export/controllers/report.py @@ -0,0 +1,91 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +import base64 +import json +import logging + +from werkzeug.urls import url_decode + +from odoo import http +from odoo.http import content_disposition, request, route, serialize_exception +from odoo.tools import html_escape +from odoo.tools.safe_eval import safe_eval, time + +from odoo.addons.web.controllers.report import ReportController + +_logger = logging.getLogger(__name__) + + +class ReportExcelController(ReportController): + @route() + def report_routes(self, reportname, docids=None, converter=None, **data): + if converter == "excel": + report = request.env["ir.actions.report"]._get_report_from_name(reportname) + context = dict(request.env.context) + if docids: + docids = [int(i) for i in docids.split(",") if i.isdigit()] + if data.get("options"): + data.update(json.loads(data.pop("options"))) + if data.get("context"): + # Ignore 'lang' here, because the context in data is the one + # from the webclient *but* if the user explicitely wants to + # change the lang, this mechanism overwrites it. + data["context"] = json.loads(data["context"]) + context.update(data["context"]) + excel, report_name = report.with_context(**context)._render_excel( + docids, data=data + ) + excel = base64.decodebytes(excel) + if docids: + records = request.env[report.model].browse(docids) + if report.print_report_name and not len(records) > 1: + # this is a bad idea, this should only be .xlsx + extension = report_name.split(".")[-1:].pop() + report_name = safe_eval( + report.print_report_name, {"object": records, "time": time} + ) + report_name = f"{report_name}.{extension}" + excelhttpheaders = [ + ( + "Content-Type", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ), + ("Content-Length", len(excel)), + ("Content-Disposition", content_disposition(report_name)), + ] + return request.make_response(excel, headers=excelhttpheaders) + return super().report_routes(reportname, docids, converter, **data) + + @http.route() + def report_download(self, data, context=None): + requestcontent = json.loads(data) + url, report_type = requestcontent[0], requestcontent[1] + if report_type != "excel": + return super().report_download(data, context) + reportname = "???" + try: + pattern = "/report/excel/" + reportname = url.split(pattern)[1].split("?")[0] + docids = None + if "/" in reportname: + reportname, docids = reportname.split("/") + if docids: + return self.report_routes( + reportname, docids=docids, converter="excel", context=context + ) + data = dict(url_decode(url.split("?")[1]).items()) + if "context" in data: + context, data_context = ( + json.loads(context or "{}"), + json.loads(data.pop("context")), + ) + context = json.dumps({**context, **data_context}) + return self.report_routes( + reportname, converter="excel", context=context, **data + ) + except Exception as e: + _logger.exception("Error while generating report %s", reportname) + se = serialize_exception(e) + error = {"code": 200, "message": "Odoo Server Error", "data": se} + return request.make_response(html_escape(json.dumps(error))) diff --git a/excel_import_export/i18n/es.po b/excel_import_export/i18n/es.po new file mode 100644 index 00000000000..0d298e8a888 --- /dev/null +++ b/excel_import_export/i18n/es.po @@ -0,0 +1,1590 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * excel_import_export +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-02-14 19:34+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\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 4.17\n" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "${object.post_import_do_something()}" +msgstr "${object.post_import_do_something()}" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "'%s' sheet not found" +msgstr "Hoja '%s' no encontrada" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__state +msgid "" +"* Choose: wizard show in user selection mode\n" +"* Get: wizard show results from user action" +msgstr "" +"* Elegir: el asistente muestra el modo de selección del usuario\n" +"* Obtener: el asistente muestra los resultados de la acción del usuario" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Cell: Location of data in excel sheet (e.g., A1, B1, ...)" +msgstr "" +"Cell: Ubicación de los datos en la hoja excel (por ejemplo, A1, " +"B1, ...)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Continue: If not selected, start rolling with specified first row " +"cells. If selected, continue from previous one2many field" +msgstr "" +"Continuar: Si no se selecciona, empieza a rodar con las celdas " +"especificadas de la primera fila. Si se selecciona, continuar desde el campo " +"one2many anterior" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Extend: If selected, extend one row after one data row in order to " +"preserve the sum line" +msgstr "" +"Extender: si se selecciona, extender una fila después de una fila de " +"datos para conservar la línea de suma" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} to " +"manipulate field value, e.g., if field = product_id, value will " +"represent product object, e.g., ${value and value.uom_id." +"name or \"\"}" +msgstr "" +"Cond. de campo: código Python en ${...} " +"para manipular el valor del campo, por ejemplo, si campo = product_id, " +"valor representará el objeto del producto, por ejemplo, " +"${value y value.uom_id.name o \"\"}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} value " +"will represent data from excel cell, e.g., if A1 = 'ABC', value " +"will represent 'ABC', e.g., ${value == \"ABC\" and \"X\" " +"or \"Y\"} thus can change from cell value to other value for import." +msgstr "" +"Cond. de campo: el código Python en el valor ${...}" +" representará datos de la celda de Excel, por ejemplo, si A1 = " +"'ABC' , value representará 'ABC', por ejemplo, ${value == \"ABC\" y \"X\" o \"Y\"}, por lo que puede " +"cambie del valor de celda a otro valor para importar." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Field: Field of the record to be imported to, e.g., product_id" +msgstr "" +"Campo: campo del registro al que se importará, por ejemplo, product_id" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field: Field of the record, e.g., product_id.uom_id.name. They are " +"orm compliant." +msgstr "" +"Campo: Campo del registro, por ejemplo, product_id.uom_id.name. " +"Cumplen con las normas." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"No Delete: By default, all one2many lines will be deleted before " +"import. Select this, to avoid deletion" +msgstr "" +"Sin eliminar: de forma predeterminada, todas las líneas one2many se " +"eliminarán antes de la importación. Seleccione esto para evitar la " +"eliminación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Note:" +msgstr "Nota:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field (e." +"g., line_ids) for row data" +msgstr "" +"Campo de fila: use _HEAD_ para el registro en sí y un campo one2many " +"(por ejemplo, line_ids) para los datos de la fila" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field for " +"row data, e.g., order_line, line_ids[max_row] where " +"[max_row] is optional number of rows to import" +msgstr "" +"Campo de fila: utilice _HEAD_ para el registro en sí y un campo " +"one2many para los datos de la fila, por ejemplo, order_line, " +"line_ids[max_row] donde [max_row] es un número " +"opcional de filas para importar" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet" +msgstr "" +"Hoja: Nombre (p. ej., Hoja 1) o índice (p. ej., 1) de la hoja de Excel" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet to " +"export data to" +msgstr "" +"Hoja: nombre (por ejemplo, hoja 1) o índice (por ejemplo, 1) de la " +"hoja de Excel a la que exportar datos" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style w/Cond.: Conditional style by python code in #?...?, e.g., apply style for specific product, #?value.name == \"ABC\" " +"and #{font=bold;fill=red} or None?" +msgstr "" +"Estilo con Cond.: Estilo condicional por código Python en #?...?" +", por ejemplo, aplicar estilo para un producto específico, #?" +"value.name = = \"ABC\" y #{font=bold;fill=red} o ¿Ninguno?" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style: Default style in #{...} that apply to each cell, " +"e.g., #{align=left;style=text}. See module's style.py " +"for available styles." +msgstr "" +"Estilo: estilo predeterminado en #{...} que se aplica a " +"cada celda, por ejemplo, #{align=left;style=text} . Consulte el " +"style.py del módulo para conocer los estilos disponibles." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sum: Add sum value on last row, @{sum}" +msgstr "" +"Suma: agregue el valor de la suma en la última fila, @{sum}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"\n" +"{\n" +" '__EXPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" '_HEAD_': {\n" +" 'B2': 'partner_id.display_name${value or \"\"}" +"#{align=left;style=text}',\n" +" 'B3': 'name${value or \"\"}#{align=left;" +"style=text}',\n" +" },\n" +" 'line_ids': { # prefix with _CONT_ to continue rows from " +"previous row field\n" +" 'A6': 'product_id.display_name${value or \"\"}" +"#{style=text}',\n" +" 'C6': 'product_uom_qty${value or 0}" +"#{style=number}',\n" +" 'E6': 'price_unit${value or 0}" +"#{style=number}',\n" +" 'G6': 'price_subtotal${value or 0}" +"#{style=number}',\n" +" },\n" +" },\n" +" },\n" +" '__IMPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" 'order_line': { # prefix with _NODEL_ to not delete rows before " +"import\n" +" 'A6': 'product_id',\n" +" 'C6': 'product_uom_qty',\n" +" 'E6': 'price_unit${value > 0 and value or " +"0}',\n" +" },\n" +" },\n" +" },\n" +" '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +"}\n" +"\n" +" " +msgstr "" +"\n" +"{\n" +" '__EXPORTAR__': {\n" +" 'sale_order': {# hoja puede ser nombre (cadena) o índice (entero)\n" +" '_CABEZA_': {\n" +" 'B2': 'partner_id.display_name${valor o \"\"}" +"#{align=left;style=text}',\n" +" 'B3': 'nombre${valor o \"\"}#{align=left;" +"style=text}',\n" +" },\n" +" 'line_ids': { # prefijo con _CONT_ para continuar filas del " +"campo de fila anterior\n" +" 'A6': 'product_id.display_name${valor o \"\"}" +"#{style=text}',\n" +" 'C6': 'product_uom_qty${valor o 0}" +"#{estilo=número}',\n" +" 'E6': 'precio_unidad${valor o 0}" +"#{estilo=número}',\n" +" 'G6': 'precio_subtotal${valor o 0}" +"#{estilo=número}',\n" +" },\n" +" },\n" +" },\n" +" '__IMPORTAR__': {\n" +" 'sale_order': {# hoja puede ser nombre (cadena) o índice (entero)\n" +" 'order_line': { # prefijo con _NODEL_ para no eliminar filas " +"antes de la importación\n" +" 'A6': 'id_producto',\n" +" 'C6': 'product_uom_qty',\n" +" 'E6': 'precio_unidad${valor > 0 y valor o " +"0}',\n" +" },\n" +" },\n" +" },\n" +" '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +"}\n" +"\n" +" " + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "date, datetime, time: some useful python classes" +msgstr "date, datetime, time: algunas clases útiles de python" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "model: active model, e.g., self.env['my.model']" +msgstr "modelo: modelo activo, por ejemplo, self.env['my.model']" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"object: record object or line object depends on Row Field" +msgstr "" +"objeto: objeto de registro u objeto de línea depende del " +"campo de fila" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Cell" +msgstr "valor: valor de la Celda" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Field" +msgstr "valor: valor del campo" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Export Action" +msgstr "Agregar Acción de Exportación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Import Action" +msgstr "Añadir Acción de Importación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Report Menu" +msgstr "Añadir informe Menú" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add data column" +msgstr "Añadir columna de datos" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add header section" +msgstr "Añadir sección de cabecera" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add new report menu at root level" +msgstr "Añadir un nuevo menú de informes en el nivel raíz" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add row section" +msgstr "Añadir sección de fila" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add sheet section" +msgstr "Añadir sección de hoja" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__choose_template +msgid "Allow Choose Template" +msgstr "Permitir Elegir Plantilla" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__assigned_attachment_ids +msgid "Assigned Attachments" +msgstr "Archivos Adjuntos Asignados" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_styles +msgid "Available styles for excel" +msgstr "Estilos disponibles para excel" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__no_delete +msgid "" +"By default, all rows will be deleted before import.\n" +"Select No Delete, otherwise" +msgstr "" +"Por defecto, todas las filas se borrarán antes de la importación.\n" +"Seleccione No borrar, de lo contrario" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_delimiter +msgid "CSV Delimiter" +msgstr "Delimitador CSV" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_extension +msgid "CSV File Extension" +msgstr "Extensión de archivo CSV" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_quote +msgid "CSV Quoting" +msgstr "Cotización CSV" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__post_import_hook +msgid "" +"Call a function after successful import, i.e.,\n" +"${object.post_import_do_something()}" +msgstr "" +"Llamar a una función después de la importación con éxito, es decir,\n" +"${object.post_import_do_something()}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Cancel" +msgstr "Cancelar" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__excel_cell +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__excel_cell +msgid "Cell" +msgstr "Celda" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__changeset_change_ids +msgid "Changeset Changes" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__changeset_ids +msgid "Changesets" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_crm_lead__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_sale_order__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__choose +msgid "Choose" +msgstr "Elegir" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Choose Template:" +msgstr "Elija Plantilla:" + +#. module: excel_import_export +#: model_terms:ir.actions.act_window,help:excel_import_export.action_xlsx_template +msgid "Click to create a XLSX Template Object." +msgstr "Haga clic para crear un objeto de plantilla XLSX." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Close" +msgstr "Cerrar" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Complete Prepare File (.xlsx)" +msgstr "Fichero Preparado Completo (.xlsx)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Complete Prepare Report (.xlsx)" +msgstr "Informe de preparación completo (.xlsx)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue" +msgstr "Continuar" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue data rows after last data row" +msgstr "Continuar las filas de datos después de la última fila de datos" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__to_csv +msgid "Convert file into CSV format on export" +msgstr "Convertir el archivo en formato CSV al exportarlo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__to_csv +msgid "Convert to CSV?" +msgstr "¿Convertir a CSV?" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_changesets +msgid "Count Changesets" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__data +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__data +msgid "Data" +msgstr "Datos" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style +msgid "Default Style" +msgstr "Estilo por defecto" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__description +msgid "Description" +msgstr "Descripción" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_export +msgid "Detailed of how excel data will be exported" +msgstr "Detalle de cómo se exportarán los datos de Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_import +msgid "Detailed of how excel data will be imported" +msgstr "Detalle de cómo se importarán los datos de Excel" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__display_name +msgid "Display Name" +msgstr "Mostrar Nombre" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Document must be in %s states" +msgstr "El documento debe estar en %s estados" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Document must be in draft state" +msgstr "El documento debe estar en estado de borrador" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Easy Reporting" +msgstr "Informes fáciles" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"Error deleting data\n" +"%s" +msgstr "" +"Error al borrar datos\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"Error filling data into Excel sheets\n" +"%s" +msgstr "" +"Error al introducir datos en hojas Excel\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Error importing data" +msgstr "Error al importar datos" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__ir_actions_report__report_type__excel +msgid "Excel" +msgstr "Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_export +msgid "Excel Export AbstractModel" +msgstr "ModeloAbstracto Exportación Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_import +msgid "Excel Import AbstractModel" +msgstr "Importar Excel Modeloabstracto" + +#. module: excel_import_export +#: model:ir.ui.menu,name:excel_import_export.menu_excel_import_export +msgid "Excel Import/Export" +msgstr "Importación/Exportación Excel" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Excel Report" +msgstr "Informe Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_report +msgid "Excel Report AbstractModel" +msgstr "ModeloAbstracto de Informe Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template +msgid "Excel template file and instruction" +msgstr "Archivo de plantilla Excel e instrucciones" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +msgid "Execute" +msgstr "Ejecutar" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Execute Report" +msgstr "Ejecutar informe" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Export" +msgstr "Exportar" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_action_id +msgid "Export Action" +msgstr "Acción de exportación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Export Instruction is how to write data from an active data record to " +"specified cells in excel sheet.\n" +" For example, an active record can be a " +"sale order that user want to export.\n" +" The record itself will be mapped to the " +"header part of excel sheet. The record can contain multiple one2many fields, " +"which will be written as data lines.\n" +" You can look at following instruction as " +"Excel Sheet(s), each with 1 header section (_HEAD_) and multiple row " +"sections (one2many fields)." +msgstr "" +"Instrucción de Exportación es como escribir datos de un registro de datos " +"activo a celdas especificadas en una hoja de Excel.\n" +" Por ejemplo, un registro activo puede ser " +"una orden de venta que el usuario desea exportar.\n" +" El registro será mapeado a la parte del " +"encabezado de la hoja de Excel. El registro puede contener múltiples campos " +"one2many, que serán escritos como líneas de datos.\n" +" Puede ver las siguientes instrucciones " +"como hojas de Excel, cada una con una sección de encabezado (_HEAD_) y " +"múltiples secciones de fila (campos one2many)." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend" +msgstr "Extender" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend a blank row after filling each record, to extend the footer" +msgstr "" +"Extender una fila en blanco después de rellenar cada registro, para extender " +"el pie de página" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_name +msgid "Field" +msgstr "Campo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_cond +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_cond +msgid "Field Cond." +msgstr "Campo Cond." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__data +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__data +msgid "File" +msgstr "Archivo" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "File \"%(fname)s\" not found in template, %(name)s." +msgstr "Archivo \"%(fname)s\" no encontrado en la plantilla, %(name)s." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__datas +msgid "File Content" +msgstr "Contenido del archivo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__fname +msgid "File Name" +msgstr "Nombre del Archivo" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Following are more explaination on each column:" +msgstr "A continuación encontrará más explicaciones sobre cada columna:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Following show very simple example of the dictionary construct.\n" +" Normally, this will be within templates." +"xml file within addons." +msgstr "" +"A continuación se muestra un ejemplo muy simple de la construcción del " +"diccionario.\n" +" Normalmente, esto será dentro del " +"archivo templates.xml dentro de addons." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...} and #?...?, " +"following object are available," +msgstr "" +"Para el bloque de código ${...} y #?...?, están disponibles los siguientes objetos," + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...}, following object are " +"available," +msgstr "" +"Para el bloque de código ${...}, están disponibles " +"los siguientes objetos," + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_report_xlsx_wizard +msgid "Generic Report Wizard, used with template reporting option" +msgstr "" +"Asistente para informes genéricos, utilizado con la opción de informes de " +"plantilla" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_crm_lead__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_sale_order__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__get +msgid "Get" +msgstr "Obtener" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Get Import Template" +msgstr "Obtener plantilla de importación" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__gname +msgid "Group Name" +msgstr "Nombre del Grupo" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__head +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__head +msgid "Head" +msgstr "Cabeza" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Export Instruction" +msgstr "Ayuda con Instrucciones de Exportación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Import Instruction" +msgstr "Ayuda con Instrucciones de Importación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Here is the exported file:" +msgstr "Aquí está el archivo exportado:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Here is the report file:" +msgstr "Aquí está el archivo del informe:" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__id +msgid "ID" +msgstr "ID (identificación)" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__row_field +msgid "If section type is row, this field is required" +msgstr "Si el tipo de sección es fila, este campo es obligatorio" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"IllegalCharacterError\n" +"Some exporting data contain special character\n" +"%s" +msgstr "" +"Error de carácter ilegal\n" +"Algunos datos de exportación contienen caracteres especiales.\n" +"%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Import" +msgstr "Importar" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_action_id +msgid "Import Action" +msgstr "Importar acción" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Import Excel" +msgstr "Importar Excel" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__import_file +msgid "Import File (*.xlsx)" +msgstr "Importar archivo (*.xlsx)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__filename +msgid "Import File Name" +msgstr "Nombre del Archivo de Importación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import File Template" +msgstr "Importar plantilla de archivo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "Import File(s) (*.xlsx)" +msgstr "Importar archivos (*.xlsx)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Import Instruction is how to get data from excel sheet and write them to an " +"active record.\n" +" For example, user create a sales order " +"document, and want to import order lines from excel.\n" +" In reverse direction to exporting, data " +"from excel's cells will be mapped to record fields during import.\n" +" Cells can be mapped to record in header " +"section (_HEAD_) and data table can be mapped to row section (one2many " +"field, begins from specifed cells." +msgstr "" +"La instrucción de importación es cómo obtener datos de una hoja de Excel y " +"escribirlos en un registro activo.\n" +" Por ejemplo, el usuario crea un documento " +"de pedido de ventas y desea importar líneas de pedido desde Excel.\n" +" En dirección inversa a la exportación, los " +"datos de las celdas de Excel se asignarán a los campos de registro durante " +"la importación.\n" +" Las celdas se pueden asignar a registros " +"en la sección de encabezado (_HEAD_) y la tabla de datos se puede asignar a " +"la sección de filas (campo uno a muchos, comienza desde las celdas " +"especificadas)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import Successful!" +msgstr "¡Importación exitosa!" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section part, map data fields (e.g., number, partner_id.name) into " +"cells (e.g., B1, B2)." +msgstr "" +"En la parte de la sección del encabezado, asigne los campos de datos (por " +"ejemplo, número, socio_id.nombre) a celdas (por ejemplo, B1, B2)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section, map cells (e.g., B1, B2) into data fields (e.g., number, " +"partner_id)." +msgstr "" +"En la sección del encabezado, asigne celdas (por ejemplo, B1, B2) a campos " +"de datos (por ejemplo, número, socio_id)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data list will be rolled out from one2many row field (e.g., " +"order_line), and map data field (i.e., product_id.name, uom_id.name, qty) " +"into the first row cells to start rolling (e.g., A6, B6, C6)." +msgstr "" +"En la sección de filas, la lista de datos se desplegará desde el campo de " +"fila one2many (por ejemplo, order_line) y el campo de datos del mapa (es " +"decir, product_id.name, uom_id.name, qty) a las celdas de la primera fila " +"para comenzar a rodar (por ejemplo, A6, B6, C6)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data table from excel can be imported to one2many row field " +"(e.g., order_line) by mapping cells on first row onwards (e.g., A6, B6, C6) " +"to fields (e.g., product_id, uom_id, qty)" +msgstr "" +"En la sección de filas, la tabla de datos de Excel se puede importar a un " +"campo de fila one2many (p. ej., order_line) asignando celdas de la primera " +"fila en adelante (p. ej., A6, B6, C6) a los campos (p. ej., product_id, " +"uom_id, qty)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Input Instruction (Dict.)" +msgstr "Instrucción de entrada (Dict.)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__instruction +msgid "Instruction" +msgstr "Instrucción" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__input_instruction +msgid "Instruction (Input)" +msgstr "Instrucción (entrada)" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__instruction +msgid "Instruction on how to import/export, prepared by system." +msgstr "Instrucción sobre cómo importar/exportar, preparada por el sistema." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Invalid declaration, %s has no valid field type" +msgstr "Declaración no válida, %s no tiene ningún tipo de campo válido" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Invalid file style, only .xls or .xlsx file allowed" +msgstr "Estilo de archivo no válido, solo se permiten archivos .xls o .xlsx" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Invalid style type %s" +msgstr "Tipo de estilo no válido %s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Invalid value %(value)s for style type %(key)s" +msgstr "Valor no válido %(value)s para el tipo de estilo %(key)s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"Key Error\n" +"%s" +msgstr "" +"Error de clave\n" +"%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import____last_update +msgid "Last Modified on" +msgstr "Última Modificación el" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_date +msgid "Last Updated on" +msgstr "Última Actualización el" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__gname +msgid "" +"Multiple template of same model, can belong to same group,\n" +"result in multiple template selection" +msgstr "" +"Varias plantillas del mismo modelo, pueden pertenecer al mismo grupo,\n" +"dar como resultado una selección de plantillas múltiples" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__no_delete +msgid "No Delete" +msgstr "Sin eliminar" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "No data_dict['__IMPORT__'] in template %s" +msgstr "No data_dict['__IMPORT__'] en la plantilla %s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +#, python-format +msgid "No file content!" +msgstr "¡Sin contenido de archivo!" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#, python-format +msgid "No file in %s" +msgstr "Ningún archivo en %s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "No template found" +msgstr "No se encontró ninguna plantilla" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "Not enough worksheets" +msgstr "No hay suficientes hojas de trabajo" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +#, python-format +msgid "Only one id is allowed for excel_import_export" +msgstr "Sólo se permite una identificación para excel_import_export" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__redirect_action +msgid "Optional action, redirection after finish import operation" +msgstr "" +"Acción opcional, redirección después de finalizar la operación de importación" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_extension +msgid "Optional for CSV, default is .csv" +msgstr "Opcional para CSV, el valor predeterminado es .csv" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_delimiter +msgid "Optional for CSV, default is comma." +msgstr "Opcional para CSV, el valor predeterminado es la coma." + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_quote +msgid "Optional for CSV, default is full quoting." +msgstr "Opcional para CSV, el valor predeterminado son las citas completas." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Please select Excel file to import" +msgstr "Seleccione el archivo Excel para importar" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Position %s is not valid" +msgstr "La posición %s no es válida" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__post_import_hook +msgid "Post Import Function Hook" +msgstr "Gancho de función posterior a la importación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Post Import Hook" +msgstr "Gancho posterior a la importación" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"Post import operation error\n" +"%s" +msgstr "" +"Error de operación posterior a la importación\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "Records in %s exceed max records allowed" +msgstr "Los registros en %s superan el máximo de registros permitidos" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Export Action" +msgstr "Eliminar acción de exportación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Import Action" +msgstr "Eliminar acción de importación" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Report Menu" +msgstr "Quitar menú Informe" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_ir_actions_report +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_action_id +msgid "Report Action" +msgstr "Informar Acción" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_menu_id +msgid "Report Menu" +msgstr "Menú Informe" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_model_id +msgid "Report Model" +msgstr "Modelo de informe" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__report_type +msgid "Report Type" +msgstr "Tipo de Informe" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__res_model +msgid "Res Model" +msgstr "Modelo Res" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_id +msgid "Resource ID" +msgstr "ID del Recurso" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_ids +msgid "Resource IDs" +msgstr "IDs del Recurso" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__res_model +msgid "Resource Model" +msgstr "Modelo del Recurso" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_field +msgid "Result Field" +msgstr "Campo del Recurso" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__redirect_action +msgid "Return Action" +msgstr "Acción de devolución" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__row +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__row +msgid "Row" +msgstr "Fila" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__row_field +msgid "Row Field" +msgstr "Campo de fila" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__datas +msgid "Sample" +msgstr "Ejemplo" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sample Input Instruction as Dictionary" +msgstr "Instrucción de entrada de muestra como diccionario" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__domain +msgid "Search Criterias" +msgstr "Criterios de búsqueda" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__section_type +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__section_type +msgid "Section Type" +msgstr "Tipo de Sección" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sequence +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sequence +msgid "Sequence" +msgstr "Secuencia" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Set Templates" +msgstr "Establecer plantillas" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sheet +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__sheet +msgid "Sheet" +msgstr "Hoja" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Sheet %s not found" +msgstr "Hoja %s s no encontrada" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__show_instruction +msgid "Show Output" +msgstr "Mostrar salida" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__smart_search +msgid "Smart Search" +msgstr "Búsqueda inteligente" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__state +msgid "State" +msgstr "Estado" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style_cond +msgid "Style w/Cond." +msgstr "Estilo con Cond." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_sum +msgid "Sum" +msgstr "Suma" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__template_id +msgid "Template" +msgstr "Plantilla" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +#, python-format +msgid "Template %(report_name)s on model %(model)s is not unique!" +msgstr "¡La plantilla %(report_name)s en el modelo %(model)s no es única!" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__fname +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__name +msgid "Template Name" +msgstr "Nombre de Plantilla" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "" +"Template with CSV Quoting = False, data must not contain the same char as " +"delimiter -> \"%s\"" +msgstr "" +"Plantilla con cita CSV = Falso, los datos no deben contener el mismo " +"carácter que el delimitador -> \"%s\"" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Template's model mismatch" +msgstr "El modelo de la plantilla no coincide" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__res_model +msgid "The database object this attachment will be attached to." +msgstr "El objeto de la base de datos al que se anexará este anexo." + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_pending_changeset_changes +msgid "The number of pending changes of this record" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_pending_changesets +msgid "The number of pending changesets of this record" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_changesets +msgid "The overall number of changesets of this record" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +#, python-format +msgid "The selected redirect action is not for model %s" +msgstr "La acción de redirección seleccionada no es para el modelo %s" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__report_type +msgid "" +"The type of the report that will be rendered, each one having its own " +"rendering method. HTML means the report will be opened directly in your " +"browser PDF means the report will be rendered using Wkhtmltopdf and " +"downloaded by the user." +msgstr "" +"El tipo de informe que se generará, cada uno con su propio método de " +"generación. HTML significa que el informe se abrirá directamente en el " +"navegador PDF quiere decir que el informe se renderizará utilizando " +"Wkhtmltopdf y será descargado por el usuario." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"The value for the '%(field)s' field is expected to be in cell " +"%(cell_position)s, but no column exists for that cell in the Excel sheet. " +"Please check your Excel file." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "This import action is not usable in this document context" +msgstr "" +"Esta acción de importación no se puede utilizar en el contexto de este " +"documento" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__show_instruction +msgid "" +"This is the computed instruction based on tab Import/Export,\n" +"to be used by xlsx import/export engine" +msgstr "" +"Esta es la instrucción calculada basada en la pestaña Importar/Exportar,\n" +"para ser utilizado por el motor de importación/exportación xlsx" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__input_instruction +msgid "This is used to construct instruction in tab Import/Export" +msgstr "" +"Esto se utiliza para construir instrucciones en la pestaña Importar/Exportar" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Use common report wizard model, instead of create specific model" +msgstr "" +"Utilice el modelo de asistente de informes común, en lugar de crear un " +"modelo específico" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__result_model_id +msgid "When use commone wizard, choose the result model" +msgstr "Cuando use el asistente común, elija el modelo de resultado" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_export_xlsx_wizard +msgid "Wizard for exporting excel" +msgstr "Asistente para exportar excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_import_xlsx_wizard +msgid "Wizard for importing excel" +msgstr "Asistente para importar excel" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__template_id +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "XLSX Template" +msgstr "Plantilla XLSX" + +#. module: excel_import_export +#: model:ir.actions.act_window,name:excel_import_export.action_xlsx_template +#: model:ir.ui.menu,name:excel_import_export.menu_xlsx_template +msgid "XLSX Templates" +msgstr "Plantilla XLSX" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "You can select multiple files to import." +msgstr "Puede seleccionar varios archivos para importar." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "or" +msgstr "o" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "⇒ Get Sample Import Template" +msgstr "⇒ Obtener plantilla de importación de muestra" diff --git a/excel_import_export/i18n/excel_import_export.pot b/excel_import_export/i18n/excel_import_export.pot new file mode 100644 index 00000000000..dd7ca05a22e --- /dev/null +++ b/excel_import_export/i18n/excel_import_export.pot @@ -0,0 +1,1230 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * excel_import_export +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "${object.post_import_do_something()}" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +msgid "'%s' sheet not found" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__state +msgid "" +"* Choose: wizard show in user selection mode\n" +"* Get: wizard show results from user action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Cell: Location of data in excel sheet (e.g., A1, B1, ...)" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Continue: If not selected, start rolling with specified first row " +"cells. If selected, continue from previous one2many field" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Extend: If selected, extend one row after one data row in order to " +"preserve the sum line" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} to " +"manipulate field value, e.g., if field = product_id, value will" +" represent product object, e.g., ${value and " +"value.uom_id.name or \"\"}" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} value " +"will represent data from excel cell, e.g., if A1 = 'ABC', value" +" will represent 'ABC', e.g., ${value == \"ABC\" and \"X\"" +" or \"Y\"} thus can change from cell value to other value for import." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Field: Field of the record to be imported to, e.g., product_id" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field: Field of the record, e.g., product_id.uom_id.name. They are " +"orm compliant." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"No Delete: By default, all one2many lines will be deleted before " +"import. Select this, to avoid deletion" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Note:" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field " +"(e.g., line_ids) for row data" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field for " +"row data, e.g., order_line, line_ids[max_row] where " +"[max_row] is optional number of rows to import" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet to " +"export data to" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style w/Cond.: Conditional style by python code in " +"#?...?, e.g., apply style for specific product, " +"#?value.name == \"ABC\" and #{font=bold;fill=red} or None?" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style: Default style in #{...} that apply to each cell, " +"e.g., #{align=left;style=text}. See module's style.py " +"for available styles." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sum: Add sum value on last row, @{sum}" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"\n" +"{\n" +" '__EXPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" '_HEAD_': {\n" +" 'B2': 'partner_id.display_name${value or \"\"}#{align=left;style=text}',\n" +" 'B3': 'name${value or \"\"}#{align=left;style=text}',\n" +" },\n" +" 'line_ids': { # prefix with _CONT_ to continue rows from previous row field\n" +" 'A6': 'product_id.display_name${value or \"\"}#{style=text}',\n" +" 'C6': 'product_uom_qty${value or 0}#{style=number}',\n" +" 'E6': 'price_unit${value or 0}#{style=number}',\n" +" 'G6': 'price_subtotal${value or 0}#{style=number}',\n" +" },\n" +" },\n" +" },\n" +" '__IMPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" 'order_line': { # prefix with _NODEL_ to not delete rows before import\n" +" 'A6': 'product_id',\n" +" 'C6': 'product_uom_qty',\n" +" 'E6': 'price_unit${value > 0 and value or 0}',\n" +" },\n" +" },\n" +" },\n" +" '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +"}\n" +"\n" +" " +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "date, datetime, time: some useful python classes" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "model: active model, e.g., self.env['my.model']" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"object: record object or line object depends on Row " +"Field" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Cell" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Field" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Export Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Import Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Report Menu" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add data column" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add header section" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add new report menu at root level" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add row section" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add sheet section" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__choose_template +msgid "Allow Choose Template" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__assigned_attachment_ids +msgid "Assigned Attachments" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_styles +msgid "Available styles for excel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__no_delete +msgid "" +"By default, all rows will be deleted before import.\n" +"Select No Delete, otherwise" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_delimiter +msgid "CSV Delimiter" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_extension +msgid "CSV File Extension" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_quote +msgid "CSV Quoting" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__post_import_hook +msgid "" +"Call a function after successful import, i.e.,\n" +"${object.post_import_do_something()}" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Cancel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__excel_cell +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__excel_cell +msgid "Cell" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__choose +msgid "Choose" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Choose Template:" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.actions.act_window,help:excel_import_export.action_xlsx_template +msgid "Click to create a XLSX Template Object." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Close" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Complete Prepare File (.xlsx)" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Complete Prepare Report (.xlsx)" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue data rows after last data row" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__to_csv +msgid "Convert file into CSV format on export" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__to_csv +msgid "Convert to CSV?" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_uid +msgid "Created by" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_date +msgid "Created on" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__data +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__data +msgid "Data" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style +msgid "Default Style" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__description +msgid "Description" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_export +msgid "Detailed of how excel data will be exported" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_import +msgid "Detailed of how excel data will be imported" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__display_name +msgid "Display Name" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "Document must be in %s states" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "Document must be in draft state" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Easy Reporting" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "" +"Error deleting data\n" +"%s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +msgid "" +"Error filling data into Excel sheets\n" +"%s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "Error importing data" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__ir_actions_report__report_type__excel +msgid "Excel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_export +msgid "Excel Export AbstractModel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_import +msgid "Excel Import AbstractModel" +msgstr "" + +#. module: excel_import_export +#: model:ir.ui.menu,name:excel_import_export.menu_excel_import_export +msgid "Excel Import/Export" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Excel Report" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_report +msgid "Excel Report AbstractModel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template +msgid "Excel template file and instruction" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +msgid "Execute" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Execute Report" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Export" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_action_id +msgid "Export Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Export Instruction is how to write data from an active data record to specified cells in excel sheet.\n" +" For example, an active record can be a sale order that user want to export.\n" +" The record itself will be mapped to the header part of excel sheet. The record can contain multiple one2many fields, which will be written as data lines.\n" +" You can look at following instruction as Excel Sheet(s), each with 1 header section (_HEAD_) and multiple row sections (one2many fields)." +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend a blank row after filling each record, to extend the footer" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_name +msgid "Field" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_cond +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_cond +msgid "Field Cond." +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__data +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__data +msgid "File" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "File \"%(fname)s\" not found in template, %(name)s." +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__datas +msgid "File Content" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__fname +msgid "File Name" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Following are more explaination on each column:" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Following show very simple example of the dictionary construct.\n" +" Normally, this will be within templates.xml file within addons." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...} and #?...?, " +"following object are available," +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...}, following object are " +"available," +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_report_xlsx_wizard +msgid "Generic Report Wizard, used with template reporting option" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__get +msgid "Get" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Get Import Template" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__gname +msgid "Group Name" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__head +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__head +msgid "Head" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Export Instruction" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Import Instruction" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Here is the exported file:" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Here is the report file:" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__id +msgid "ID" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__row_field +msgid "If section type is row, this field is required" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +msgid "" +"IllegalCharacterError\n" +"Some exporting data contain special character\n" +"%s" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Import" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_action_id +msgid "Import Action" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "Import Excel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__import_file +msgid "Import File (*.xlsx)" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__filename +msgid "Import File Name" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import File Template" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "Import File(s) (*.xlsx)" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Import Instruction is how to get data from excel sheet and write them to an active record.\n" +" For example, user create a sales order document, and want to import order lines from excel.\n" +" In reverse direction to exporting, data from excel's cells will be mapped to record fields during import.\n" +" Cells can be mapped to record in header section (_HEAD_) and data table can be mapped to row section (one2many field, begins from specifed cells." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import Successful!" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section part, map data fields (e.g., number, partner_id.name) into" +" cells (e.g., B1, B2)." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section, map cells (e.g., B1, B2) into data fields (e.g., number, " +"partner_id)." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data list will be rolled out from one2many row field (e.g., " +"order_line), and map data field (i.e., product_id.name, uom_id.name, qty) " +"into the first row cells to start rolling (e.g., A6, B6, C6)." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data table from excel can be imported to one2many row field " +"(e.g., order_line) by mapping cells on first row onwards (e.g., A6, B6, C6) " +"to fields (e.g., product_id, uom_id, qty)" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Input Instruction (Dict.)" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__instruction +msgid "Instruction" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__input_instruction +msgid "Instruction (Input)" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__instruction +msgid "Instruction on how to import/export, prepared by system." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "Invalid declaration, %s has no valid field type" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "Invalid file style, only .xls or .xlsx file allowed" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +msgid "Invalid style type %s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +msgid "Invalid value %(value)s for style type %(key)s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +msgid "" +"Key Error\n" +"%s" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_date +msgid "Last Updated on" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__gname +msgid "" +"Multiple template of same model, can belong to same group,\n" +"result in multiple template selection" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__no_delete +msgid "No Delete" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "No data_dict['__IMPORT__'] in template %s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +msgid "No file content!" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +msgid "No file in %s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "No template found" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +msgid "Not enough worksheets" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +msgid "Only one id is allowed for excel_import_export" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__redirect_action +msgid "Optional action, redirection after finish import operation" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_extension +msgid "Optional for CSV, default is .csv" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_delimiter +msgid "Optional for CSV, default is comma." +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_quote +msgid "Optional for CSV, default is full quoting." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "Please select Excel file to import" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +msgid "Position %s is not valid" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__post_import_hook +msgid "Post Import Function Hook" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Post Import Hook" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "" +"Post import operation error\n" +"%s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +msgid "Records in %s exceed max records allowed" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Export Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Import Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Report Menu" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_ir_actions_report +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_action_id +msgid "Report Action" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_menu_id +msgid "Report Menu" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_model_id +msgid "Report Model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__report_type +msgid "Report Type" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__res_model +msgid "Res Model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_id +msgid "Resource ID" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_ids +msgid "Resource IDs" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__res_model +msgid "Resource Model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_field +msgid "Result Field" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__redirect_action +msgid "Return Action" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__row +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__row +msgid "Row" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__row_field +msgid "Row Field" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__datas +msgid "Sample" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sample Input Instruction as Dictionary" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__domain +msgid "Search Criterias" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__section_type +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__section_type +msgid "Section Type" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sequence +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sequence +msgid "Sequence" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "Set Templates" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sheet +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__sheet +msgid "Sheet" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "Sheet %s not found" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__show_instruction +msgid "Show Output" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__smart_search +msgid "Smart Search" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__state +msgid "State" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style_cond +msgid "Style w/Cond." +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_sum +msgid "Sum" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__template_id +msgid "Template" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +msgid "Template %(report_name)s on model %(model)s is not unique!" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__fname +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__name +msgid "Template Name" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +msgid "" +"Template with CSV Quoting = False, data must not contain the same char as " +"delimiter -> \"%s\"" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "Template's model mismatch" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__res_model +msgid "The database object this attachment will be attached to." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +msgid "The selected redirect action is not for model %s" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__report_type +msgid "" +"The type of the report that will be rendered, each one having its own " +"rendering method. HTML means the report will be opened directly in your " +"browser PDF means the report will be rendered using Wkhtmltopdf and " +"downloaded by the user." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +msgid "" +"The value for the '%(field)s' field is expected to be in cell " +"%(cell_position)s, but no column exists for that cell in the Excel sheet. " +"Please check your Excel file." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +msgid "This import action is not usable in this document context" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__show_instruction +msgid "" +"This is the computed instruction based on tab Import/Export,\n" +"to be used by xlsx import/export engine" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__input_instruction +msgid "This is used to construct instruction in tab Import/Export" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Use common report wizard model, instead of create specific model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__result_model_id +msgid "When use commone wizard, choose the result model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_export_xlsx_wizard +msgid "Wizard for exporting excel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_import_xlsx_wizard +msgid "Wizard for importing excel" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__template_id +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "XLSX Template" +msgstr "" + +#. module: excel_import_export +#: model:ir.actions.act_window,name:excel_import_export.action_xlsx_template +#: model:ir.ui.menu,name:excel_import_export.menu_xlsx_template +msgid "XLSX Templates" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "You can select multiple files to import." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "or" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "⇒ Get Sample Import Template" +msgstr "" diff --git a/excel_import_export/i18n/it.po b/excel_import_export/i18n/it.po new file mode 100644 index 00000000000..7e9027ac52b --- /dev/null +++ b/excel_import_export/i18n/it.po @@ -0,0 +1,1691 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * excel_import_export +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-11-28 10:43+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.10.4\n" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "${object.post_import_do_something()}" +msgstr "${object.post_import_do_something()}" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "'%s' sheet not found" +msgstr "Foglio '%s' non trovato" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__state +msgid "" +"* Choose: wizard show in user selection mode\n" +"* Get: wizard show results from user action" +msgstr "" +"* Choose: wizard mostrato in modalità selezione utente\n" +"* Get: wizard mostra i risultati dall'azione dell'utente" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Cell: Location of data in excel sheet (e.g., A1, B1, ...)" +msgstr "Cella: Posizione del dato nel foglio excel (ad es. A1, B1, ...)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Continue: If not selected, start rolling with specified first row " +"cells. If selected, continue from previous one2many field" +msgstr "" +"Continua: Se non selezionato, inizia riempiendo la prima riga di " +"celle specificata. Se selezionato, continua dal precedente campo one2many" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Extend: If selected, extend one row after one data row in order to " +"preserve the sum line" +msgstr "" +"Estendi: Se selezionato, estende una riga dopo l'altra al fine di " +"preservare la riga di somma" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} to " +"manipulate field value, e.g., if field = product_id, value will " +"represent product object, e.g., ${value and value.uom_id." +"name or \"\"}" +msgstr "" +"Cond. campo: Codice Python in ${...} per " +"manipolare il valore del campo, es., se il campo è product_id, valore rappresenterà l'oggetto prodotto, es., ${value and " +"value.uom_id.name or \"\"}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} value " +"will represent data from excel cell, e.g., if A1 = 'ABC', value " +"will represent 'ABC', e.g., ${value == \"ABC\" and \"X\" " +"or \"Y\"} thus can change from cell value to other value for import." +msgstr "" +"Cond. campo: codice Python nel valore ${...} reppresenterà dati dalla cella Excel, es., se A1 = 'ABC', " +"valore reppresenterà 'ABC', es., ${value == " +"\"ABC\" and \"X\" or \"Y\"} può quindi modificare da un valore della " +"cella ad un altro valore per l'importazione." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Field: Field of the record to be imported to, e.g., product_id" +msgstr "Campo: Campo del record dove importare, ad es. product_id" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field: Field of the record, e.g., product_id.uom_id.name. They are " +"orm compliant." +msgstr "" +"Campo: Campo del record, ad es. product_id.uom_id.name. Seguono le " +"convenzioni dell'orm." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"No Delete: By default, all one2many lines will be deleted before " +"import. Select this, to avoid deletion" +msgstr "" +"Non cancellare: Per default, tutte le righe one2many saranno " +"cancellate prima dell'importazione. Seleziona questo per evitare la " +"cancellazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Note:" +msgstr "Note:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field (e." +"g., line_ids) for row data" +msgstr "" +"Campo Riga: Usa _HEAD_ per il record stesso, e un campo one2many (ad " +"es. line_ids) per i dati della riga" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field for " +"row data, e.g., order_line, line_ids[max_row] where " +"[max_row] is optional number of rows to import" +msgstr "" +"Campo riga: Usa _HEAD_ per il record stesso, e un campo one2many per " +"i dati della riga, ad es. order_line, line_ids[max_row] " +"dove[max_row] è il numero massimo opzionale di righe da " +"importare" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet" +msgstr "" +"Foglio: Foglio (ad es. Foglio 1) o indice (ad es. 1) del foglio excel" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet to " +"export data to" +msgstr "" +"Foglio: Nome (ad es. Foglio 1) o indice (ad es. 1) del foglio excel " +"dove esportare i dati" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style w/Cond.: Conditional style by python code in #?...?, e.g., apply style for specific product, #?value.name == \"ABC\" " +"and #{font=bold;fill=red} or None?" +msgstr "" +"Stile con/Cond.: stile condizionale da codice Python in #?...?, es., applica lo sptile per un prodotto specifico, #?value.name " +"== \"ABC\" and #{font=bold;fill=red} or None?" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style: Default style in #{...} that apply to each cell, " +"e.g., #{align=left;style=text}. See module's style.py " +"for available styles." +msgstr "" +"Stile: stile predefinito in #{...} che si applica ad " +"ogni cella, es., #{align=left;style=text}. Vedere il style." +"py del modulo per gli stili disponibili." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sum: Add sum value on last row, @{sum}" +msgstr "" +"Somma: Aggiunge il valore della somma sull'ultima riga, @{sum}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"\n" +"{\n" +" '__EXPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" '_HEAD_': {\n" +" 'B2': 'partner_id.display_name${value or \"\"}" +"#{align=left;style=text}',\n" +" 'B3': 'name${value or \"\"}#{align=left;" +"style=text}',\n" +" },\n" +" 'line_ids': { # prefix with _CONT_ to continue rows from " +"previous row field\n" +" 'A6': 'product_id.display_name${value or \"\"}" +"#{style=text}',\n" +" 'C6': 'product_uom_qty${value or 0}" +"#{style=number}',\n" +" 'E6': 'price_unit${value or 0}" +"#{style=number}',\n" +" 'G6': 'price_subtotal${value or 0}" +"#{style=number}',\n" +" },\n" +" },\n" +" },\n" +" '__IMPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" 'order_line': { # prefix with _NODEL_ to not delete rows before " +"import\n" +" 'A6': 'product_id',\n" +" 'C6': 'product_uom_qty',\n" +" 'E6': 'price_unit${value > 0 and value or " +"0}',\n" +" },\n" +" },\n" +" },\n" +" '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +"}\n" +"\n" +" " +msgstr "" +"\n" +"{\n" +" '__EXPORT__': {\n" +" 'sale_order': { # il foglio può essere un nuome (stringa) o indice " +"(intero)\n" +" '_HEAD_': {\n" +" 'B2': 'partner_id.display_name${value or \"\"}" +"#{align=left;style=text}',\n" +" 'B3': 'name${value or \"\"}#{align=left;" +"style=text}',\n" +" },\n" +" 'line_ids': { # prefisso con _CONT_ per continuare la riga " +"dalla riga campo precedente \n" +" 'A6': 'product_id.display_name${value or \"\"}" +"#{style=text}',\n" +" 'C6': 'product_uom_qty${value or 0}" +"#{style=number}',\n" +" 'E6': 'price_unit${value or 0}" +"#{style=number}',\n" +" 'G6': 'price_subtotal${value or 0}" +"#{style=number}',\n" +" },\n" +" },\n" +" },\n" +" '__IMPORT__': {\n" +" 'sale_order': { # il foglio può essere un nuome (stringa) o " +"indice (intero)\n" +" 'order_line': { # prefisso con _NODEL_ per non cancellare le " +"righe prima dell'impostazione\n" +" 'A6': 'product_id',\n" +" 'C6': 'product_uom_qty',\n" +" 'E6': 'price_unit${value > 0 and value or " +"0}',\n" +" },\n" +" },\n" +" },\n" +" '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +"}\n" +"\n" +" " + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "date, datetime, time: some useful python classes" +msgstr "date, datetime, time: alcune utili classi python" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "model: active model, e.g., self.env['my.model']" +msgstr "modello: modello attivo, ad es. self.env['my.model']" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"object: record object or line object depends on Row Field" +msgstr "" +"oggetto: oggetto del record o oggetto della riga che dipende " +"dal Campo Riga" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Cell" +msgstr "valore: valore dalla Cella" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Field" +msgstr "valore: valore dal Campo" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Export Action" +msgstr "Aggiungi Azione Esportazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Import Action" +msgstr "Aggiungi Azione Importazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Report Menu" +msgstr "Aggiungi Menù Report" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add data column" +msgstr "Aggiungi colonna dati" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add header section" +msgstr "Aggiungi sezione intestazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add new report menu at root level" +msgstr "Aggiunge un nuovo report alla radice" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add row section" +msgstr "Aggiunge sezione riga" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add sheet section" +msgstr "Aggiunge sezione foglio" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__choose_template +msgid "Allow Choose Template" +msgstr "Consente selezione schema" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__assigned_attachment_ids +msgid "Assigned Attachments" +msgstr "Allegati assegnati" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_styles +msgid "Available styles for excel" +msgstr "Stili disponibili per excel" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__no_delete +msgid "" +"By default, all rows will be deleted before import.\n" +"Select No Delete, otherwise" +msgstr "" +"Di default, tutte le righe saranno cancellate prima dell'importazione.\n" +"Altrimenti seleziona Non Cancellare" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_delimiter +msgid "CSV Delimiter" +msgstr "Delimitatore CSV" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_extension +msgid "CSV File Extension" +msgstr "Estensione File CSV" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_quote +msgid "CSV Quoting" +msgstr "Virgolettatura CSV" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__post_import_hook +msgid "" +"Call a function after successful import, i.e.,\n" +"${object.post_import_do_something()}" +msgstr "" +"Chiama una funzione dopo un import eseguito con successo, ad es.,\n" +"${object.post_import_do_something()}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Cancel" +msgstr "Annulla" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__excel_cell +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__excel_cell +msgid "Cell" +msgstr "Cella" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__changeset_change_ids +msgid "Changeset Changes" +msgstr "Modifiche dell'insieme di modifiche" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__changeset_ids +msgid "Changesets" +msgstr "Insiemi di modifiche" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_crm_lead__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_sale_order__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__choose +msgid "Choose" +msgstr "Selezione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Choose Template:" +msgstr "Seleziona schema:" + +#. module: excel_import_export +#: model_terms:ir.actions.act_window,help:excel_import_export.action_xlsx_template +msgid "Click to create a XLSX Template Object." +msgstr "Fare clic per creare un schema oggetto XLSX." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Close" +msgstr "Chiudi" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Complete Prepare File (.xlsx)" +msgstr "Completa File Preparato (.xlsx)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Complete Prepare Report (.xlsx)" +msgstr "Completa Preparazione Report (.xlsx)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue" +msgstr "Continua" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue data rows after last data row" +msgstr "Continua le righe dei dati dopo l'ultima riga di dati" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__to_csv +msgid "Convert file into CSV format on export" +msgstr "Converte i file in formato CSV in esportazione" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__to_csv +msgid "Convert to CSV?" +msgstr "Converto in CSV?" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_changesets +msgid "Count Changesets" +msgstr "Conta insiemi di modifiche" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "Conteggio modifiche dell'insieme di modifiche in attesa" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "Conteggio insieme di modifiche in attesa" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__data +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__data +msgid "Data" +msgstr "Dati" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style +msgid "Default Style" +msgstr "Stile di Default" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__description +msgid "Description" +msgstr "Descrizione" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_export +msgid "Detailed of how excel data will be exported" +msgstr "Dettagli su come i dati excel saranno esportati" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_import +msgid "Detailed of how excel data will be imported" +msgstr "Dettaglio di come i dati excel saranno importati" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Document must be in %s states" +msgstr "Il documento deve essere in stato %s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Document must be in draft state" +msgstr "Il documento deve essere in stato bozza" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Easy Reporting" +msgstr "Reportistica facile" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"Error deleting data\n" +"%s" +msgstr "" +"Errore cancellando i dati\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"Error filling data into Excel sheets\n" +"%s" +msgstr "" +"Errore riempiendo i dati nei fogli Excel\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Error importing data" +msgstr "Errore importando i dati" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__ir_actions_report__report_type__excel +msgid "Excel" +msgstr "Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_export +msgid "Excel Export AbstractModel" +msgstr "Esportazione Excel AbstractModel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_import +msgid "Excel Import AbstractModel" +msgstr "Importazione Excel AbstractModel" + +#. module: excel_import_export +#: model:ir.ui.menu,name:excel_import_export.menu_excel_import_export +msgid "Excel Import/Export" +msgstr "Importazione/Esportazione Excel" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Excel Report" +msgstr "Report Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_report +msgid "Excel Report AbstractModel" +msgstr "Resoconto Excel AbstractModel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template +msgid "Excel template file and instruction" +msgstr "File schema excel e istruzioni" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +msgid "Execute" +msgstr "Esegui" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Execute Report" +msgstr "Esegui Report" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Export" +msgstr "Esporta" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_action_id +msgid "Export Action" +msgstr "Azione Esportazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Export Instruction is how to write data from an active data record to " +"specified cells in excel sheet.\n" +" For example, an active record can be a " +"sale order that user want to export.\n" +" The record itself will be mapped to the " +"header part of excel sheet. The record can contain multiple one2many fields, " +"which will be written as data lines.\n" +" You can look at following instruction as " +"Excel Sheet(s), each with 1 header section (_HEAD_) and multiple row " +"sections (one2many fields)." +msgstr "" +"Le istruzioni di esportazione indicano come scrivere i dati da un record " +"attivo nelle celle specifiche di un foglio Excel.\n" +" Per esempio, un record attivo può essere " +"un ordine di vendita che l'utente vuol esportare.\n" +" Il record stesso verrà mappato " +"nell'intestazione del foglio Excel. Il record può contenere campi multipli " +"one2many, che verranno scritti come righe di dati.\n" +" Le segenti istruzioni si possno " +"considerare cme fogli Excel, ognuno con una sezione intestazione (_HEAD_) e " +"sessioni righe multiple (one2many fields)." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend" +msgstr "Estendi" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend a blank row after filling each record, to extend the footer" +msgstr "" +"Estende una riga bianca dopo aver riempito ogni record, per estender il piè " +"di pagina" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_name +msgid "Field" +msgstr "Campo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_cond +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_cond +msgid "Field Cond." +msgstr "Cond. campo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__data +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__data +msgid "File" +msgstr "File" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "File \"%(fname)s\" not found in template, %(name)s." +msgstr "File \"%(fname)s\" non trovato nello schema, %(name)s." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__datas +msgid "File Content" +msgstr "Contenuto file" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__fname +msgid "File Name" +msgstr "Nome file" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Following are more explaination on each column:" +msgstr "Di seguito maggiori spiegazioni su ciascuna colonna:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Following show very simple example of the dictionary construct.\n" +" Normally, this will be within templates." +"xml file within addons." +msgstr "" +"Di seguito si mistra un semplice esempio della costruzione del dizionario.\n" +" Normalmente, questo è all'interno del " +"file templates.xml negli addons." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...} and #?...?, " +"following object are available," +msgstr "" +"Per il blocco di codice ${...} e #?...?, sono disponibili i segenti oggetti," + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...}, following object are " +"available," +msgstr "" +"Per il blocco di codice ${...}, sono disponibili i " +"seguenti oggetti," + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_report_xlsx_wizard +msgid "Generic Report Wizard, used with template reporting option" +msgstr "Wizard Report Generico, usato con l'opzione dello schema resoconto" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_crm_lead__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_sale_order__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__get +msgid "Get" +msgstr "Ottieni" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Get Import Template" +msgstr "Ottieni schema importazione" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__gname +msgid "Group Name" +msgstr "Nome gruppo" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__head +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__head +msgid "Head" +msgstr "Intestazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Export Instruction" +msgstr "Aiuto con le Istruzioni di Esportazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Import Instruction" +msgstr "Aiuto con le Istruzioni di Importazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Here is the exported file:" +msgstr "Qui il file esportato:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Here is the report file:" +msgstr "Qui il report file:" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__id +msgid "ID" +msgstr "ID" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__row_field +msgid "If section type is row, this field is required" +msgstr "Se il tipo sezione è riga, questo campo è obbligatorio" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"IllegalCharacterError\n" +"Some exporting data contain special character\n" +"%s" +msgstr "" +"IllegalCharacterError\n" +"Alcuni dati di esportazioni contengono caratteri speciali\n" +"%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Import" +msgstr "Importa" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_action_id +msgid "Import Action" +msgstr "Azione Importazione" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Import Excel" +msgstr "Importa Excel" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__import_file +msgid "Import File (*.xlsx)" +msgstr "Importa File (*.xlsx)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__filename +msgid "Import File Name" +msgstr "Nome file importazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import File Template" +msgstr "Schema file importazione" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "Import File(s) (*.xlsx)" +msgstr "Importa File (*.xlsx)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Import Instruction is how to get data from excel sheet and write them to an " +"active record.\n" +" For example, user create a sales order " +"document, and want to import order lines from excel.\n" +" In reverse direction to exporting, data " +"from excel's cells will be mapped to record fields during import.\n" +" Cells can be mapped to record in header " +"section (_HEAD_) and data table can be mapped to row section (one2many " +"field, begins from specifed cells." +msgstr "" +"Le istruzioni di importazione indicano come ottenere dati dai fogli Excel e " +"scriverli in un record attivo.\n" +" Per esempio, l'utente crea un documento " +"ordine di vendita e vuole impotare le righe ordine da Excel.\n" +" Viceversa per esportare, i dati dalle " +"celle Excel verranno mappati nei campi del record durante l'importazione.\n" +" Le celle possono essere mappate sui record " +"nella sezione intestazione (_HEAD_) e la tabella dati può essere mappata nel " +"campo della sezione riga (one2many), iniziando da una cella specifica." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import Successful!" +msgstr "Importazione eseguita con successo!" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section part, map data fields (e.g., number, partner_id.name) into " +"cells (e.g., B1, B2)." +msgstr "" +"Nella sezione intestazione, mappa i campi di dati (ad es., numero, " +"partner_id.name) in celle (ad es. B1, B2)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section, map cells (e.g., B1, B2) into data fields (e.g., number, " +"partner_id)." +msgstr "" +"Nella sezione intestazione, mappa celle (ad es. B1, B2) in campi dato (ad " +"es. numero, partner_id)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data list will be rolled out from one2many row field (e.g., " +"order_line), and map data field (i.e., product_id.name, uom_id.name, qty) " +"into the first row cells to start rolling (e.g., A6, B6, C6)." +msgstr "" +"Nella sezione riga, la lista dati verrà estratta dal campo riga one2many " +"(es. order_line), e il campo data mappa (cioè product_id.name, uom_id.name, " +"qty) nella prima cella della riga per iniziare l'estrazione (es. A6, B6, C6)." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data table from excel can be imported to one2many row field " +"(e.g., order_line) by mapping cells on first row onwards (e.g., A6, B6, C6) " +"to fields (e.g., product_id, uom_id, qty)" +msgstr "" +"Nella sezione riga, la tabella dati da Excel può essere importata in un " +"campo riga one2many (es, order_line) mappando le celle dalla prima riga in " +"avanti (es. A6, B6, C6) ai campi (es. product_id, uom_id, qty)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Input Instruction (Dict.)" +msgstr "Istruzioni di input (Diz.)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__instruction +msgid "Instruction" +msgstr "Istruzioni" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__input_instruction +msgid "Instruction (Input)" +msgstr "Istruzioni (Input)" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__instruction +msgid "Instruction on how to import/export, prepared by system." +msgstr "Istruzioni su come importare/esportare, preparate dal sistema." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Invalid declaration, %s has no valid field type" +msgstr "Dichiarazione non valida, %s non è un tipo di campo valido" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Invalid file style, only .xls or .xlsx file allowed" +msgstr "Tipologia file non valida, sono consentiti solo file .xls o .xlsx" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Invalid style type %s" +msgstr "Tipo stile %s non valido" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Invalid value %(value)s for style type %(key)s" +msgstr "Valore %(value)s non valido per il tipo stile %(key)s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"Key Error\n" +"%s" +msgstr "" +"Errore chiave\n" +"%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__gname +msgid "" +"Multiple template of same model, can belong to same group,\n" +"result in multiple template selection" +msgstr "" +"Schemi multipli dello stesso modello possono appartenere allo stesso " +"gruppo,\n" +"risultando in una selezione schema multiplo" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__no_delete +msgid "No Delete" +msgstr "Non Cancellare" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "No data_dict['__IMPORT__'] in template %s" +msgstr "Nessun data_dict['__IMPORT__'] nello schema %s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +#, python-format +msgid "No file content!" +msgstr "Il file non ha contenuto!" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#, python-format +msgid "No file in %s" +msgstr "Nessun file in %s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "No template found" +msgstr "Nessuno schema trovato" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "Not enough worksheets" +msgstr "Non abbastanza fogli di lavoro" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +#, python-format +msgid "Only one id is allowed for excel_import_export" +msgstr "Solo un id è consentito per excel_import_export" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__redirect_action +msgid "Optional action, redirection after finish import operation" +msgstr "Azione opzionale, redirezione dopo aver finito l'operazione di import" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_extension +msgid "Optional for CSV, default is .csv" +msgstr "Opzionale per CSV, il default è .csv" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_delimiter +msgid "Optional for CSV, default is comma." +msgstr "Opzionale per CSV, il default è virgola." + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_quote +msgid "Optional for CSV, default is full quoting." +msgstr "Opzionale per CSV, default è doppie virgolette." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Please select Excel file to import" +msgstr "Prego selezionare il file Excel da importare" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Position %s is not valid" +msgstr "Posizione %s non valida" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__post_import_hook +msgid "Post Import Function Hook" +msgstr "Aggancio Funzione Post Importazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Post Import Hook" +msgstr "Aggancio Post Importazione" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"Post import operation error\n" +"%s" +msgstr "" +"Errore operazione post import\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "Records in %s exceed max records allowed" +msgstr "I record in %s superano il numero massimo di record consentiti" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Export Action" +msgstr "Rimuove Azione di Esportazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Import Action" +msgstr "Rimuove Azione di Importazione" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Report Menu" +msgstr "Rimuove Menù Report" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_ir_actions_report +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_action_id +msgid "Report Action" +msgstr "Azione resoconto" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_menu_id +msgid "Report Menu" +msgstr "Menù Report" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_model_id +msgid "Report Model" +msgstr "Modello Report" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__report_type +msgid "Report Type" +msgstr "Tipo resoconto" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__res_model +msgid "Res Model" +msgstr "Modello res" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_id +msgid "Resource ID" +msgstr "ID risorsa" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_ids +msgid "Resource IDs" +msgstr "ID Risorse" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__res_model +msgid "Resource Model" +msgstr "Modello risorsa" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_field +msgid "Result Field" +msgstr "Campo Risultato" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__redirect_action +msgid "Return Action" +msgstr "Azione di Ritorno" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__row +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__row +msgid "Row" +msgstr "Riga" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__row_field +msgid "Row Field" +msgstr "Campo Riga" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__datas +msgid "Sample" +msgstr "Esempio" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sample Input Instruction as Dictionary" +msgstr "Esempio istruzione ingresso cme dizionario" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__domain +msgid "Search Criterias" +msgstr "Criteri di Ricerca" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__section_type +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__section_type +msgid "Section Type" +msgstr "Tipo sezione" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sequence +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sequence +msgid "Sequence" +msgstr "Sequenza" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Set Templates" +msgstr "Imposta schemi" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sheet +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__sheet +msgid "Sheet" +msgstr "Foglio" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Sheet %s not found" +msgstr "Il foglio %s non trovato" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__show_instruction +msgid "Show Output" +msgstr "Mostra Output" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__smart_search +msgid "Smart Search" +msgstr "Ricerca intelligente" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__state +msgid "State" +msgstr "Stato" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style_cond +msgid "Style w/Cond." +msgstr "Stile con Cond." + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_sum +msgid "Sum" +msgstr "Somma" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__template_id +msgid "Template" +msgstr "Modello" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +#, python-format +msgid "Template %(report_name)s on model %(model)s is not unique!" +msgstr "Lo schema %(report_name)s nel modello %(model)s non è univoco!" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__fname +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__name +msgid "Template Name" +msgstr "Nome modello" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "" +"Template with CSV Quoting = False, data must not contain the same char as " +"delimiter -> \"%s\"" +msgstr "" +"Schema CSV con Quoting = False, i dati non devno contenere lo stesso " +"carattere come separatore -> \"%s\"" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Template's model mismatch" +msgstr "Schema del modello non corrispondente" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__res_model +msgid "The database object this attachment will be attached to." +msgstr "L'oggetto del database a cui verrà assegnato questo allegato." + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_pending_changeset_changes +msgid "The number of pending changes of this record" +msgstr "Numero di modifiche di questo record in attesa" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_pending_changesets +msgid "The number of pending changesets of this record" +msgstr "Numero di insiemi di modifiche in attesa di questo record" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_changesets +msgid "The overall number of changesets of this record" +msgstr "Numero totale di insiemi di modifiche di questo record" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +#, python-format +msgid "The selected redirect action is not for model %s" +msgstr "L'azione di reindirizzamento selezionato non è per il modello %s" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__report_type +msgid "" +"The type of the report that will be rendered, each one having its own " +"rendering method. HTML means the report will be opened directly in your " +"browser PDF means the report will be rendered using Wkhtmltopdf and " +"downloaded by the user." +msgstr "" +"Il tipo di resoconto che verrà generato, ognuno avente il suo metodo di " +"generazione. HTML vuol dire che il resoconto sarà aperto direttamente nel " +"tuo browser mentre PDF vuol dire che il resoconto sarà generato usando " +"Wkhtmltopdf e scaricato dall'utente." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"The value for the '%(field)s' field is expected to be in cell " +"%(cell_position)s, but no column exists for that cell in the Excel sheet. " +"Please check your Excel file." +msgstr "" +"Il valore per il campo '%(field)s' dovrebbe essere nella cella " +"%(cell_position)s, ma non esiste alcuna colonna per quella cella nel foglio " +"Excel. Controllare il file Excel." + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "This import action is not usable in this document context" +msgstr "" +"Questa azione di importazione non è utilizzabile in questo contesto del " +"documento" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__show_instruction +msgid "" +"This is the computed instruction based on tab Import/Export,\n" +"to be used by xlsx import/export engine" +msgstr "" +"Questa è l'istruzione elaborata in base alla linguetta Importa/Esporta\n" +"da usare dal motore importa/esporta xlsx" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__input_instruction +msgid "This is used to construct instruction in tab Import/Export" +msgstr "Questo è usato per costruire le istruzioni nel tab Importa/Esporta" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Use common report wizard model, instead of create specific model" +msgstr "" +"Usa il modello comune per il wizard dei report, invece di creare un modello " +"specifico" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "L'utente può vedere l'insieme delle modifiche" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__result_model_id +msgid "When use commone wizard, choose the result model" +msgstr "Quando si una un wizard comune, seleziona il modello del risultato" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_export_xlsx_wizard +msgid "Wizard for exporting excel" +msgstr "Wizard per l'esportazione excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_import_xlsx_wizard +msgid "Wizard for importing excel" +msgstr "Wizard per l'importazione excel" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__template_id +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "XLSX Template" +msgstr "Schema XLSX" + +#. module: excel_import_export +#: model:ir.actions.act_window,name:excel_import_export.action_xlsx_template +#: model:ir.ui.menu,name:excel_import_export.menu_xlsx_template +msgid "XLSX Templates" +msgstr "Schemi XLSX" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "You can select multiple files to import." +msgstr "Puoi selezionare file multipli per l'importazione." + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "or" +msgstr "o" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "⇒ Get Sample Import Template" +msgstr "⇒ Scarica esempio schema di importazione" + +#~ msgid "" +#~ "\n" +#~ "{\n" +#~ " '__EXPORT__': {\n" +#~ " 'sale_order': { # sheet can be name (string) or index (integer)\n" +#~ " '_HEAD_': {\n" +#~ " 'B2': 'partner_id.display_name${value or \"\"}" +#~ "#{align=left;style=text}',\n" +#~ " 'B3': 'name${value or \"\"}#{align=left;style=text}',\n" +#~ " },\n" +#~ " 'line_ids': { # prefix with _CONT_ to continue rows from " +#~ "previous row field\n" +#~ " 'A6': 'product_id.display_name${value or \"\"}" +#~ "#{style=text}',\n" +#~ " 'C6': 'product_uom_qty${value or 0}#{style=number}',\n" +#~ " 'E6': 'price_unit${value or 0}#{style=number}',\n" +#~ " 'G6': 'price_subtotal${value or 0}#{style=number}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__IMPORT__': {\n" +#~ " 'sale_order': { # sheet can be name (string) or index (integer)\n" +#~ " 'order_line': { # prefix with _NODEL_ to not delete rows " +#~ "before import\n" +#~ " 'A6': 'product_id',\n" +#~ " 'C6': 'product_uom_qty',\n" +#~ " 'E6': 'price_unit${value > 0 and value or 0}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +#~ "}\n" +#~ "\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "{\n" +#~ " '__EXPORT__': {\n" +#~ " 'sale_order': { # foglio può essere nome (stringa) o indice " +#~ "(intero)\n" +#~ " '_HEAD_': {\n" +#~ " 'B2': 'partner_id.display_name${value or \"\"}" +#~ "#{align=left;style=text}',\n" +#~ " 'B3': 'name${value or \"\"}#{align=left;style=text}',\n" +#~ " },\n" +#~ " 'line_ids': { # prefisso _CONT_ per continuare le righe " +#~ "dalla precedente campo\n" +#~ " 'A6': 'product_id.display_name${value or \"\"}" +#~ "#{style=text}',\n" +#~ " 'C6': 'product_uom_qty${value or 0}#{style=number}',\n" +#~ " 'E6': 'price_unit${value or 0}#{style=number}',\n" +#~ " 'G6': 'price_subtotal${value or 0}#{style=number}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__IMPORT__': {\n" +#~ " 'sale_order': { # foglio può essere nome (stringa) o indice " +#~ "(intero)\n" +#~ " 'order_line': { # prefisso _NODEL_ per non cancellare le " +#~ "righe prima dell'importazione\n" +#~ " 'A6': 'product_id',\n" +#~ " 'C6': 'product_uom_qty',\n" +#~ " 'E6': 'price_unit${value > 0 and value or 0}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +#~ "}\n" +#~ "\n" +#~ " " + +#, python-format +#~ msgid "" +#~ "A popup window with your report was blocked. You may need to change your " +#~ "browser settings to allow popup windows for this page." +#~ msgstr "" +#~ "Una finestra di popup con il tuo report è stata bloccata. Bisogna " +#~ "cambiare le impostazioni del browser per consentire le finestre popup da " +#~ "questa pagina." + +#, python-format +#~ msgid "File \"%s\" not found in template, %s." +#~ msgstr "Il file \"%s\" non trovato nel modello, %s." + +#~ msgid "" +#~ "For code block ${...} and #?...?, following " +#~ "object are available," +#~ msgstr "" +#~ "Per il blocco di codice ${...} e #?...?, i " +#~ "seguenti oggetti sono disponibili," + +#~ msgid "For code block ${...}, following object are available," +#~ msgstr "" +#~ "Per il blocco di codice ${...}, i seguenti oggetti sono " +#~ "disponibili," + +#, python-format +#~ msgid "Invalid value {} for style type {}" +#~ msgstr "Valore non valido {} per il tipo stile {}" + +#, python-format +#~ msgid "Template %s on model %s is not unique!" +#~ msgstr "Il modello %s sul modello %s non è unico!" + +#, python-format +#~ msgid "Warning" +#~ msgstr "Avviso" diff --git a/excel_import_export/i18n/zh_CN.po b/excel_import_export/i18n/zh_CN.po new file mode 100644 index 00000000000..ea34c528e67 --- /dev/null +++ b/excel_import_export/i18n/zh_CN.po @@ -0,0 +1,1631 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * excel_import_export +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-08-31 18:23+0000\n" +"Last-Translator: 黎伟杰 <674416404@qq.com>\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.8\n" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "${object.post_import_do_something()}" +msgstr "${object.post_import_do_something()}" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "'%s' sheet not found" +msgstr "'%s' 找不到工作表" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__state +msgid "" +"* Choose: wizard show in user selection mode\n" +"* Get: wizard show results from user action" +msgstr "" +"* 选择:用户选择模式下的向导显示\n" +"* 获取:向导显示用户操作的结果" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Cell: Location of data in excel sheet (e.g., A1, B1, ...)" +msgstr "单元格:Excel工作表中的数据位置(例如:A1,B1,...)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Continue: If not selected, start rolling with specified first row " +"cells. If selected, continue from previous one2many field" +msgstr "" +"继续: 如果未选中,则使用指定的第一行单元格开始滚动。 如果选中,则从之" +"前的one2many字段继续" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Extend: If selected, extend one row after one data row in order to " +"preserve the sum line" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} to " +"manipulate field value, e.g., if field = product_id, value will " +"represent product object, e.g., ${value and value.uom_id." +"name or \"\"}" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field Cond.: Python code in ${...} value " +"will represent data from excel cell, e.g., if A1 = 'ABC', value " +"will represent 'ABC', e.g., ${value == \"ABC\" and \"X\" " +"or \"Y\"} thus can change from cell value to other value for import." +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Field: Field of the record to be imported to, e.g., product_id" +msgstr "字段: 要导入的记录的字段,例如product_id" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Field: Field of the record, e.g., product_id.uom_id.name. They are " +"orm compliant." +msgstr "字段: 记录的字段,例如product_id.uom_id.name。他们是合规的。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"No Delete: By default, all one2many lines will be deleted before " +"import. Select this, to avoid deletion" +msgstr "" +"不删除: 默认情况下,导入前将删除所有one2many行。选择此项,以避免删除" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Note:" +msgstr "备注:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field (e." +"g., line_ids) for row data" +msgstr "" +"行字段: 使用_HEAD_表示记录本身,使用one2many字段(例如line_ids)表示行" +"数据" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Row Field: Use _HEAD_ for the record itself, and one2many field for " +"row data, e.g., order_line, line_ids[max_row] where " +"[max_row] is optional number of rows to import" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet" +msgstr "工作表: excel工作表的名称(例如,工作表1)或索引(例如,1)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet to " +"export data to" +msgstr "" +"工作表: 要将数据导出到的Excel工作表的名称(例如,工作表1)或索引(例" +"如,1)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style w/Cond.: Conditional style by python code in #?...?, e.g., apply style for specific product, #?value.name == \"ABC\" " +"and #{font=bold;fill=red} or None?" +msgstr "" +"样式条件: python代码中的条件样式 #?...?, 例如,为特定产品" +"应用样式, #?value.name == \"ABC\" and #{font=bold;fill=red} or None?" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Style: Default style in #{...} that apply to each cell, " +"e.g., #{align=left;style=text}. See module's style.py " +"for available styles." +msgstr "" +"样式: 默认样式#{...} 适用于每个单元格, 例如, " +"#{align=left;style=text}. 请参阅模块的style.py 可用的样" +"式。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sum: Add sum value on last row, @{sum}" +msgstr "总和: 在最后一行添加总和值, @{sum}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"\n" +"{\n" +" '__EXPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" '_HEAD_': {\n" +" 'B2': 'partner_id.display_name${value or \"\"}" +"#{align=left;style=text}',\n" +" 'B3': 'name${value or \"\"}#{align=left;" +"style=text}',\n" +" },\n" +" 'line_ids': { # prefix with _CONT_ to continue rows from " +"previous row field\n" +" 'A6': 'product_id.display_name${value or \"\"}" +"#{style=text}',\n" +" 'C6': 'product_uom_qty${value or 0}" +"#{style=number}',\n" +" 'E6': 'price_unit${value or 0}" +"#{style=number}',\n" +" 'G6': 'price_subtotal${value or 0}" +"#{style=number}',\n" +" },\n" +" },\n" +" },\n" +" '__IMPORT__': {\n" +" 'sale_order': { # sheet can be name (string) or index (integer)\n" +" 'order_line': { # prefix with _NODEL_ to not delete rows before " +"import\n" +" 'A6': 'product_id',\n" +" 'C6': 'product_uom_qty',\n" +" 'E6': 'price_unit${value > 0 and value or " +"0}',\n" +" },\n" +" },\n" +" },\n" +" '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +"}\n" +"\n" +" " +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "date, datetime, time: some useful python classes" +msgstr "date, datetime, time: 一些有用的python类" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "model: active model, e.g., self.env['my.model']" +msgstr "model: 活动模型,例如., self.env['my.model']" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"object: record object or line object depends on Row Field" +msgstr "object: 记录对象或行对象依赖于 行字段" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Cell" +msgstr "value: 值来自 单元格" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "value: value from Field" +msgstr "value: 值来自 字段" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Export Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Import Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add Report Menu" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add data column" +msgstr "添加数据列" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add header section" +msgstr "添加头部分" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add new report menu at root level" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add row section" +msgstr "添加行部分" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Add sheet section" +msgstr "添加工作表部分" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__choose_template +msgid "Allow Choose Template" +msgstr "添加表单部分" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__assigned_attachment_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__assigned_attachment_ids +msgid "Assigned Attachments" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_styles +msgid "Available styles for excel" +msgstr "excel的可用样式" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__no_delete +msgid "" +"By default, all rows will be deleted before import.\n" +"Select No Delete, otherwise" +msgstr "" +"默认情况下,导入前将删除所有行。\n" +"否则请选择“不删除”" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_delimiter +msgid "CSV Delimiter" +msgstr "CSV分隔符" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_extension +msgid "CSV File Extension" +msgstr "CSV文件扩展名" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__csv_quote +msgid "CSV Quoting" +msgstr "CSV引用" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__post_import_hook +msgid "" +"Call a function after successful import, i.e.,\n" +"${object.post_import_do_something()}" +msgstr "" +"成功导入后调用函数,即,\n" +"${object.post_import_do_something()}" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Cancel" +msgstr "取消" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__excel_cell +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__excel_cell +msgid "Cell" +msgstr "单元格" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__changeset_change_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__changeset_change_ids +msgid "Changeset Changes" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__changeset_ids +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__changeset_ids +msgid "Changesets" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_crm_lead__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_sale_order__state__choose +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__choose +msgid "Choose" +msgstr "选择" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Choose Template:" +msgstr "选择模板:" + +#. module: excel_import_export +#: model_terms:ir.actions.act_window,help:excel_import_export.action_xlsx_template +msgid "Click to create a XLSX Template Object." +msgstr "单击以创建XLSX模板对象。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Close" +msgstr "关闭" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Complete Prepare File (.xlsx)" +msgstr "完成准备文件(.xlsx)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Complete Prepare Report (.xlsx)" +msgstr "完成准备报告(.xlsx)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue" +msgstr "继续" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_cont +msgid "Continue data rows after last data row" +msgstr "在最后一个数据行之后继续数据行" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__to_csv +msgid "Convert file into CSV format on export" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__to_csv +msgid "Convert to CSV?" +msgstr "转换为CSV?" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_changesets +msgid "Count Changesets" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_pending_changeset_changes +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_pending_changeset_changes +msgid "Count Pending Changeset Changes" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__count_pending_changesets +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__count_pending_changesets +msgid "Count Pending Changesets" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_uid +msgid "Created by" +msgstr "创建者" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__create_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__create_date +msgid "Created on" +msgstr "创建时间" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__data +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__data +msgid "Data" +msgstr "数据" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style +msgid "Default Style" +msgstr "默认样式" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__description +msgid "Description" +msgstr "说明" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_export +msgid "Detailed of how excel data will be exported" +msgstr "详细介绍如何导出Excel数据" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template_import +msgid "Detailed of how excel data will be imported" +msgstr "详细介绍如何导入Excel数据" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__display_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__display_name +msgid "Display Name" +msgstr "显示名称" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Document must be in %s states" +msgstr "文档必须处于%s状态" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Document must be in draft state" +msgstr "文件必须处于草稿状态" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Easy Reporting" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"Error deleting data\n" +"%s" +msgstr "" +"删除数据时出错\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"Error filling data into Excel sheets\n" +"%s" +msgstr "" +"将数据填充到Excel工作表时出错\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Error importing data" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__ir_actions_report__report_type__excel +msgid "Excel" +msgstr "Excel" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_export +msgid "Excel Export AbstractModel" +msgstr "Excel导出抽象模型" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_import +msgid "Excel Import AbstractModel" +msgstr "Excel导入抽象模型" + +#. module: excel_import_export +#: model:ir.ui.menu,name:excel_import_export.menu_excel_import_export +msgid "Excel Import/Export" +msgstr "Excel导入/导出" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Excel Report" +msgstr "Excel报告" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_report +msgid "Excel Report AbstractModel" +msgstr "Excel报告抽象模型" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_xlsx_template +msgid "Excel template file and instruction" +msgstr "Excel模板文件和说明" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.report_xlsx_wizard +msgid "Execute" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Execute Report" +msgstr "执行报告" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Export" +msgstr "导出" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__export_action_id +msgid "Export Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Export Instruction is how to write data from an active data record to " +"specified cells in excel sheet.\n" +" For example, an active record can be a " +"sale order that user want to export.\n" +" The record itself will be mapped to the " +"header part of excel sheet. The record can contain multiple one2many fields, " +"which will be written as data lines.\n" +" You can look at following instruction as " +"Excel Sheet(s), each with 1 header section (_HEAD_) and multiple row " +"sections (one2many fields)." +msgstr "" +"导出指令是如何将数据从活动数据记录写入Excel工作表中的指定单元格。\n" +" 例如,活动记录可以是用户想要导出的销售订" +"单。\n" +" 记录本身将映射到Excel工作表的标题部分。该记" +"录可以包含多个one2many字段,这些字段将写为数据行。\n" +" 您可以将以下指令看作Excel工作表,每个工作表" +"有1个标题部分(_HEAD_)和多个行部分(one2many字段)。" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__is_extend +msgid "Extend a blank row after filling each record, to extend the footer" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_name +msgid "Field" +msgstr "字段" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__field_cond +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__field_cond +msgid "Field Cond." +msgstr "字段条件" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__data +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__data +msgid "File" +msgstr "文件" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "File \"%(fname)s\" not found in template, %(name)s." +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__datas +msgid "File Content" +msgstr "文件内容" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__name +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__fname +msgid "File Name" +msgstr "文件名" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Following are more explaination on each column:" +msgstr "以下是每列的详细说明:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Following show very simple example of the dictionary construct.\n" +" Normally, this will be within templates." +"xml file within addons." +msgstr "" +"下面显示了字典构造的非常简单的示例。\n" +" 通常,这将位于插件中的templates.xml文件" +"中。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...} and #?...?, " +"following object are available," +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"For code block ${...}, following object are " +"available," +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_report_xlsx_wizard +msgid "Generic Report Wizard, used with template reporting option" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__export_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__import_xlsx_wizard__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_crm_lead__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__report_sale_order__state__get +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_report__state__get +msgid "Get" +msgstr "获取" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Get Import Template" +msgstr "获取导入模板" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__gname +msgid "Group Name" +msgstr "组名" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__head +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__head +msgid "Head" +msgstr "头" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Export Instruction" +msgstr "导出帮助说明" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Help with Import Instruction" +msgstr "导入帮助说明" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +msgid "Here is the exported file:" +msgstr "这是导出的文件:" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "Here is the report file:" +msgstr "这是报告文件:" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__id +msgid "ID" +msgstr "ID" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__row_field +msgid "If section type is row, this field is required" +msgstr "如果部分类型是行,则此字段是必需的" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"IllegalCharacterError\n" +"Some exporting data contain special character\n" +"%s" +msgstr "" +"非法字符错误\n" +"某些导出数据包含特殊字符\n" +"%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_ids +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Import" +msgstr "导入" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__import_action_id +msgid "Import Action" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Import Excel" +msgstr "导入Excel" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__import_file +msgid "Import File (*.xlsx)" +msgstr "导入文件 (*.xlsx)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__filename +msgid "Import File Name" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import File Template" +msgstr "导入文件模板" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "Import File(s) (*.xlsx)" +msgstr "导入文件(*.xlsx)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"Import Instruction is how to get data from excel sheet and write them to an " +"active record.\n" +" For example, user create a sales order " +"document, and want to import order lines from excel.\n" +" In reverse direction to exporting, data " +"from excel's cells will be mapped to record fields during import.\n" +" Cells can be mapped to record in header " +"section (_HEAD_) and data table can be mapped to row section (one2many " +"field, begins from specifed cells." +msgstr "" +"导入指令是如何从Excel工作表中获取数据并将其写入活动记录。\n" +" 例如,用户创建销售订单文档,并希望从excel导" +"入订单行。\n" +" 与导出相反,excel单元格中的数据将在导入期间" +"映射到记录字段。\n" +" 单元格可以映射到标题部分(_HEAD_)中的记" +"录,数据表可以映射到行部分(one2many字段,从指定的单元格开始)。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "Import Successful!" +msgstr "导入成功!" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section part, map data fields (e.g., number, partner_id.name) into " +"cells (e.g., B1, B2)." +msgstr "" +"在头部分,将数据字段(例如,number, partner id.name)映射到单元格(例如,B1, " +"B2)。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In header section, map cells (e.g., B1, B2) into data fields (e.g., number, " +"partner_id)." +msgstr "在头部分,将单元格(如B1、B2)映射到数据字段(如number、合作伙伴id)。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data list will be rolled out from one2many row field (e.g., " +"order_line), and map data field (i.e., product_id.name, uom_id.name, qty) " +"into the first row cells to start rolling (e.g., A6, B6, C6)." +msgstr "" +"在行部分中,数据列表将从one2many行字段(例如,order_line)推出,并将数据字段" +"(即product_id.name,uom_id.name,qty)映射到第一行单元格以开始滚动(例如," +"A6,B6,C6)。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "" +"In row section, data table from excel can be imported to one2many row field " +"(e.g., order_line) by mapping cells on first row onwards (e.g., A6, B6, C6) " +"to fields (e.g., product_id, uom_id, qty)" +msgstr "" +"在行部分中,可以通过将第一行上的单元格(例如,A6,B6,C6)映射到字段(例如," +"product_id,uom_id,qty),将来自excel的数据表导入到one2many行字段(例如," +"order_line)" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Input Instruction (Dict.)" +msgstr "输入指令(字典)" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__instruction +msgid "Instruction" +msgstr "指令" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__input_instruction +msgid "Instruction (Input)" +msgstr "指令(输入)" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__instruction +msgid "Instruction on how to import/export, prepared by system." +msgstr "关于如何导入/导出的说明,由系统准备。" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Invalid declaration, %s has no valid field type" +msgstr "声明无效,%s没有有效的字段类型" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Invalid file style, only .xls or .xlsx file allowed" +msgstr "文件样式无效,仅允许.xls或.xlsx文件" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Invalid style type %s" +msgstr "样式类型%s无效" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Invalid value %(value)s for style type %(key)s" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "" +"Key Error\n" +"%s" +msgstr "" +"关键字错误\n" +"%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export____last_update +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import____last_update +msgid "Last Modified on" +msgstr "最后修改时间" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_uid +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_uid +msgid "Last Updated by" +msgstr "最后更新者" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__write_date +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__write_date +msgid "Last Updated on" +msgstr "最后更新时间" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__gname +msgid "" +"Multiple template of same model, can belong to same group,\n" +"result in multiple template selection" +msgstr "" +"同一模型的多个模板,可以属于同一组,\n" +"导致多个模板选择" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__no_delete +msgid "No Delete" +msgstr "不删除" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "No data_dict['__IMPORT__'] in template %s" +msgstr "模版%s中没有 data_dict['__IMPORT__']" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +#, python-format +msgid "No file content!" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#, python-format +msgid "No file in %s" +msgstr "%s中没有文件" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_report.py:0 +#: code:addons/excel_import_export/wizard/export_xlsx_wizard.py:0 +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "No template found" +msgstr "找不到模板" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "Not enough worksheets" +msgstr "没有足够的工作表" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +#, python-format +msgid "Only one id is allowed for excel_import_export" +msgstr "excel_import_export只允许一个id" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__redirect_action +msgid "Optional action, redirection after finish import operation" +msgstr "可选操作,导入操作完成后重定向" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_extension +msgid "Optional for CSV, default is .csv" +msgstr "CSV的可选项,默认为.csv" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_delimiter +msgid "Optional for CSV, default is comma." +msgstr "CSV的可选项,默认为逗号。" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__csv_quote +msgid "Optional for CSV, default is full quoting." +msgstr "CSV的可选项,默认为完全引用。" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Please select Excel file to import" +msgstr "请选择要导入的Excel文件" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "Position %s is not valid" +msgstr "位置%s无效" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__post_import_hook +msgid "Post Import Function Hook" +msgstr "导入后功能挂钩" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Post Import Hook" +msgstr "导入后挂钩" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"Post import operation error\n" +"%s" +msgstr "" +"发布导入操作错误\n" +"%s" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#, python-format +msgid "Records in %s exceed max records allowed" +msgstr "%s中的记录超过允许的最大记录" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Export Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Import Action" +msgstr "" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Remove Report Menu" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_ir_actions_report +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_action_id +msgid "Report Action" +msgstr "报告动作" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__report_menu_id +msgid "Report Menu" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_model_id +msgid "Report Model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__report_type +msgid "Report Type" +msgstr "报告类型" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__res_model +msgid "Res Model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_id +msgid "Resource ID" +msgstr "资源ID" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_ids +msgid "Resource IDs" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__res_model +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__res_model +msgid "Resource Model" +msgstr "资源模型" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__result_field +msgid "Result Field" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__redirect_action +msgid "Return Action" +msgstr "返回动作" + +#. module: excel_import_export +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__row +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__row +msgid "Row" +msgstr "行" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__row_field +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__row_field +msgid "Row Field" +msgstr "行字段" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__datas +msgid "Sample" +msgstr "样本" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "Sample Input Instruction as Dictionary" +msgstr "样本输入指令为字典" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__domain +msgid "Search Criterias" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__section_type +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__section_type +msgid "Section Type" +msgstr "部分类型" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sequence +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sequence +msgid "Sequence" +msgstr "序列" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "Set Templates" +msgstr "设置模板" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__sheet +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_export__section_type__sheet +#: model:ir.model.fields.selection,name:excel_import_export.selection__xlsx_template_import__section_type__sheet +msgid "Sheet" +msgstr "工作表" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Sheet %s not found" +msgstr "未找到工作表%s" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__show_instruction +msgid "Show Output" +msgstr "显示输出" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__smart_search +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__smart_search +msgid "Smart Search" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__state +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__state +msgid "State" +msgstr "状态" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__style_cond +msgid "Style w/Cond." +msgstr "样式条件" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__is_sum +msgid "Sum" +msgstr "总和" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__template_id +msgid "Template" +msgstr "模板" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/ir_report.py:0 +#, python-format +msgid "Template %(report_name)s on model %(model)s is not unique!" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__fname +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__name +msgid "Template Name" +msgstr "模板名称" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/common.py:0 +#, python-format +msgid "" +"Template with CSV Quoting = False, data must not contain the same char as " +"delimiter -> \"%s\"" +msgstr "CSV Quoting =False的模板,数据不能包含与分隔符相同的字符->\"%s\"" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_export.py:0 +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "Template's model mismatch" +msgstr "模板的模型不匹配" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__res_model +msgid "The database object this attachment will be attached to." +msgstr "此附件将附加到的数据库对象。" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_pending_changeset_changes +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_pending_changeset_changes +msgid "The number of pending changes of this record" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_pending_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_pending_changesets +msgid "The number of pending changesets of this record" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_export_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_report_xlsx_wizard__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_export__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_import__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_report__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_styles__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_export__count_changesets +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template_import__count_changesets +msgid "The overall number of changesets of this record" +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_template.py:0 +#, python-format +msgid "The selected redirect action is not for model %s" +msgstr "选定的重定向操作不适用于模型%s" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_ir_actions_report__report_type +msgid "" +"The type of the report that will be rendered, each one having its own " +"rendering method. HTML means the report will be opened directly in your " +"browser PDF means the report will be rendered using Wkhtmltopdf and " +"downloaded by the user." +msgstr "" +"将呈现的报告类型,每个报告都有自己的呈现方法。HTML表示报告将直接在浏览器中打" +"开PDF表示报告将使用Wkhtmltopdf呈现并由用户下载。" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/models/xlsx_import.py:0 +#, python-format +msgid "" +"The value for the '%(field)s' field is expected to be in cell " +"%(cell_position)s, but no column exists for that cell in the Excel sheet. " +"Please check your Excel file." +msgstr "" + +#. module: excel_import_export +#. odoo-python +#: code:addons/excel_import_export/wizard/import_xlsx_wizard.py:0 +#, python-format +msgid "This import action is not usable in this document context" +msgstr "此导入操作在此文档上下文中不可用" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__show_instruction +msgid "" +"This is the computed instruction based on tab Import/Export,\n" +"to be used by xlsx import/export engine" +msgstr "" +"这是基于选项卡导入/导出的计算指令,\n" +"由xlsx导入/导出引擎使用" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__input_instruction +msgid "This is used to construct instruction in tab Import/Export" +msgstr "这用于构造选项卡导入/导出中的指令" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__use_report_wizard +msgid "Use common report wizard model, instead of create specific model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_export_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_import_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_ir_actions_report__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_report_xlsx_wizard__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_export__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_import__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_report__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_styles__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__user_can_see_changeset +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__user_can_see_changeset +msgid "User Can See Changeset" +msgstr "" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_xlsx_template__result_model_id +msgid "When use commone wizard, choose the result model" +msgstr "" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_export_xlsx_wizard +msgid "Wizard for exporting excel" +msgstr "导出excel的向导" + +#. module: excel_import_export +#: model:ir.model,name:excel_import_export.model_import_xlsx_wizard +msgid "Wizard for importing excel" +msgstr "导入excel的向导" + +#. module: excel_import_export +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_export__template_id +#: model:ir.model.fields,field_description:excel_import_export.field_xlsx_template_import__template_id +#: model_terms:ir.ui.view,arch_db:excel_import_export.view_xlsx_template_form +msgid "XLSX Template" +msgstr "XLSX模板" + +#. module: excel_import_export +#: model:ir.actions.act_window,name:excel_import_export.action_xlsx_template +#: model:ir.ui.menu,name:excel_import_export.menu_xlsx_template +msgid "XLSX Templates" +msgstr "XLSX模板" + +#. module: excel_import_export +#: model:ir.model.fields,help:excel_import_export.field_import_xlsx_wizard__attachment_ids +msgid "You can select multiple files to import." +msgstr "您可以选择要导入的多个文件。" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.export_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +#: model_terms:ir.ui.view,arch_db:excel_import_export.xlsx_report_view +msgid "or" +msgstr "或" + +#. module: excel_import_export +#: model_terms:ir.ui.view,arch_db:excel_import_export.import_xlsx_wizard +msgid "⇒ Get Sample Import Template" +msgstr "⇒ 获取示例导入模板" + +#~ msgid "" +#~ "Field Cond.: Python code in ${...} to manipulate " +#~ "field value, e.g., if field = product_id, value will " +#~ "represent product object, e.g., ${value and value.uom_id.name or " +#~ "\"\"}" +#~ msgstr "" +#~ "字段条件: Python代码${...} 操纵字段值, 例如, if field " +#~ "= product_id, value 将代表产品对象, 例如, ${value and " +#~ "value.uom_id.name or \"\"}" + +#~ msgid "" +#~ "Field Cond.: Python code in ${...} value will " +#~ "represent data from excel cell, e.g., if A1 = 'ABC', value " +#~ "will represent 'ABC', e.g., ${value == \"ABC\" and \"X\" or \"Y\"} thus can change from cell value to other value for import." +#~ msgstr "" +#~ "字段条件: Python代码 ${...} 值将代表来自excel 单元格的" +#~ "数据, 例如, if A1 = 'ABC', value 代表'ABC',例如, " +#~ "${value == \"ABC\" and \"X\" or \"Y\"} 因此可以从单元格值更改" +#~ "为其他值以进行导入." + +#~ msgid "" +#~ "\n" +#~ "{\n" +#~ " '__EXPORT__': {\n" +#~ " 'sale_order': { # sheet can be name (string) or index (integer)\n" +#~ " '_HEAD_': {\n" +#~ " 'B2': 'partner_id.display_name${value or \"\"}" +#~ "#{align=left;style=text}',\n" +#~ " 'B3': 'name${value or \"\"}#{align=left;style=text}',\n" +#~ " },\n" +#~ " 'line_ids': { # prefix with _CONT_ to continue rows from " +#~ "previous row field\n" +#~ " 'A6': 'product_id.display_name${value or \"\"}" +#~ "#{style=text}',\n" +#~ " 'C6': 'product_uom_qty${value or 0}#{style=number}',\n" +#~ " 'E6': 'price_unit${value or 0}#{style=number}',\n" +#~ " 'G6': 'price_subtotal${value or 0}#{style=number}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__IMPORT__': {\n" +#~ " 'sale_order': { # sheet can be name (string) or index (integer)\n" +#~ " 'order_line': { # prefix with _NODEL_ to not delete rows " +#~ "before import\n" +#~ " 'A6': 'product_id',\n" +#~ " 'C6': 'product_uom_qty',\n" +#~ " 'E6': 'price_unit${value > 0 and value or 0}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +#~ "}\n" +#~ "\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "{\n" +#~ " '__EXPORT__': {\n" +#~ " 'sale_order': { # 工作表名称可以是(字符串)或索引(整数)\n" +#~ " '_HEAD_': {\n" +#~ " 'B2': 'partner_id.display_name${value or \"\"}" +#~ "#{align=left;style=text}',\n" +#~ " 'B3': 'name${value or \"\"}#{align=left;style=text}',\n" +#~ " },\n" +#~ " 'line_ids': { # prefix with _CONT_ to continue rows from " +#~ "previous row field\n" +#~ " 'A6': 'product_id.display_name${value or \"\"}" +#~ "#{style=text}',\n" +#~ " 'C6': 'product_uom_qty${value or 0}#{style=number}',\n" +#~ " 'E6': 'price_unit${value or 0}#{style=number}',\n" +#~ " 'G6': 'price_subtotal${value or 0}#{style=number}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__IMPORT__': {\n" +#~ " 'sale_order': { # sheet can be name (string) or index (integer)\n" +#~ " 'order_line': { # prefix with _NODEL_ to not delete rows " +#~ "before import\n" +#~ " 'A6': 'product_id',\n" +#~ " 'C6': 'product_uom_qty',\n" +#~ " 'E6': 'price_unit${value > 0 and value or 0}',\n" +#~ " },\n" +#~ " },\n" +#~ " },\n" +#~ " '__POST_IMPORT__': '${object.post_import_do_something()}',\n" +#~ "}\n" +#~ "\n" +#~ " " + +#, python-format +#~ msgid "" +#~ "A popup window with your report was blocked. You may need to change your " +#~ "browser settings to allow popup windows for this page." +#~ msgstr "" +#~ "您的报告的弹出窗口被阻止。您可能需要更改浏览器设置以允许此页面的弹出窗口。" + +#, python-format +#~ msgid "File \"%s\" not found in template, %s." +#~ msgstr "文件\"%s\"在模板“%s”中没有找到。" + +#~ msgid "" +#~ "For code block ${...} and #?...?, following " +#~ "object are available," +#~ msgstr "" +#~ "对于代码块 ${...}#?...?, 以下对象可用," + +#~ msgid "For code block ${...}, following object are available," +#~ msgstr "对于代码块${...}, 以下对象可用," + +#, python-format +#~ msgid "Template %s on model %s is not unique!" +#~ msgstr "模板%s在模型%s上不是唯一的!" + +#, python-format +#~ msgid "Warning" +#~ msgstr "警告" + +#~ msgid "" +#~ "Error importing data\n" +#~ "%s" +#~ msgstr "" +#~ "导入数据时出错\n" +#~ "%s" + +#~ msgid "HTML" +#~ msgstr "HTML" + +#~ msgid "Invalid value %s for style type %s" +#~ msgstr "样式类型%s的值%s无效" + +#~ msgid "PDF" +#~ msgstr "PDF" + +#~ msgid "Text" +#~ msgstr "文本" diff --git a/excel_import_export/models/__init__.py b/excel_import_export/models/__init__.py new file mode 100644 index 00000000000..52501c936b5 --- /dev/null +++ b/excel_import_export/models/__init__.py @@ -0,0 +1,9 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) +from . import styles +from . import common +from . import xlsx_export +from . import xlsx_import +from . import xlsx_template +from . import xlsx_report +from . import ir_report diff --git a/excel_import_export/models/common.py b/excel_import_export/models/common.py new file mode 100644 index 00000000000..2e494baee93 --- /dev/null +++ b/excel_import_export/models/common.py @@ -0,0 +1,339 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +# pylint: disable=prefer-env-translation + +import csv +import itertools +import re +import string +import uuid +from ast import literal_eval +from datetime import datetime as dt +from io import StringIO + +import xlrd +from dateutil.parser import parse + +from odoo import _ +from odoo.exceptions import ValidationError + + +def adjust_cell_formula(value, k): + """Cell formula, i.e., if i=5, val=?(A11)+?(B12) -> val=A16+B17""" + if isinstance(value, str): + for i in range(value.count("?(")): + if value and "?(" in value and ")" in value: + i = value.index("?(") + j = value.index(")", i) + val = value[i + 2 : j] + col, row = split_row_col(val) + new_val = f"{col}{row + k}" + value = value.replace(f"?({val})", new_val) + return value + + +def get_field_aggregation(field): + """i..e, 'field@{sum}'""" + if field and "@{" in field and "}" in field: + i = field.index("@{") + j = field.index("}", i) + cond = field[i + 2 : j] + try: + if cond or cond == "": + return (field[:i], cond) + except Exception: + return (field.replace(f"@{{{cond}}}", ""), False) + return (field, False) + + +def get_field_condition(field): + """i..e, 'field${value > 0 and value or False}'""" + if field and "${" in field and "}" in field: + i = field.index("${") + j = field.index("}", i) + cond = field[i + 2 : j] + try: + if cond or cond == "": + return (field.replace(f"${{{cond}}}", ""), cond) + except Exception: + return (field, False) + return (field, False) + + +def get_field_style(field): + """ + Available styles + - font = bold, bold_red + - fill = red, blue, yellow, green, grey + - align = left, center, right + - number = true, false + i.e., 'field#{font=bold;fill=red;align=center;style=number}' + """ + if field and "#{" in field and "}" in field: + i = field.index("#{") + j = field.index("}", i) + cond = field[i + 2 : j] + try: + if cond or cond == "": + return (field.replace(f"#{{{cond}}}", ""), cond) + except Exception: + return (field, False) + return (field, False) + + +def get_field_style_cond(field): + """i..e, 'field#?object.partner_id and #{font=bold} or #{}?'""" + if field and "#?" in field and "?" in field: + i = field.index("#?") + j = field.index("?", i + 2) + cond = field[i + 2 : j] + try: + if cond or cond == "": + return (field.replace(f"#?{cond}?", ""), cond) + except Exception: + return (field, False) + return (field, False) + + +def fill_cell_style(field, field_style, styles): + field_styles = field_style.split(";") if field_style else [] + for f in field_styles: + (key, value) = f.split("=") + if key not in styles.keys(): + raise ValidationError(_("Invalid style type %s", key)) + if value.lower() not in styles[key].keys(): + raise ValidationError( + _( + "Invalid value %(value)s for style type %(key)s", + value=value, + key=key, + ) + ) + cell_style = styles[key][value] + if key == "font": + field.font = cell_style + if key == "fill": + field.fill = cell_style + if key == "align": + field.alignment = cell_style + if key == "style": + if value == "text": + try: + # In case value can't be encoded as utf, we do normal str() + field.value = field.value.encode("utf-8") + except Exception: + field.value = str(field.value) + field.number_format = cell_style + + +def get_line_max(line_field): + """i.e., line_field = line_ids[100], max = 100 else 0""" + if line_field and "[" in line_field and "]" in line_field: + i = line_field.index("[") + j = line_field.index("]") + max_str = line_field[i + 1 : j] + try: + if len(max_str) > 0: + return (line_field[:i], int(max_str)) + return (line_field, False) + except Exception: + return (line_field, False) + return (line_field, False) + + +def get_groupby(line_field): + """i.e., line_field = line_ids["a_id, b_id"], groupby = ["a_id", "b_id"]""" + if line_field and "[" in line_field and "]" in line_field: + i = line_field.index("[") + j = line_field.index("]") + groupby = literal_eval(line_field[i : j + 1]) + return groupby + return False + + +def split_row_col(pos): + match = re.match(r"([a-z]+)([0-9]+)", pos, re.I) + if not match: + raise ValidationError(_("Position %s is not valid", pos)) + col, row = match.groups() + return col, int(row) + + +def openpyxl_get_sheet_by_name(book, name): + """Get sheet by name for openpyxl""" + i = 0 + for sheetname in book.sheetnames: + if sheetname == name: + return book.worksheets[i] + i += 1 + raise ValidationError(_("'%s' sheet not found", name)) + + +def xlrd_get_sheet_by_name(book, name): + try: + for idx in itertools.count(): + sheet = book.sheet_by_index(idx) + if sheet.name == name: + return sheet + except IndexError as exc: + raise ValidationError(_("'%s' sheet not found", name)) from exc + + +def isfloat(input_val): + try: + float(input_val) + return True + except ValueError: + return False + + +def isinteger(input_val): + try: + int(input_val) + return True + except ValueError: + return False + + +def isdatetime(input_val): + try: + if len(input_val) == 10: + dt.strptime(input_val, "%Y-%m-%d") + elif len(input_val) == 19: + dt.strptime(input_val, "%Y-%m-%d %H:%M:%S") + else: + return False + return True + except ValueError: + return False + + +def str_to_number(input_val): + if isinstance(input_val, str): + if " " not in input_val: + if isdatetime(input_val): + return parse(input_val) + if isinteger(input_val): + if not (len(input_val) > 1 and input_val[:1] == "0"): + return int(input_val) + if isfloat(input_val): + if not (input_val.find(".") > 2 and input_val[:1] == "0"): + return float(input_val) + return input_val + + +def csv_from_excel(excel_content, delimiter, quote): + wb = xlrd.open_workbook(file_contents=excel_content) + sh = wb.sheet_by_index(0) + content = StringIO() + quoting = csv.QUOTE_ALL + if not quote: + quoting = csv.QUOTE_NONE + if delimiter == " " and quoting == csv.QUOTE_NONE: + quoting = csv.QUOTE_MINIMAL + wr = csv.writer(content, delimiter=delimiter, quoting=quoting) + for rownum in range(sh.nrows): + row = [] + for x in sh.row_values(rownum): + if quoting == csv.QUOTE_NONE and delimiter in x: + raise ValidationError( + _( + "Template with CSV Quoting = False, data must not " + 'contain the same char as delimiter -> "%s"', + delimiter, + ) + ) + row.append(x) + wr.writerow(row) + content.seek(0) # Set index to 0, and start reading + out_file = content.getvalue().encode("utf-8") + return out_file + + +def pos2idx(pos): + match = re.match(r"([a-z]+)([0-9]+)", pos, re.I) + if not match: + raise ValidationError(_("Position %s is not valid", pos)) + col, row = match.groups() + col_num = 0 + for c in col: + if c in string.ascii_letters: + col_num = col_num * 26 + (ord(c.upper()) - ord("A")) + 1 + return (int(row) - 1, col_num - 1) + + +def _get_cell_value(cell, field_type=False): + """If Odoo's field type is known, convert to valid string for import, + if not know, just get value as is""" + value = False + datemode = 0 # From book.datemode, but we fix it for simplicity + if field_type in ["date", "datetime"]: + ctype = xlrd.sheet.ctype_text.get(cell.ctype, "unknown type") + if ctype in ("xldate", "number"): + is_datetime = cell.value % 1 != 0.0 + time_tuple = xlrd.xldate_as_tuple(cell.value, datemode) + date = dt(*time_tuple) + value = ( + date.strftime("%Y-%m-%d %H:%M:%S") + if is_datetime + else date.strftime("%Y-%m-%d") + ) + else: + value = cell.value + elif field_type in ["integer", "float"]: + value_str = str(cell.value).strip().replace(",", "") + if len(value_str) == 0: + value = "" + elif value_str.replace(".", "", 1).isdigit(): # Is number + if field_type == "integer": + value = int(float(value_str)) + elif field_type == "float": + value = float(value_str) + else: # Is string, no conversion + value = value_str + elif field_type in ["many2one"]: + # If number, change to string + if isinstance(cell.value, int | float | complex): + value = str(cell.value) + else: + value = cell.value + else: # text, char + value = cell.value + # If string, cleanup + if isinstance(value, str): + if value[-2:] == ".0": + value = value[:-2] + # Except boolean, when no value, we should return as '' + if field_type not in ["boolean"]: + if not value: + value = "" + return value + + +def _add_column(column_name, column_value, file_txt): + i = 0 + txt_lines = [] + for line in file_txt.split("\n"): + if line and i == 0: + line = '"' + str(column_name) + '",' + line + elif line: + line = '"' + str(column_value) + '",' + line + txt_lines.append(line) + i += 1 + file_txt = "\n".join(txt_lines) + return file_txt + + +def _add_id_column(file_txt): + i = 0 + txt_lines = [] + for line in file_txt.split("\n"): + if line and i == 0: + line = '"id",' + line + elif line: + line = f"__excel_import_export__.{uuid.uuid4()},{line}" + txt_lines.append(line) + i += 1 + file_txt = "\n".join(txt_lines) + return file_txt diff --git a/excel_import_export/models/ir_report.py b/excel_import_export/models/ir_report.py new file mode 100644 index 00000000000..5d0d95ed7ba --- /dev/null +++ b/excel_import_export/models/ir_report.py @@ -0,0 +1,46 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo import api, fields, models +from odoo.exceptions import UserError +from odoo.fields import Domain + + +class ReportAction(models.Model): + _inherit = "ir.actions.report" + + report_type = fields.Selection( + selection_add=[("excel", "Excel")], ondelete={"excel": "cascade"} + ) + + @api.model + def _render_excel(self, docids, data): + if len(docids) != 1: + raise UserError( + self.env._("Only one id is allowed for excel_import_export") + ) + domain = Domain("fname", "in", [self.report_name]) & Domain( + "res_model", "in", [self.model] + ) + xlsx_template = self.env["xlsx.template"].search(domain) + if not xlsx_template or len(xlsx_template) != 1: + raise UserError( + self.env._( + "Template %(report_name)s on model %(model)s is not unique!", + report_name=self.report_name, + model=self.model, + ) + ) + return self.env["xlsx.export"].export_xlsx(xlsx_template, self.model, docids[0]) + + @api.model + def _get_report_from_name(self, report_name): + res = super()._get_report_from_name(report_name) + if res: + return res + report_obj = self.env["ir.actions.report"] + domain = Domain("report_type", "in", ["excel"]) & Domain( + "report_name", "in", [report_name] + ) + context = self.env["res.users"].context_get() + return report_obj.with_context(**context).search(domain, limit=1) diff --git a/excel_import_export/models/styles.py b/excel_import_export/models/styles.py new file mode 100644 index 00000000000..03cb9cac9b3 --- /dev/null +++ b/excel_import_export/models/styles.py @@ -0,0 +1,47 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +import logging + +from odoo import api, models + +_logger = logging.getLogger(__name__) + +try: + from openpyxl.styles import Alignment, Font, PatternFill +except ImportError: + _logger.debug('Cannot import "openpyxl". Please make sure it is installed.') + + +class XLSXStyles(models.AbstractModel): + _name = "xlsx.styles" + _description = "Available styles for excel" + + @api.model + def get_openpyxl_styles(self): + """List all syles that can be used with styleing directive #{...}""" + return { + "font": { + "bold": Font(name="Arial", size=10, bold=True), + "bold_red": Font(name="Arial", size=10, color="FF0000", bold=True), + }, + "fill": { + "red": PatternFill("solid", fgColor="FF0000"), + "grey": PatternFill("solid", fgColor="DDDDDD"), + "yellow": PatternFill("solid", fgColor="FFFCB7"), + "blue": PatternFill("solid", fgColor="9BF3FF"), + "green": PatternFill("solid", fgColor="B0FF99"), + }, + "align": { + "left": Alignment(horizontal="left"), + "center": Alignment(horizontal="center"), + "right": Alignment(horizontal="right"), + }, + "style": { + "number": "#,##0.00", + "date": "dd/mm/yyyy", + "datestamp": "yyyy-mm-dd", + "text": "@", + "percent": "0.00%", + }, + } diff --git a/excel_import_export/models/xlsx_export.py b/excel_import_export/models/xlsx_export.py new file mode 100644 index 00000000000..8e05888df0a --- /dev/null +++ b/excel_import_export/models/xlsx_export.py @@ -0,0 +1,316 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +import base64 +import logging +import os +import zipfile +from datetime import date +from datetime import datetime as dt +from io import BytesIO + +from odoo import api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools.float_utils import float_compare +from odoo.tools.safe_eval import safe_eval + +from . import common as co + +_logger = logging.getLogger(__name__) +try: + from openpyxl import load_workbook + from openpyxl.utils.exceptions import IllegalCharacterError +except ImportError: + _logger.debug('Cannot import "openpyxl". Please make sure it is installed.') + + +class XLSXExport(models.AbstractModel): + _name = "xlsx.export" + _description = "Excel Export AbstractModel" + + @api.model + def get_eval_context(self, model, record, value): + eval_context = { + "float_compare": float_compare, + "datetime": dt, + "date": date, + "value": value, + "object": record, + "model": self.env[model], + "env": self.env, + "context": self.env.context, + } + return eval_context + + def _get_conditions_dict(self): + return { + "field_cond_dict": {}, + "field_style_dict": {}, + "style_cond_dict": {}, + "aggre_func_dict": {}, + } + + def run_field_cond_dict(self, field): + temp_field, eval_cond = co.get_field_condition(field) + eval_cond = eval_cond or 'value or ""' + return temp_field, eval_cond + + def run_field_style_dict(self, field): + return co.get_field_style(field) + + def run_style_cond_dict(self, field): + return co.get_field_style_cond(field) + + def run_aggre_func_dict(self, field): + return co.get_field_aggregation(field) + + def apply_extra_conditions_to_value(self, field, value, conditions_dict): + return value + + @api.model + def _get_line_vals(self, record, line_field, fields): + """Get values of this field from record set and return as dict of vals + - record: main object + - line_field: rows object, i.e., line_ids + - fields: fields in line_ids, i.e., partner_id.display_name + """ + line_field, max_row = co.get_line_max(line_field) + line_field = line_field.replace("_CONT_", "") # Remove _CONT_ if any + line_field = line_field.replace("_EXTEND_", "") # Remove _EXTEND_ if any + lines = record[line_field] + if max_row > 0 and len(lines) > max_row: + raise Exception( + self.env._("Records in %s exceed max records allowed", line_field) + ) + vals = {field: [] for field in fields} # value and do_style + # Get field condition & aggre function + conditions_dict = self._get_conditions_dict() + + pair_fields = [] # I.e., ('debit${value and . or .}@{sum}', 'debit') + for field in fields: + raw_field = field + for key, condition_dict in conditions_dict.items(): + run_func_name = "run_" + key + raw_field, get_result = getattr(self, run_func_name, None)(raw_field) + condition_dict.update({field: get_result}) + pair_fields.append((field, raw_field)) + for line in lines: + for field in pair_fields: # (field, raw_field) + value = self._get_field_data(field[1], line) + eval_cond = conditions_dict["field_cond_dict"][field[0]] + eval_context = self.get_eval_context(line._name, line, value) + if eval_cond: + value = safe_eval(eval_cond, eval_context) + value = self.apply_extra_conditions_to_value( + field, value, conditions_dict + ) + # style w/Cond takes priority + style_cond = conditions_dict["style_cond_dict"][field[0]] + style = self._eval_style_cond(line._name, line, value, style_cond) + if style is None: + style = False # No style + elif style is False: + style = conditions_dict["field_style_dict"][ + field[0] + ] # Use default style + vals[field[0]].append((value, style)) + return (vals, conditions_dict["aggre_func_dict"]) + + @api.model + def _eval_style_cond(self, model, record, value, style_cond): + eval_context = self.get_eval_context(model, record, value) + field = style_cond = style_cond or "#??" + styles = {} + for i in range(style_cond.count("#{")): + i += 1 + field, style = co.get_field_style(field) + styles.update({i: style}) + style_cond = style_cond.replace(f"#{{{style}}}", str(i)) + if not styles: + return False + res = safe_eval(style_cond, eval_context) + if res is None or res is False: + return res + return styles[res] + + @api.model + def _fill_workbook_data(self, workbook, record, data_dict): + """Fill data from record with style in data_dict to workbook""" + if not record or not data_dict: + return + try: + for sheet_name in data_dict: + ws = data_dict[sheet_name] + st = False + if isinstance(sheet_name, str): + st = co.openpyxl_get_sheet_by_name(workbook, sheet_name) + elif isinstance(sheet_name, int): + if sheet_name > len(workbook.worksheets): + raise Exception(self.env._("Not enough worksheets")) + st = workbook.worksheets[sheet_name - 1] + if not st: + raise ValidationError(self.env._("Sheet %s not found", sheet_name)) + # Fill data, header and rows + self._fill_head(ws, st, record) + self._fill_lines(ws, st, record) + except KeyError as e: + raise ValidationError(self.env._("Key Error\n%s", e)) from e + except IllegalCharacterError as e: + raise ValidationError( + self.env._( + "IllegalCharacterError\n" + "Some exporting data contain special character\n%s", + e, + ) + ) from e + except Exception as e: + raise ValidationError( + self.env._("Error filling data into Excel sheets\n%s", e) + ) from e + + @api.model + def _get_field_data(self, _field, _line): + """Get field data, and convert data type if needed""" + if not _field: + return None + line_copy = _line + for f in _field.split("."): + line_copy = line_copy[f] + if isinstance(line_copy, str): + line_copy = line_copy.encode("utf-8") + return line_copy + + @api.model + def _fill_head(self, ws, st, record): + for rc, field in ws.get("_HEAD_", {}).items(): + tmp_field, eval_cond = co.get_field_condition(field) + eval_cond = eval_cond or 'value or ""' + tmp_field, field_style = co.get_field_style(tmp_field) + tmp_field, style_cond = co.get_field_style_cond(tmp_field) + value = tmp_field and self._get_field_data(tmp_field, record) + # Eval + eval_context = self.get_eval_context(record._name, record, value) + if eval_cond: + value = safe_eval(eval_cond, eval_context) + if value is not None: + st[rc] = value + fc = not style_cond and True or safe_eval(style_cond, eval_context) + if field_style and fc: # has style and pass style_cond + styles = self.env["xlsx.styles"].get_openpyxl_styles() + co.fill_cell_style(st[rc], field_style, styles) + + @api.model + def _fill_lines(self, ws, st, record): + line_fields = list(ws) + if "_HEAD_" in line_fields: + line_fields.remove("_HEAD_") + cont_row = 0 # last data row to continue + for line_field in line_fields: + fields = ws.get(line_field, {}).values() + vals, func = self._get_line_vals(record, line_field, fields) + is_cont = "_CONT_" in line_field and True or False # continue row + is_extend = "_EXTEND_" in line_field and True or False # extend row + cont_set = 0 + rows_inserted = False # flag to insert row + for rc, field in ws.get(line_field, {}).items(): + col, row = co.split_row_col(rc) # starting point + # Case continue, start from the last data row + if is_cont and not cont_set: # only once per line_field + cont_set = cont_row + 1 + if is_cont: + row = cont_set + rc = f"{col}{cont_set}" + i = 0 + new_row = 0 + new_rc = False + row_count = len(vals[field]) + # Insert rows to preserve total line + if is_extend and not rows_inserted: + rows_inserted = True + st.insert_rows(row + 1, row_count - 1) + # -- + for row_val, style in vals[field]: + new_row = row + i + new_rc = f"{col}{new_row}" + row_val = co.adjust_cell_formula(row_val, i) + if row_val not in ("None", None): + st[new_rc] = co.str_to_number(row_val) + if style: + styles = self.env["xlsx.styles"].get_openpyxl_styles() + co.fill_cell_style(st[new_rc], style, styles) + i += 1 + # Add footer line if at least one field have sum + f = func.get(field, False) + if f and new_row > 0: + new_row += 1 + f_rc = f"{col}{new_row}" + st[f_rc] = f"={f}({rc}:{new_rc})" + styles = self.env["xlsx.styles"].get_openpyxl_styles() + co.fill_cell_style(st[f_rc], style, styles) + cont_row = cont_row < new_row and new_row or cont_row + return + + @api.model + def export_xlsx(self, template, res_model, res_ids): + if template.res_model != res_model: + raise ValidationError(self.env._("Template's model mismatch")) + data_dict = co.literal_eval(template.instruction.strip()) + export_dict = data_dict.get("__EXPORT__", False) + out_name = template.name + if not export_dict: # If there is not __EXPORT__ formula, just export + out_name = template.fname + out_file = template.datas + return (out_file, out_name) + # Prepare temp file (from now, only xlsx file works for openpyxl) + decoded_data = base64.decodebytes(template.datas) + ConfParam = self.env["ir.config_parameter"].sudo() + ptemp = ConfParam.get_param("path_temp_file") or "/tmp" + stamp = dt.utcnow().strftime("%H%M%S%f")[:-3] + ftemp = f"{ptemp}/temp{stamp}.xlsx" + # Start working with workbook + records = res_model and self.env[res_model].browse(res_ids) or False + outputs = [] + for record in records: + f = open(ftemp, "wb") + f.write(decoded_data) + f.seek(0) + f.close() + # Workbook created, temp file removed + wb = load_workbook(ftemp) + os.remove(ftemp) + self._fill_workbook_data(wb, record, export_dict) + # Return file as .xlsx + content = BytesIO() + wb.save(content) + content.seek(0) # Set index to 0, and start reading + out_file = content.read() + if record and "name" in record and record.name: + out_name = record.name.replace(" ", "").replace("/", "") + else: + fname = out_name.replace(" ", "").replace("/", "") + ts = fields.Datetime.context_timestamp(self, dt.now()) + out_name = "{}_{}".format(fname, ts.strftime("%Y%m%d_%H%M%S")) + if not out_name or len(out_name) == 0: + out_name = "noname" + out_ext = "xlsx" + # CSV (convert only on 1st sheet) + if template.to_csv: + delimiter = template.csv_delimiter + out_file = co.csv_from_excel(out_file, delimiter, template.csv_quote) + out_ext = template.csv_extension + outputs.append((out_file, f"{out_name}.{out_ext}")) + # If outputs > 1 files, zip it + if len(outputs) > 1: + zip_buffer = BytesIO() + with zipfile.ZipFile( + zip_buffer, "a", zipfile.ZIP_DEFLATED, False + ) as zip_file: + for data, file_name in outputs: + zip_file.writestr(file_name, data) + zip_buffer.seek(0) + out_file = base64.encodebytes(zip_buffer.read()) + out_name = "files.zip" + return (out_file, out_name) + else: + (out_file, out_name) = outputs[0] + return (base64.encodebytes(out_file), out_name) diff --git a/excel_import_export/models/xlsx_import.py b/excel_import_export/models/xlsx_import.py new file mode 100644 index 00000000000..88fa6c1138f --- /dev/null +++ b/excel_import_export/models/xlsx_import.py @@ -0,0 +1,378 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +import base64 +import uuid +from ast import literal_eval +from datetime import date +from datetime import datetime as dt +from io import BytesIO + +import xlrd +import xlwt + +from odoo import api, models +from odoo.exceptions import UserError, ValidationError +from odoo.tools.float_utils import float_compare +from odoo.tools.parse_version import parse_version +from odoo.tools.safe_eval import safe_eval + +from . import common as co + + +class XLSXImport(models.AbstractModel): + _name = "xlsx.import" + _description = "Excel Import AbstractModel" + + @api.model + def get_eval_context(self, model=False, value=False): + eval_context = { + "float_compare": float_compare, + "datetime": dt, + "date": date, + "env": self.env, + "context": self.env.context, + "value": False, + "model": False, + } + if model: + eval_context.update({"model": self.env[model]}) + if value: + if isinstance(value, str): # Remove non Ord 128 character + value = "".join([i if ord(i) < 128 else " " for i in value]) + eval_context.update({"value": value}) + return eval_context + + @api.model + def get_external_id(self, record): + """Get external ID of the record, if not already exists create one""" + ModelData = self.sudo().env["ir.model.data"] + xml_id = record.get_external_id() + if not xml_id or (record.id in xml_id and xml_id[record.id] == ""): + ModelData.create( + { + "name": f"{record._table}_{record.id}", + "module": "__excel_import_export__", + "model": record._name, + "res_id": record.id, + } + ) + xml_id = record.get_external_id() + return xml_id[record.id] + + @api.model + def _get_field_type(self, model, field): + try: + record = self.env[model].new() + for f in field.split("/"): + field_type = record._fields[f].type + if field_type in ("one2many", "many2many"): + record = record[f] + else: + return field_type + except Exception as exc: + raise ValidationError( + self.env._("Invalid declaration, %s has no valid field type", field) + ) from exc + + @api.model + def _delete_record_data(self, record, data_dict): + """If no _NODEL_, delete existing lines before importing""" + if not record or not data_dict: + return + try: + for sheet_name in data_dict: + worksheet = data_dict[sheet_name] + line_fields = filter(lambda x: x != "_HEAD_", worksheet) + for line_field in line_fields: + if "_NODEL_" not in line_field: + if line_field in record and record[line_field]: + record[line_field].unlink() + # Remove _NODEL_ from dict + for s, _sv in data_dict.copy().items(): + for f, _fv in data_dict[s].copy().items(): + if "_NODEL_" in f: + new_fv = data_dict[s].pop(f) + data_dict[s][f.replace("_NODEL_", "")] = new_fv + except Exception as e: + raise ValidationError(self.env._("Error deleting data\n%s", e)) from e + + @api.model + def _get_end_row(self, st, worksheet, line_field, is_xlsx=False): + """Get max row or next empty row as the ending row""" + _x, max_row = co.get_line_max(line_field) + test_rows = {} + max_end_row = 0 + if is_xlsx: + # For openpyxl + sheet_nrows = st.max_row + else: + # For xlrd + sheet_nrows = st.nrows + for rc, _col in worksheet.get(line_field, {}).items(): + rc, key_eval_cond = co.get_field_condition(rc) + row, col = co.pos2idx(rc) + # Use max_row, i.e., order_line[5], use it. Otherwise, use st.nrows + max_end_row = sheet_nrows if max_row is False else (row + max_row) + for idx in range(row, max_row and max_end_row or sheet_nrows): + try: + if is_xlsx: + # openpyxl uses 1-based indexing + cell = st.cell(row=idx + 1, column=col + 1) + # Check if cell is empty (None or empty string) + cell_type = 0 if cell.value in (None, "") else 1 + else: + cell_type = st.cell_type(idx, col) # empty type = 0 + except Exception as e: + raise UserError( + self.env._( + "The value for the '%(field)s' field is expected to be " + "in cell %(cell_position)s, but no column exists for that " + "cell in the Excel sheet. Please check your Excel file.", + field=_col, + cell_position=rc, + ) + ) from e + r_types = test_rows.get(idx, []) + r_types.append(cell_type) + test_rows[idx] = r_types + empty_list = filter(lambda y: all(i == 0 for i in y[1]), test_rows.items()) + empty_rows = list(map(lambda z: z[0], empty_list)) + next_empty_row = empty_rows and min(empty_rows) or max_end_row + return next_empty_row + + @api.model + def _get_line_vals(self, st, worksheet, model, line_field, is_xlsx=False): + """Get values of this field from excel sheet""" + vals = {} + end_row = self._get_end_row(st, worksheet, line_field, is_xlsx) + for rc, columns in worksheet.get(line_field, {}).items(): + if not isinstance(columns, list): + columns = [columns] + for field in columns: + rc, key_eval_cond = co.get_field_condition(rc) + x_field, val_eval_cond = co.get_field_condition(field) + row, col = co.pos2idx(rc) + new_line_field, _x = co.get_line_max(line_field) + out_field = f"{new_line_field}/{x_field}" + field_type = self._get_field_type(model, out_field) + vals.update({out_field: []}) + for idx in range(row, end_row): + if is_xlsx: # Handle openpyxl cells + cell_value = st.cell(row=idx + 1, column=col + 1) + else: # Handle xlrd cells + cell_value = st.cell(idx, col) + value = co._get_cell_value(cell_value, field_type=field_type) + eval_context = self.get_eval_context(model=model, value=value) + if key_eval_cond: + value = safe_eval(key_eval_cond, eval_context) + if val_eval_cond: + value = safe_eval(val_eval_cond, eval_context) + vals[out_field].append(value) + if not filter(lambda x: x != "", vals[out_field]): + vals.pop(out_field) + return vals + + @api.model + def _process_worksheet( + self, wb, out_st, model, data_dict, header_fields, is_xlsx=False + ): # noqa: C901 + col_idx = 1 + for sheet_name in data_dict: # For each Sheet + worksheet = data_dict[sheet_name] + st = None + if isinstance(sheet_name, str): + # Get sheet by name for openpyxl + st = ( + wb[sheet_name] + if is_xlsx + else co.xlrd_get_sheet_by_name(wb, sheet_name) + ) + elif isinstance(sheet_name, int): + # Get sheet by index for openpyxl + st = ( + wb.worksheets[sheet_name - 1] + if is_xlsx + else wb.sheet_by_index(sheet_name - 1) + ) + if not st: + raise ValidationError(self.env._("Sheet %s not found", sheet_name)) + # HEAD updates + for rc, field in worksheet.get("_HEAD_", {}).items(): + rc, key_eval_cond = co.get_field_condition(rc) + field, val_eval_cond = co.get_field_condition(field) + field_type = self._get_field_type(model, field) + try: + row, col = co.pos2idx(rc) + if is_xlsx: # openpyxl + # openpyxl uses 1-based indexing + cell_value = st.cell(row=row + 1, column=col + 1).value + else: # xlrd + cell_value = st.cell(row, col) + value = co._get_cell_value(cell_value, field_type=field_type) + except Exception: + value = False + eval_context = self.get_eval_context(model=model, value=value) + if key_eval_cond: + value = str(safe_eval(key_eval_cond, eval_context)) + if val_eval_cond: + value = str(safe_eval(val_eval_cond, eval_context)) + out_st.write(0, col_idx, field) # Next Column + out_st.write(1, col_idx, value) # Next Value + header_fields.append(field) + col_idx += 1 + # Line Items + line_fields = filter(lambda x: x != "_HEAD_", worksheet) + for line_field in line_fields: + vals = self._get_line_vals(st, worksheet, model, line_field, is_xlsx) + for field, values in vals.items(): + # Columns, i.e., line_ids/field_id + out_st.write(0, col_idx, field) + header_fields.append(field) + # Data + i = 1 + for value in values: + out_st.write(i, col_idx, value) + i += 1 + col_idx += 1 + + @api.model + def _import_record_data(self, import_file, record, data_dict): + if not data_dict: + return + try: + model = record._name + xml_id = self._generate_xml_id(record) + decoded_data = base64.decodebytes(import_file) + out_wb = xlwt.Workbook() + out_st = out_wb.add_sheet("Sheet 1") + out_st.write(0, 0, "id") + out_st.write(1, 0, xml_id) + header_fields = ["id"] + is_xlsx = self._is_xlsx_file() + wb = self._load_workbook(decoded_data, is_xlsx) + # Process on all worksheets + self._process_worksheet( + wb, out_st, model, data_dict, header_fields, is_xlsx + ) + content = BytesIO() + out_wb.save(content) + content.seek(0) # Set index to 0, and start reading + xls_file = content.read() + # Do the import + imp = self._create_import_record(model, xls_file) + errors = self._execute_import(imp, header_fields) + if errors.get("messages"): + self._handle_import_errors(errors) + return self.env.ref(xml_id) + except xlrd.XLRDError as exc: + raise ValidationError( + self.env._("Invalid file style, only .xls or .xlsx file allowed") + ) from exc + except Exception as e: + raise e + + def _generate_xml_id(self, record): + return ( + record + and self.get_external_id(record) + or "{}.{}".format("__excel_import_export__", uuid.uuid4()) + ) + + def _is_xlsx_file(self): + if xlrd and parse_version(xlrd.__VERSION__) < parse_version("2.0"): + return False + return True + + def _load_workbook(self, decoded_data, is_xlsx): + if not is_xlsx: + return xlrd.open_workbook(file_contents=decoded_data) + try: + import io + + from openpyxl import load_workbook + + return load_workbook(io.BytesIO(decoded_data or b""), data_only=True) + except Exception as exc: + raise ValidationError( + self.env._("Invalid file style, only .xls or .xlsx file allowed") + ) from exc + + def _create_import_record(self, model, xls_file): + Import = self.env["base_import.import"] + return Import.create( + { + "res_model": model, + "file": xls_file, + "file_type": "application/vnd.ms-excel", + "file_name": "temp.xls", + } + ) + + def _execute_import(self, imp, header_fields): + return imp.execute_import( + header_fields, + header_fields, + { + "has_headers": True, + "advanced": True, + "keep_matches": False, + "encoding": "", + "separator": "", + "quoting": '"', + "date_format": "%Y-%m-%d", + "datetime_format": "%Y-%m-%d %H:%M:%S", + "float_thousand_separator": ",", + "float_decimal_separator": ".", + "fields": [], + }, + ) + + def _handle_import_errors(self, errors): + message = self.env._("Error importing data") + messages = errors["messages"] + if isinstance(messages, dict): + message = messages["message"] + if isinstance(messages, list): + message = ", ".join([x["message"] for x in messages]) + raise ValidationError(message.encode("utf-8")) + + @api.model + def _post_import_operation(self, record, operation): + """Run python code after import""" + if not record or not operation: + return + try: + if "${" in operation: + code = (operation.split("${"))[1].split("}")[0] + eval_context = {"object": record} + safe_eval(code, eval_context) + except Exception as e: + raise ValidationError( + self.env._("Post import operation error\n%s", e) + ) from e + + @api.model + def import_xlsx(self, import_file, template, res_model=False, res_id=False): + """ + - If res_id = False, we want to create new document first + - Delete fields' data according to data_dict['__IMPORT__'] + - Import data from excel according to data_dict['__IMPORT__'] + """ + if res_model and template.res_model != res_model: + raise ValidationError(self.env._("Template's model mismatch")) + record = self.env[template.res_model].browse(res_id) + data_dict = literal_eval(template.instruction.strip()) + if not data_dict.get("__IMPORT__"): + raise ValidationError( + self.env._("No data_dict['__IMPORT__'] in template %s", template.name) + ) + if record: + # Delete existing data first + self._delete_record_data(record, data_dict["__IMPORT__"]) + # Fill up record with data from excel sheets + record = self._import_record_data(import_file, record, data_dict["__IMPORT__"]) + # Post Import Operation, i.e., cleanup some data + if data_dict.get("__POST_IMPORT__", False): + self._post_import_operation(record, data_dict["__POST_IMPORT__"]) + return record diff --git a/excel_import_export/models/xlsx_report.py b/excel_import_export/models/xlsx_report.py new file mode 100644 index 00000000000..cf013e62eb5 --- /dev/null +++ b/excel_import_export/models/xlsx_report.py @@ -0,0 +1,57 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo import api, fields, models +from odoo.exceptions import ValidationError + + +class XLSXReport(models.AbstractModel): + """Common class for xlsx reporting wizard""" + + _name = "xlsx.report" + _description = "Excel Report AbstractModel" + + name = fields.Char(string="File Name", readonly=True, size=500) + data = fields.Binary(string="File", readonly=True) + template_id = fields.Many2one( + "xlsx.template", + string="Template", + required=True, + ondelete="cascade", + domain=lambda self: self.env.context.get("template_domain", []), + ) + choose_template = fields.Boolean(string="Allow Choose Template", default=False) + state = fields.Selection( + [("choose", "Choose"), ("get", "Get")], + default="choose", + help="* Choose: wizard show in user selection mode" + "\n* Get: wizard show results from user action", + ) + + @api.model + def default_get(self, fields): + template_domain = self.env.context.get("template_domain", []) + templates = self.env["xlsx.template"].search(template_domain) + if not templates: + raise ValidationError(self.env._("No template found")) + defaults = super().default_get(fields) + for template in templates: + if not template.datas: + raise ValidationError(self.env._("No file in %s", template.name)) + defaults["template_id"] = len(templates) == 1 and templates.id or False + return defaults + + def report_xlsx(self): + self.ensure_one() + Export = self.env["xlsx.export"] + out_file, out_name = Export.export_xlsx(self.template_id, self._name, self.id) + self.write({"state": "get", "data": out_file, "name": out_name}) + return { + "name": self.env._("Excel Report"), + "type": "ir.actions.act_window", + "res_model": self._name, + "view_mode": "form", + "res_id": self.id, + "views": [(False, "form")], + "target": "new", + } diff --git a/excel_import_export/models/xlsx_template.py b/excel_import_export/models/xlsx_template.py new file mode 100644 index 00000000000..a420a0b5421 --- /dev/null +++ b/excel_import_export/models/xlsx_template.py @@ -0,0 +1,661 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +import base64 +import os +from ast import literal_eval +from os.path import join as opj + +from odoo import Command, api, fields, models +from odoo.exceptions import UserError, ValidationError +from odoo.fields import Domain +from odoo.modules.module import get_module_path + +from . import common as co + + +class XLSXTemplate(models.Model): + """Master Data for XLSX Templates + - Excel Template + - Import/Export Meta Data (dict text) + - Default values, etc. + """ + + _name = "xlsx.template" + _description = "Excel template file and instruction" + _order = "name" + + name = fields.Char(string="Template Name", required=True) + res_model = fields.Char( + string="Resource Model", + help="The database object this attachment will be attached to.", + ) + fname = fields.Char(string="File Name") + gname = fields.Char( + string="Group Name", + help="Multiple template of same model, can belong to same group,\n" + "result in multiple template selection", + ) + description = fields.Char() + input_instruction = fields.Text( + string="Instruction (Input)", + help="This is used to construct instruction in tab Import/Export", + ) + instruction = fields.Text( + compute="_compute_output_instruction", + help="Instruction on how to import/export, prepared by system.", + ) + datas = fields.Binary(string="File Content") + to_csv = fields.Boolean( + string="Convert to CSV?", + default=False, + help="Convert file into CSV format on export", + ) + csv_delimiter = fields.Char( + string="CSV Delimiter", + size=1, + default=",", + required=True, + help="Optional for CSV, default is comma.", + ) + csv_extension = fields.Char( + string="CSV File Extension", + size=5, + default="csv", + required=True, + help="Optional for CSV, default is .csv", + ) + csv_quote = fields.Boolean( + string="CSV Quoting", + default=True, + help="Optional for CSV, default is full quoting.", + ) + export_ids = fields.One2many( + comodel_name="xlsx.template.export", inverse_name="template_id" + ) + import_ids = fields.One2many( + comodel_name="xlsx.template.import", inverse_name="template_id" + ) + post_import_hook = fields.Char( + string="Post Import Function Hook", + help="Call a function after successful import, i.e.,\n" + "${object.post_import_do_something()}", + ) + show_instruction = fields.Boolean( + string="Show Output", + default=False, + help="This is the computed instruction based on tab Import/Export,\n" + "to be used by xlsx import/export engine", + ) + redirect_action = fields.Many2one( + comodel_name="ir.actions.act_window", + string="Return Action", + domain=[("type", "=", "ir.actions.act_window")], + help="Optional action, redirection after finish import operation", + ) + # Utilities + export_action_id = fields.Many2one( + comodel_name="ir.actions.act_window", + ondelete="set null", + ) + import_action_id = fields.Many2one( + comodel_name="ir.actions.act_window", + ondelete="set null", + ) + use_report_wizard = fields.Boolean( + string="Easy Reporting", + help="Use common report wizard model, instead of create specific model", + ) + result_model_id = fields.Many2one( + comodel_name="ir.model", + string="Report Model", + help="When use commone wizard, choose the result model", + ) + result_field = fields.Char( + compute="_compute_result_field", + ) + report_menu_id = fields.Many2one( + comodel_name="ir.ui.menu", + string="Report Menu", + readonly=True, + ) + report_action_id = fields.Many2one( + comodel_name="ir.actions.report", + string="Report Action", + ) + + def _compute_result_field(self): + for rec in self: + rec.result_field = (f"x_{rec.id}_results") if rec.result_model_id else False + + @api.constrains("redirect_action", "res_model") + def _check_action_model(self): + for rec in self: + if ( + rec.res_model + and rec.redirect_action + and rec.res_model != rec.redirect_action.res_model + ): + raise ValidationError( + self.env._( + "The selected redirect action is not for model %s", + rec.res_model, + ) + ) + + @api.model + def load_xlsx_template(self, template_ids, addon=False): + for template in self.browse(template_ids): + if not addon: + addon = list(template.get_external_id().values())[0].split(".")[0] + addon_path = get_module_path(addon) + file_path = False + for root, _dirs, files in os.walk(addon_path): + for name in files: + if name == template.fname: + file_path = os.path.abspath(opj(root, name)) + if file_path: + template.datas = base64.b64encode(open(file_path, "rb").read()) + return True + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + for rec in res: + if rec.input_instruction: + rec._compute_input_export_instruction() + rec._compute_input_import_instruction() + rec._compute_input_post_import_hook() + if rec.result_model_id: + rec._update_result_field_common_wizard() + rec._update_result_export_ids() + return res + + def write(self, vals): + res = super().write(vals) + if vals.get("input_instruction"): + for rec in self: + rec._compute_input_export_instruction() + rec._compute_input_import_instruction() + rec._compute_input_post_import_hook() + if vals.get("result_model_id"): + for rec in self: + rec._update_result_field_common_wizard() + rec._update_result_export_ids() + return res + + def unlink(self): + domain = Domain("model", "in", ["report.xlsx.wizard"]) & Domain( + "name", "in", self.mapped("result_field") + ) + self.env["ir.model.fields"].search(domain).unlink() + return super().unlink() + + def _update_result_field_common_wizard(self): + self.ensure_one() + _model = self.env["ir.model"].search( + Domain("model", "in", ["report.xlsx.wizard"]) + ) + _model.ensure_one() + result_model = self.result_model_id.model + domain = Domain("model", "=", "report.xlsx.wizard") & Domain( + "name", "=", self.result_field + ) + _field = self.env["ir.model.fields"].search(domain) + if not _field: + _field = self.env["ir.model.fields"].create( + { + "model_id": _model.id, + "name": self.result_field, + "field_description": "Results", + "ttype": "many2many", + "relation": result_model, + "store": False, + "depends": "res_model", + } + ) + else: + _field.ensure_one() + _field.write({"relation": result_model}) + _field.compute = f""" +self[ +'{self.result_field}' +] = self.env['{result_model}'].search(self.safe_domain(self.domain)) + """ + + def _update_result_export_ids(self): + self.ensure_one() + domain = Domain("template_id", "in", [self.id]) & Domain( + "row_field", "in", [self.result_field] + ) + results = self.env["xlsx.template.export"].search(domain) + if not results: + self.export_ids.unlink() + self.write( + { + "export_ids": [ + Command.create( + {"sequence": 10, "section_type": "sheet", "sheet": 1} + ), + Command.create( + { + "sequence": 20, + "section_type": "row", + "row_field": self.result_field, + } + ), + Command.create( + { + "sequence": 30, + "section_type": "data", + "excel_cell": "A1", + "field_name": "id", + } + ), + ], + } + ) + + @api.onchange("use_report_wizard") + def _onchange_use_report_wizard(self): + self.res_model = "report.xlsx.wizard" if self.use_report_wizard else False + self.redirect_action = False + + def _compute_input_export_instruction(self): + self = self.with_context(compute_from_input=True) + for rec in self: + # Export Instruction + input_dict = literal_eval(rec.input_instruction.strip()) + rec.export_ids.unlink() + export_dict = input_dict.get("__EXPORT__") + if not export_dict: + continue + export_lines = [] + sequence = 0 + # Sheet + for sheet, rows in export_dict.items(): + sequence += 1 + vals = { + "sequence": sequence, + "section_type": "sheet", + "sheet": str(sheet), + } + export_lines.append((0, 0, vals)) + # Rows + for row_field, lines in rows.items(): + sequence += 1 + is_cont = False + if "_CONT_" in row_field: + is_cont = True + row_field = row_field.replace("_CONT_", "") + is_extend = False + if "_EXTEND_" in row_field: + is_extend = True + row_field = row_field.replace("_EXTEND_", "") + vals = { + "sequence": sequence, + "section_type": (row_field == "_HEAD_" and "head" or "row"), + "row_field": row_field, + "is_cont": is_cont, + "is_extend": is_extend, + } + export_lines.append((0, 0, vals)) + for excel_cell, field_name in lines.items(): + sequence += 1 + vals = { + "sequence": sequence, + "section_type": "data", + "excel_cell": excel_cell, + "field_name": field_name, + } + export_lines.append((0, 0, vals)) + rec.write({"export_ids": export_lines}) + + def _compute_input_import_instruction(self): + self = self.with_context(compute_from_input=True) + for rec in self: + # Import Instruction + input_dict = literal_eval(rec.input_instruction.strip()) + rec.import_ids.unlink() + import_dict = input_dict.get("__IMPORT__") + if not import_dict: + continue + import_lines = [] + sequence = 0 + # Sheet + for sheet, rows in import_dict.items(): + sequence += 1 + vals = { + "sequence": sequence, + "section_type": "sheet", + "sheet": str(sheet), + } + import_lines.append((0, 0, vals)) + # Rows + for row_field, lines in rows.items(): + sequence += 1 + no_delete = False + if "_NODEL_" in row_field: + no_delete = True + row_field = row_field.replace("_NODEL_", "") + vals = { + "sequence": sequence, + "section_type": (row_field == "_HEAD_" and "head" or "row"), + "row_field": row_field, + "no_delete": no_delete, + } + import_lines.append((0, 0, vals)) + for excel_cell, field_name in lines.items(): + sequence += 1 + vals = { + "sequence": sequence, + "section_type": "data", + "excel_cell": excel_cell, + "field_name": field_name, + } + import_lines.append((0, 0, vals)) + rec.write({"import_ids": import_lines}) + + def _compute_input_post_import_hook(self): + self = self.with_context(compute_from_input=True) + for rec in self: + # Import Instruction + input_dict = literal_eval(rec.input_instruction.strip()) + rec.post_import_hook = input_dict.get("__POST_IMPORT__") + + def _compose_field_name(self, line): + field_name = line.field_name or "" + field_name += line.field_cond or "" + field_name += line.style or "" + field_name += line.style_cond or "" + if line.is_sum: + field_name += "@{sum}" + return field_name + + def _compute_output_instruction(self): + """From database, compute back to dictionary""" + for rec in self: + inst_dict = {} + prev_sheet = False + prev_row = False + # Export Instruction + itype = "__EXPORT__" + inst_dict[itype] = {} + for line in rec.export_ids: + if line.section_type == "sheet": + sheet = co.isinteger(line.sheet) and int(line.sheet) or line.sheet + sheet_dict = {sheet: {}} + inst_dict[itype].update(sheet_dict) + prev_sheet = sheet + continue + if line.section_type in ("head", "row"): + row_field = line.row_field + if line.section_type == "row" and line.is_cont: + row_field = f"_CONT_{row_field}" + if line.section_type == "row" and line.is_extend: + row_field = f"_EXTEND_{row_field}" + row_dict = {row_field: {}} + inst_dict[itype][prev_sheet].update(row_dict) + prev_row = row_field + continue + if line.section_type == "data": + excel_cell = line.excel_cell + field_name = self._compose_field_name(line) + cell_dict = {excel_cell: field_name} + inst_dict[itype][prev_sheet][prev_row].update(cell_dict) + continue + # Import Instruction + itype = "__IMPORT__" + inst_dict[itype] = {} + for line in rec.import_ids: + if line.section_type == "sheet": + sheet = co.isinteger(line.sheet) and int(line.sheet) or line.sheet + sheet_dict = {sheet: {}} + inst_dict[itype].update(sheet_dict) + prev_sheet = sheet + continue + if line.section_type in ("head", "row"): + row_field = line.row_field + if line.section_type == "row" and line.no_delete: + row_field = f"_NODEL_{row_field}" + row_dict = {row_field: {}} + inst_dict[itype][prev_sheet].update(row_dict) + prev_row = row_field + continue + if line.section_type == "data": + excel_cell = line.excel_cell + field_name = line.field_name or "" + field_name += line.field_cond or "" + cell_dict = {excel_cell: field_name} + inst_dict[itype][prev_sheet][prev_row].update(cell_dict) + continue + itype = "__POST_IMPORT__" + inst_dict[itype] = False + if rec.post_import_hook: + inst_dict[itype] = rec.post_import_hook + rec.instruction = inst_dict + + def _get_export_action_domain(self, model): + domain = Domain.AND( + [ + Domain("binding_model_id", "in", [model.id]), + Domain("res_model", "in", ["export.xlsx.wizard"]), + Domain("name", "in", ["Export Excel"]), + ] + ) + return domain + + def _get_export_action(self, model): + export_action_domain = self._get_export_action_domain(model) + return self.env["ir.actions.act_window"].search(export_action_domain, limit=1) + + def _create_export_action(self, model): + vals = { + "name": "Export Excel", + "res_model": "export.xlsx.wizard", + "binding_model_id": model.id, + "binding_type": "action", + "target": "new", + "view_mode": "form", + "context": { + "template_domain": [ + ("res_model", "=", self.res_model), + ("export_action_id", "!=", False), + ("gname", "=", False), + ] + }, + } + return self.env["ir.actions.act_window"].create(vals) + + def add_export_action(self): + self.ensure_one() + model = self.env["ir.model"].search( + Domain("model", "in", [self.res_model]), limit=1 + ) + export_action = self._get_export_action(model) + if not export_action: + export_action = self._create_export_action(model) + self.export_action_id = export_action + + def remove_export_action(self): + self.ensure_one() + export_action = self.export_action_id + self.export_action_id = False + domain = Domain("res_model", "in", [self.res_model]) & Domain( + "export_action_id", "in", [export_action.id] + ) + if not self.search(domain): + export_action.unlink() + + def add_import_action(self): + self.ensure_one() + model = self.env["ir.model"].search( + Domain("model", "in", [self.res_model]), limit=1 + ) + tmpl_domain = ( + Domain("res_model", "in", [self.res_model]) + & Domain("fname", "in", [self.fname]) + & Domain("gname", "in", [False]) + ) + vals = { + "name": "Import Excel", + "res_model": "import.xlsx.wizard", + "binding_model_id": model.id, + "binding_type": "action", + "target": "new", + "view_mode": "form", + "context": {"template_domain": tmpl_domain}, + } + action = self.env["ir.actions.act_window"].create(vals) + self.import_action_id = action + + def remove_import_action(self): + self.ensure_one() + if self.import_action_id: + self.import_action_id.unlink() + + def add_report_menu(self): + self.ensure_one() + if not self.fname: + raise UserError(self.env._("No file content!")) + # Create report action + vals = { + "name": self.name, + "report_type": "excel", + "model": "report.xlsx.wizard", + "report_name": self.fname, + "report_file": self.fname, + } + report_action = self.env["ir.actions.report"].create(vals) + self.report_action_id = report_action + # Create window action + vals = { + "name": self.name, + "res_model": "report.xlsx.wizard", + "binding_type": "action", + "target": "new", + "view_mode": "form", + "context": { + "report_action_id": report_action.id, + "default_res_model": self.result_model_id.model, + }, + } + action = self.env["ir.actions.act_window"].create(vals) + # Create menu + vals = { + "name": self.name, + "action": f"{action._name},{action.id}", + } + menu = self.env["ir.ui.menu"].create(vals) + self.report_menu_id = menu + + def remove_report_menu(self): + self.ensure_one() + if self.report_action_id: + self.report_action_id.unlink() + if self.report_menu_id: + self.report_menu_id.action.unlink() + self.report_menu_id.unlink() + + +class XLSXTemplateImport(models.Model): + _name = "xlsx.template.import" + _description = "Detailed of how excel data will be imported" + _order = "sequence" + + template_id = fields.Many2one( + comodel_name="xlsx.template", + string="XLSX Template", + index=True, + ondelete="cascade", + readonly=True, + ) + sequence = fields.Integer(default=10) + sheet = fields.Char() + section_type = fields.Selection( + [("sheet", "Sheet"), ("head", "Head"), ("row", "Row"), ("data", "Data")], + required=True, + ) + row_field = fields.Char(help="If section type is row, this field is required") + no_delete = fields.Boolean( + default=False, + help="By default, all rows will be deleted before import.\n" + "Select No Delete, otherwise", + ) + excel_cell = fields.Char(string="Cell") + field_name = fields.Char(string="Field") + field_cond = fields.Char(string="Field Cond.") + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + vals = self._extract_field_name(vals) + return super().create(vals_list) + + @api.model + def _extract_field_name(self, vals): + if self.env.context.get("compute_from_input") and vals.get("field_name"): + field_name, field_cond = co.get_field_condition(vals["field_name"]) + field_cond = field_cond and f"${{{field_cond or ''}}}" or False + vals.update({"field_name": field_name, "field_cond": field_cond}) + return vals + + +class XLSXTemplateExport(models.Model): + _name = "xlsx.template.export" + _description = "Detailed of how excel data will be exported" + _order = "sequence" + + template_id = fields.Many2one( + comodel_name="xlsx.template", + string="XLSX Template", + index=True, + ondelete="cascade", + readonly=True, + ) + sequence = fields.Integer(default=10) + sheet = fields.Char() + section_type = fields.Selection( + [("sheet", "Sheet"), ("head", "Head"), ("row", "Row"), ("data", "Data")], + required=True, + ) + row_field = fields.Char(help="If section type is row, this field is required") + is_cont = fields.Boolean( + string="Continue", default=False, help="Continue data rows after last data row" + ) + is_extend = fields.Boolean( + string="Extend", + default=False, + help="Extend a blank row after filling each record, to extend the footer", + ) + excel_cell = fields.Char(string="Cell") + field_name = fields.Char(string="Field") + field_cond = fields.Char(string="Field Cond.") + is_sum = fields.Boolean(string="Sum", default=False) + style = fields.Char(string="Default Style") + style_cond = fields.Char(string="Style w/Cond.") + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + vals = self._extract_field_name(vals) + return super().create(vals_list) + + @api.model + def _extract_field_name(self, vals): + if self.env.context.get("compute_from_input") and vals.get("field_name"): + field_name, field_cond = co.get_field_condition(vals["field_name"]) + field_cond = field_cond or 'value or ""' + field_name, style = co.get_field_style(field_name) + field_name, style_cond = co.get_field_style_cond(field_name) + field_name, func = co.get_field_aggregation(field_name) + vals.update( + { + "field_name": field_name, + "field_cond": f"${{{field_cond or ''}}}", + "style": f"#{{{style or ''}}}", + "style_cond": f"#?{style_cond or ''}?", + "is_sum": func == "sum" and True or False, + } + ) + return vals diff --git a/excel_import_export/pyproject.toml b/excel_import_export/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/excel_import_export/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/excel_import_export/readme/CONFIGURE.md b/excel_import_export/readme/CONFIGURE.md new file mode 100644 index 00000000000..c088240106b --- /dev/null +++ b/excel_import_export/readme/CONFIGURE.md @@ -0,0 +1,3 @@ +If you have existing templates from the version 16.0.1.2.0 or earlier, +you need to click 'REMOVE EXPORT ACTION' and then click 'ADD EXPORT +ACTION' in these templates for export actions to work as expected. diff --git a/excel_import_export/readme/CONTRIBUTORS.md b/excel_import_export/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..772c04f03cf --- /dev/null +++ b/excel_import_export/readme/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +- Kitti Upariphutthiphong. \<\> + () +- Saran Lim. \<\> () +- Do Anh Duy \<\> +- [Studio73, S.L.](https://www.studio73.es/) + - Pablo Cortés diff --git a/excel_import_export/readme/DESCRIPTION.md b/excel_import_export/readme/DESCRIPTION.md new file mode 100644 index 00000000000..e86d077c2bb --- /dev/null +++ b/excel_import_export/readme/DESCRIPTION.md @@ -0,0 +1,12 @@ +The module provide pre-built functions and wizards for developer to +build excel import / export / report with ease. + +Without having to code to create excel file, developer do, + +- Create menu, action, wizard, model, view a normal Odoo development. +- Design excel template using standard Excel application, e.g., colors, + fonts, formulas, etc. +- Instruct how the data will be located in Excel with simple dictionary + instruction or from Odoo UI. +- Odoo will combine instruction with excel template, and result in final + excel file. diff --git a/excel_import_export/readme/INSTALL.md b/excel_import_export/readme/INSTALL.md new file mode 100644 index 00000000000..27f33e88cfd --- /dev/null +++ b/excel_import_export/readme/INSTALL.md @@ -0,0 +1,6 @@ +To install this module, you need to install following python library, +**xlrd, xlwt, openpyxl**. + +Then, simply install **excel_import_export**. + +For demo, install **excel_import_export_demo** diff --git a/excel_import_export/readme/ROADMAP.md b/excel_import_export/readme/ROADMAP.md new file mode 100644 index 00000000000..3e7abb91227 --- /dev/null +++ b/excel_import_export/readme/ROADMAP.md @@ -0,0 +1,2 @@ +- Module extension e.g., excel_import_export_async, that add ability to + execute as async process. diff --git a/excel_import_export/readme/USAGE.md b/excel_import_export/readme/USAGE.md new file mode 100644 index 00000000000..34ffa3a1005 --- /dev/null +++ b/excel_import_export/readme/USAGE.md @@ -0,0 +1,120 @@ +## Concepts + +This module contain pre-defined function and wizards to make exporting, +importing and reporting easy. + +At the heart of this module, there are 2 main methods + +- `self.env['xlsx.export'].export_xlsx(...)` +- `self.env['xlsx.import'].import_xlsx(...)` + +For reporting, also call export_xlsx(...) but through following method + +- `self.env['xslx.report'].report_xlsx(...)` + +After install this module, go to Settings \> Technical \> Excel Import/Export \> XLSX +Templates, this is where the key component located. + +As this module provide tools, it is best to explain as use cases. For +example use cases, please install **excel_import_export_demo** + +## Use Cases + +**Use Case 1:** Export/Import Excel on existing document + +This add export/import action menus in existing document (example - +excel_import_export_demo/import_export_sale_order) + +1. Create export action menu on document, \ with + res_model="export.xlsx.wizard" and src_model="\", + and context\['template_domain'\] to locate the right template -- + actions.xml +2. Create import action menu on document, \ with + res_model="import.xlsx.wizard" and src_model="\", + and context\['template_domain'\] to locate the right template -- + action.xml +3. Create/Design Excel Template File (.xlsx), in the template, name the + underlining tab used for export/import -- \.xlsx +4. Create instruction dictionary for export/import in xlsx.template + model -- templates.xml + +**Use Case 2:** Import Excel Files + +With menu wizard to create new documents (example - +excel_import_export_demo/import_sale_orders) + +1. Create report menu with search wizard, + res_model="import.xlsx.wizard" and context\['template_domain'\] to + locate the right template -- menu_action.xml +2. Create Excel Template File (.xlsx), in the template, name the + underlining tab used for import -- \.xlsx +3. Create instruction dictionary for import in xlsx.template model -- + templates.xml + +**Use Case 3:** Create Excel Report + +This create report menu with criteria wizard. (example - +excel_import_export_demo/report_sale_order) + +1. Create report's menu, action, and add context\['template_domain'\] + to locate the right template for this report -- \.xml +2. Create report's wizard for search criteria. The view inherits + `excel_import_export.xlsx_report_view` and mode="primary". In this + view, you only need to add criteria fields, the rest will reuse from + interited view -- \ +3. Create report model as models.Transient, then define search criteria + fields, and get reporing data into `results` field -- \.py +4. Create/Design Excel Template File (.xlsx), in the template, name the + underlining tab used for report results -- \.xlsx +5. Create instruction dictionary for report in xlsx.template model -- + templates.xml + +**Note:** + +Another option for reporting is to use report action +(report_type='excel'), I.e., + +``` xml + + Quotation / Order (.xlsx) + ir.model + 'sale.order' + 'sale.order' + + report + excel + +``` + +By using report action, Odoo will find template using combination of +model and name, then do the export for the underlining record. Please +see example in excel_import_export_demo/report_action, which shows, + +1. Print excel from an active sale.order +2. Run partner list report based on search criteria. + +## Easy Reporting Option + +Technically, this option is the same as "Create Excel Report" use case. +But instead of having to write XML / Python code like normally do, this +option allow user to create a report based on a model or view, all by +configuration only. + +1. Go to Settings \> Technical\> Excel Import/Export \> XLSX Templates, and + create a new template for a report. +2. On the new template, select "Easy Reporting" option, then select + followings + - Report Model, this can be data model or data view we want to get + the results from. + - Click upload your file and add the excel template (.xlsx) + - Click Save, system will create sample export line, user can add + more fields according to results model. +3. Click Add Report Menu, the report menu will be created, user can + change its location. Now the report is ready to use. + +> ![](../static/description/xlsx_template.png) + +Note: Using easy reporting mode, system will used a common criteria +wizard. + +> ![](../static/description/common_wizard.png) diff --git a/excel_import_export/security/ir.model.access.csv b/excel_import_export/security/ir.model.access.csv new file mode 100644 index 00000000000..c71433f5bc0 --- /dev/null +++ b/excel_import_export/security/ir.model.access.csv @@ -0,0 +1,7 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +xlsx_template_user,xlsx_template_user,model_xlsx_template,base.group_user,1,1,1,1 +xlsx_template_export_user,xlsx_template_export_user,model_xlsx_template_export,base.group_user,1,1,1,1 +xlsx_template_import_user,xlsx_template_import_user,model_xlsx_template_import,base.group_user,1,1,1,1 +access_export_xlsx_wizard,access_export_xlsx_wizard,model_export_xlsx_wizard,base.group_user,1,1,1,1 +access_import_xlsx_wizard,access_import_xlsx_wizard,model_import_xlsx_wizard,base.group_user,1,1,1,1 +access_report_xlsx_wizard,access_report_xlsx_wizard,model_report_xlsx_wizard,base.group_user,1,1,1,1 diff --git a/excel_import_export/static/description/common_wizard.png b/excel_import_export/static/description/common_wizard.png new file mode 100644 index 00000000000..0fb95407901 Binary files /dev/null and b/excel_import_export/static/description/common_wizard.png differ diff --git a/excel_import_export/static/description/icon.png b/excel_import_export/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/excel_import_export/static/description/icon.png differ diff --git a/excel_import_export/static/description/index.html b/excel_import_export/static/description/index.html new file mode 100644 index 00000000000..4febd1a3f9e --- /dev/null +++ b/excel_import_export/static/description/index.html @@ -0,0 +1,596 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Excel Import/Export/Report

+ +

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

+

The module provide pre-built functions and wizards for developer to +build excel import / export / report with ease.

+

Without having to code to create excel file, developer do,

+
    +
  • Create menu, action, wizard, model, view a normal Odoo development.
  • +
  • Design excel template using standard Excel application, e.g., colors, +fonts, formulas, etc.
  • +
  • Instruct how the data will be located in Excel with simple dictionary +instruction or from Odoo UI.
  • +
  • Odoo will combine instruction with excel template, and result in +final excel file.
  • +
+

Table of contents

+ +
+

Installation

+

To install this module, you need to install following python library, +xlrd, xlwt, openpyxl.

+

Then, simply install excel_import_export.

+

For demo, install excel_import_export_demo

+
+
+

Configuration

+

If you have existing templates from the version 16.0.1.2.0 or earlier, +you need to click ‘REMOVE EXPORT ACTION’ and then click ‘ADD EXPORT +ACTION’ in these templates for export actions to work as expected.

+
+
+

Usage

+
+

Concepts

+

This module contain pre-defined function and wizards to make exporting, +importing and reporting easy.

+

At the heart of this module, there are 2 main methods

+
    +
  • self.env['xlsx.export'].export_xlsx(...)
  • +
  • self.env['xlsx.import'].import_xlsx(...)
  • +
+

For reporting, also call export_xlsx(…) but through following method

+
    +
  • self.env['xslx.report'].report_xlsx(...)
  • +
+

After install this module, go to Settings > Technical > Excel +Import/Export > XLSX Templates, this is where the key component located.

+

As this module provide tools, it is best to explain as use cases. For +example use cases, please install excel_import_export_demo

+
+
+

Use Cases

+

Use Case 1: Export/Import Excel on existing document

+

This add export/import action menus in existing document (example - +excel_import_export_demo/import_export_sale_order)

+
    +
  1. Create export action menu on document, <act_window> with +res_model=”export.xlsx.wizard” and src_model=”<document_model>”, and +context[‘template_domain’] to locate the right template – +actions.xml
  2. +
  3. Create import action menu on document, <act_window> with +res_model=”import.xlsx.wizard” and src_model=”<document_model>”, and +context[‘template_domain’] to locate the right template – action.xml
  4. +
  5. Create/Design Excel Template File (.xlsx), in the template, name the +underlining tab used for export/import – <file>.xlsx
  6. +
  7. Create instruction dictionary for export/import in xlsx.template +model – templates.xml
  8. +
+

Use Case 2: Import Excel Files

+

With menu wizard to create new documents (example - +excel_import_export_demo/import_sale_orders)

+
    +
  1. Create report menu with search wizard, res_model=”import.xlsx.wizard” +and context[‘template_domain’] to locate the right template – +menu_action.xml
  2. +
  3. Create Excel Template File (.xlsx), in the template, name the +underlining tab used for import – <import file>.xlsx
  4. +
  5. Create instruction dictionary for import in xlsx.template model – +templates.xml
  6. +
+

Use Case 3: Create Excel Report

+

This create report menu with criteria wizard. (example - +excel_import_export_demo/report_sale_order)

+
    +
  1. Create report’s menu, action, and add context[‘template_domain’] to +locate the right template for this report – <report>.xml
  2. +
  3. Create report’s wizard for search criteria. The view inherits +excel_import_export.xlsx_report_view and mode=”primary”. In this +view, you only need to add criteria fields, the rest will reuse from +interited view – <report.xml>
  4. +
  5. Create report model as models.Transient, then define search criteria +fields, and get reporing data into results field – <report>.py
  6. +
  7. Create/Design Excel Template File (.xlsx), in the template, name the +underlining tab used for report results – <report_file>.xlsx
  8. +
  9. Create instruction dictionary for report in xlsx.template model – +templates.xml
  10. +
+

Note:

+

Another option for reporting is to use report action +(report_type=’excel’), I.e.,

+
+<record id="action_report_saleorder_excel" model="ir.actions.report">
+        <field name="name">Quotation / Order (.xlsx)</field>
+        <field name="model">ir.model</field>
+        <field name="report_name">'sale.order'</field>
+        <field name="report_file">'sale.order'</field>
+        <field name="binding_model_id" ref="sale.model_sale_order"/>
+        <field name="binding_type">report</field>
+        <field name="report_type">excel</field>
+</record>
+
+

By using report action, Odoo will find template using combination of +model and name, then do the export for the underlining record. Please +see example in excel_import_export_demo/report_action, which shows,

+
    +
  1. Print excel from an active sale.order
  2. +
  3. Run partner list report based on search criteria.
  4. +
+
+
+

Easy Reporting Option

+

Technically, this option is the same as “Create Excel Report” use case. +But instead of having to write XML / Python code like normally do, this +option allow user to create a report based on a model or view, all by +configuration only.

+
    +
  1. Go to Settings > Technical> Excel Import/Export > XLSX Templates, and +create a new template for a report.
  2. +
  3. On the new template, select “Easy Reporting” option, then select +followings
      +
    • Report Model, this can be data model or data view we want to get +the results from.
    • +
    • Click upload your file and add the excel template (.xlsx)
    • +
    • Click Save, system will create sample export line, user can add +more fields according to results model.
    • +
    +
  4. +
  5. Click Add Report Menu, the report menu will be created, user can +change its location. Now the report is ready to use.
  6. +
+ +
+image1
+

Note: Using easy reporting mode, system will used a common criteria +wizard.

+
+image2
+
+
+
+

Known issues / Roadmap

+
    +
  • Module extension e.g., excel_import_export_async, that add ability to +execute as async process.
  • +
+
+
+

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

+
    +
  • Ecosoft
  • +
+
+
+

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.

+

Current maintainer:

+

kittiu

+

This module is part of the OCA/server-tools project on GitHub.

+

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

+
+
+
+
+ + diff --git a/excel_import_export/static/description/xlsx_template.png b/excel_import_export/static/description/xlsx_template.png new file mode 100644 index 00000000000..c4bdc37f9fa Binary files /dev/null and b/excel_import_export/static/description/xlsx_template.png differ diff --git a/excel_import_export/static/src/js/report/action_manager_report.esm.js b/excel_import_export/static/src/js/report/action_manager_report.esm.js new file mode 100644 index 00000000000..20b073be419 --- /dev/null +++ b/excel_import_export/static/src/js/report/action_manager_report.esm.js @@ -0,0 +1,54 @@ +import {download} from "@web/core/network/download"; +import {registry} from "@web/core/registry"; +import {user} from "@web/core/user"; + +function getReportUrl({report_name, context, data}) { + // Rough copy of action_service.js _getReportUrl method. + let url = `/report/excel/${report_name}`; + const actionContext = context || {}; + if (data && JSON.stringify(data) !== "{}") { + const encodedOptions = encodeURIComponent(JSON.stringify(data)); + const encodedContext = encodeURIComponent(JSON.stringify(actionContext)); + return `${url}?options=${encodedOptions}&context=${encodedContext}`; + } + if (actionContext.active_ids) { + url += `/${actionContext.active_ids.join(",")}`; + } + const userContext = encodeURIComponent(JSON.stringify(user.context)); + return `${url}?context=${userContext}`; +} + +async function triggerDownload(action, {onClose}, env) { + // Rough copy of action_service.js _triggerDownload method. + env.services.ui.block(); + try { + await download({ + url: "/report/download", + data: { + data: JSON.stringify([getReportUrl(action), "excel"]), + context: JSON.stringify(user.context), + }, + }); + } finally { + env.services.ui.unblock(); + } + if (action.close_on_report_download) { + return env.services.action.doAction( + {type: "ir.actions.act_window_close"}, + {onClose} + ); + } + if (onClose) { + onClose(); + } +} + +registry + .category("ir.actions.report handlers") + .add("excel_handler", async function (action, options, env) { + if (action.report_type === "excel") { + await triggerDownload(action, options, env); + return true; + } + return false; + }); diff --git a/excel_import_export/tests/__init__.py b/excel_import_export/tests/__init__.py new file mode 100644 index 00000000000..ef34cffd2de --- /dev/null +++ b/excel_import_export/tests/__init__.py @@ -0,0 +1 @@ +from . import test_excel_import_export diff --git a/excel_import_export/tests/common.py b/excel_import_export/tests/common.py new file mode 100644 index 00000000000..67fd5ee06f9 --- /dev/null +++ b/excel_import_export/tests/common.py @@ -0,0 +1,34 @@ +# Copyright 2026 Studio73 - Pablo Cortés +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +import base64 +from io import BytesIO + +import openpyxl + +from odoo.addons.base.tests.common import BaseCommon + + +class TestExcelImportExportCommon(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + wb = openpyxl.Workbook() + ws = wb.active + ws.title = "Sheet1" + out = BytesIO() + wb.save(out) + out.seek(0) + cls.dummy_xlsx_b64 = base64.b64encode(out.read()) + cls.partner = cls.env["res.partner"].create({"name": "Test OCA Partner"}) + cls.template = cls.env["xlsx.template"].create( + { + "name": "Test Partner Template", + "res_model": "res.partner", + "fname": "test_partner.xlsx", + "datas": cls.dummy_xlsx_b64, + "input_instruction": "{'__EXPORT__': {'Sheet1': {'_HEAD_': {'A1': 'name','B1': 'phone'}}},'__IMPORT__': {'Sheet1': {'_HEAD_': {'A1': 'name'}}}}", # noqa: E501 + "to_csv": False, + "use_report_wizard": False, + } + ) diff --git a/excel_import_export/tests/test_excel_import_export.py b/excel_import_export/tests/test_excel_import_export.py new file mode 100644 index 00000000000..172a317d21a --- /dev/null +++ b/excel_import_export/tests/test_excel_import_export.py @@ -0,0 +1,243 @@ +# Copyright 2026 Studio73 - Pablo Cortés +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +import base64 + +from odoo.exceptions import UserError, ValidationError + +from odoo.addons.excel_import_export.models import common + +from .common import TestExcelImportExportCommon + + +class TestExcelImportExport(TestExcelImportExportCommon): + def test_01_compute_instructions_from_dict(self): + """Test the string dictionary is parsed into the Odoo lines correctly""" + self.assertTrue(self.template.export_ids) + self.assertTrue(self.template.import_ids) + export_data_lines = self.template.export_ids.filtered( + lambda line: line.section_type == "data" + ) + self.assertEqual( + len(export_data_lines), 2, "It should parse 2 data fields for Export" + ) + self.assertIn("name", export_data_lines.mapped("field_name")) + + def test_02_add_and_remove_export_action(self): + """Test the creation and removal of contextual export actions""" + self.template.add_export_action() + self.assertTrue(self.template.export_action_id) + self.assertEqual(self.template.export_action_id.res_model, "export.xlsx.wizard") + self.assertEqual( + self.template.export_action_id.binding_model_id.model, "res.partner" + ) + self.template.remove_export_action() + self.assertFalse(self.template.export_action_id) + + def test_03_easy_reporting_menu(self): + """Test Easy Reporting Wizard capabilities""" + self.template.write( + { + "use_report_wizard": True, + "result_model_id": self.env["ir.model"]._get_id("res.partner"), + } + ) + self.assertTrue(self.template.result_field) + self.assertEqual(self.template.res_model, "res.partner") + self.template.add_report_menu() + self.assertTrue(self.template.report_action_id) + self.assertTrue(self.template.report_menu_id) + self.template.remove_report_menu() + self.assertFalse(self.template.report_action_id) + self.assertFalse(self.template.report_menu_id) + + def test_04_export_wizard_default_get(self): + """Test that the export wizard finds the right template based on context""" + self.template.write( + { + "use_report_wizard": False, + "res_model": "res.partner", + } + ) + self.template.add_export_action() + Wizard = self.env["export.xlsx.wizard"].with_context( + active_model="res.partner", + active_ids=[self.partner.id], + template_domain=[("res_model", "=", "res.partner")], + ) + defaults = Wizard.default_get(["template_id", "res_ids", "res_model"]) + self.assertEqual(defaults.get("template_id"), self.template.id) + self.assertEqual(defaults.get("res_model"), "res.partner") + self.assertEqual(defaults.get("res_ids"), str(self.partner.id)) + + def test_05_mismatch_model_exception(self): + """Test that attempting to export with a wrong model raises ValidationError""" + ExportService = self.env["xlsx.export"] + with self.assertRaises(ValidationError): + ExportService.export_xlsx(self.template, res_model="res.users", res_ids=[1]) + + def test_06_actual_export(self): + """Test standard export capabilities""" + ExportService = self.env["xlsx.export"] + out_file, out_name = ExportService.export_xlsx( + self.template, res_model="res.partner", res_ids=[self.partner.id] + ) + self.assertTrue(out_file) + self.assertTrue(out_name) + + def test_07_export_multiple_records_zip(self): + """Test exporting multiple records to force the ZIP fallback""" + partner2 = self.env["res.partner"].create({"name": "Partner 2"}) + ExportService = self.env["xlsx.export"] + out_file, out_name = ExportService.export_xlsx( + self.template, + res_model="res.partner", + res_ids=[self.partner.id, partner2.id], + ) + self.assertTrue(out_file) + self.assertEqual(out_name, "files.zip") + + def test_08_actual_import(self): + """Test standard import back from exported file""" + ExportService = self.env["xlsx.export"] + out_file, out_name = ExportService.export_xlsx( + self.template, res_model="res.partner", res_ids=[self.partner.id] + ) + ImportService = self.env["xlsx.import"] + record = ImportService.import_xlsx( + out_file, self.template, res_model="res.partner", res_id=False + ) + self.assertTrue(record) + + def test_09_report_render_excel(self): + """Test the report action override""" + report_action = self.env["ir.actions.report"].create( + { + "name": "Test Excel Report", + "model": "res.partner", + "report_name": "test_partner.xlsx", + "report_file": "test_partner.xlsx", + "report_type": "excel", + } + ) + excel_data = report_action._render_excel([self.partner.id], {}) + self.assertTrue(excel_data) + self.assertTrue(excel_data[1].endswith(".xlsx")) + # Test error for multiple ids + with self.assertRaises(UserError): + report_action._render_excel([self.partner.id, self.partner.id], {}) + + def test_10_common_utils(self): + """Test coverage for common tools functions""" + self.assertEqual(common.split_row_col("A1"), ("A", 1)) + self.assertEqual(common.pos2idx("A1"), (0, 0)) + self.assertEqual(common.pos2idx("B2"), (1, 1)) + self.assertTrue(common.isdatetime("2020-01-01")) + self.assertTrue(common.isdatetime("2020-01-01 10:00:00")) + self.assertFalse(common.isdatetime("abc")) + self.assertTrue(common.isfloat("1.23")) + self.assertFalse(common.isfloat("abc")) + self.assertTrue(common.isinteger("123")) + self.assertFalse(common.isinteger("abc")) + self.assertEqual(common.adjust_cell_formula("?(A1)+?(B2)", 5), "A6+B7") + self.assertEqual(common.get_field_aggregation("field@{sum}"), ("field", "sum")) + self.assertEqual( + common.get_field_style("field#{font=bold}"), ("field", "font=bold") + ) + self.assertEqual( + common.get_field_condition("field${value > 0}"), ("field", "value > 0") + ) + self.assertEqual( + common.get_groupby('line_ids["a_id", "b_id"]'), ["a_id", "b_id"] + ) + + def test_11_csv_export(self): + """Test csv exportation override in template""" + self.template.to_csv = True + ExportService = self.env["xlsx.export"] + out_file, out_name = ExportService.export_xlsx( + self.template, res_model="res.partner", res_ids=[self.partner.id] + ) + self.assertTrue(out_name.endswith(".csv")) + + def test_12_report_xlsx_wizard(self): + """Test execution of the specific wizard view""" + self.template.write( + { + "use_report_wizard": True, + "result_model_id": self.env["ir.model"]._get_id("res.partner"), + } + ) + self.template.add_report_menu() + action_id = self.template.report_action_id.id + + wizard = ( + self.env["report.xlsx.wizard"] + .with_context(report_action_id=action_id) + .create( + { + "res_model": "res.partner", + "domain": "[]", + } + ) + ) + res = wizard.action_report() + self.assertEqual(res["type"], "ir.actions.report") + + def test_13_import_wizard(self): + """Test import wizard views and flow""" + wizard = ( + self.env["import.xlsx.wizard"] + .with_context( + active_model="res.partner", + active_id=self.partner.id, + template_domain=[("id", "=", self.template.id)], + ) + .create( + { + "template_id": self.template.id, + } + ) + ) + sample = wizard.get_import_sample() + self.assertEqual(sample["res_model"], "import.xlsx.wizard") + + ExportService = self.env["xlsx.export"] + out_file, _ = ExportService.export_xlsx( + self.template, res_model="res.partner", res_ids=[self.partner.id] + ) + wizard.import_file = out_file + wizard.action_import() + self.assertEqual(wizard.state, "get") + + def test_14_xlsx_report_abstract_model(self): + """Test default get on the base report model""" + defaults = ( + self.env["xlsx.report"] + .with_context(template_domain=[("id", "=", self.template.id)]) + .default_get(["template_id"]) + ) + self.assertEqual(defaults.get("template_id"), self.template.id) + + def test_15_styles(self): + """Test the generic styler load""" + styles = self.env["xlsx.styles"].get_openpyxl_styles() + self.assertIn("font", styles) + self.assertIn("fill", styles) + self.assertIn("align", styles) + + def test_16_csv_from_excel_util(self): + """Test CSV converter natively""" + out_file, _ = self.env["xlsx.export"].export_xlsx( + self.template, res_model="res.partner", res_ids=[self.partner.id] + ) + excel_content = base64.b64decode(out_file) + csv_content = common.csv_from_excel(excel_content, ",", True) + self.assertTrue(csv_content) + + def test_17_get_field_type_deep(self): + """Test deep model search for types in import utility.""" + field_type = self.env["xlsx.import"]._get_field_type( + "res.partner", "child_ids/name" + ) + self.assertEqual(field_type, "char") diff --git a/excel_import_export/views/xlsx_report.xml b/excel_import_export/views/xlsx_report.xml new file mode 100644 index 00000000000..e412a351c34 --- /dev/null +++ b/excel_import_export/views/xlsx_report.xml @@ -0,0 +1,54 @@ + + + + + xlsx.report.view + xlsx.report + +
+ + + +
+
+
+
+

+ Complete Prepare Report (.xlsx) +

+

+ Here is the report file: + +

+
+
+
+
+
+
+ +
+
+
diff --git a/excel_import_export/views/xlsx_template_view.xml b/excel_import_export/views/xlsx_template_view.xml new file mode 100644 index 00000000000..bc3da2fcbcb --- /dev/null +++ b/excel_import_export/views/xlsx_template_view.xml @@ -0,0 +1,422 @@ + + + + + xlsx.template + + + + + + + + xlsx.template + +
+ +
+
+

+ +

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+

Help with Export Instruction

+

+ Export Instruction is how to write data from an active data record to specified cells in excel sheet. + For example, an active record can be a sale order that user want to export. + The record itself will be mapped to the header part of excel sheet. The record can contain multiple one2many fields, which will be written as data lines. + You can look at following instruction as Excel Sheet(s), each with 1 header section (_HEAD_) and multiple row sections (one2many fields). +

+
    +
  • In header section part, map data fields (e.g., number, partner_id.name) into cells (e.g., B1, B2).
  • +
  • In row section, data list will be rolled out from one2many row field (e.g., order_line), and map data field (i.e., product_id.name, uom_id.name, qty) into the first row cells to start rolling (e.g., A6, B6, C6).
  • +
+

Following are more explaination on each column:

+
    +
  • Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet to export data to
  • +
  • Row Field: Use _HEAD_ for the record itself, and one2many field (e.g., line_ids) for row data
  • +
  • Continue: If not selected, start rolling with specified first row cells. If selected, continue from previous one2many field
  • +
  • Extend: If selected, extend one row after one data row in order to preserve the sum line
  • +
  • Cell: Location of data in excel sheet (e.g., A1, B1, ...)
  • +
  • Field: Field of the record, e.g., product_id.uom_id.name. They are orm compliant.
  • +
  • Field Cond.: Python code in ${...} to manipulate field value, e.g., if field = product_id, value will represent product object, e.g., ${value and value.uom_id.name or ""}
  • +
  • Sum: Add sum value on last row, @{sum}
  • +
  • Style: Default style in #{...} that apply to each cell, e.g., #{align=left;style=text}. See module's style.py for available styles.
  • +
  • Style w/Cond.: Conditional style by python code in #?...?, e.g., apply style for specific product, #?value.name == "ABC" and #{font=bold;fill=red} or None?
  • +
+

+ Note: +

+ For code block ${...} and #?...?, following object are available, +
    +
  • value: value from Field
  • +
  • object: record object or line object depends on Row Field
  • +
  • model: active model, e.g., self.env['my.model']
  • +
  • date, datetime, time: some useful python classes
  • +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+

Help with Import Instruction

+

+ Import Instruction is how to get data from excel sheet and write them to an active record. + For example, user create a sales order document, and want to import order lines from excel. + In reverse direction to exporting, data from excel's cells will be mapped to record fields during import. + Cells can be mapped to record in header section (_HEAD_) and data table can be mapped to row section (one2many field, begins from specifed cells. +

+
    +
  • In header section, map cells (e.g., B1, B2) into data fields (e.g., number, partner_id).
  • +
  • In row section, data table from excel can be imported to one2many row field (e.g., order_line) by mapping cells on first row onwards (e.g., A6, B6, C6) to fields (e.g., product_id, uom_id, qty)
  • +
+

Following are more explaination on each column:

+
    +
  • Sheet: Name (e.g., Sheet 1) or index (e.g., 1) of excel sheet
  • +
  • Row Field: Use _HEAD_ for the record itself, and one2many field for row data, e.g., order_line, line_ids[max_row] where [max_row] is optional number of rows to import
  • +
  • No Delete: By default, all one2many lines will be deleted before import. Select this, to avoid deletion
  • +
  • Cell: Location of data in excel sheet (e.g., A1, B1, ...)
  • +
  • Field: Field of the record to be imported to, e.g., product_id
  • +
  • Field Cond.: Python code in ${...} value will represent data from excel cell, e.g., if A1 = 'ABC', value will represent 'ABC', e.g., ${value == "ABC" and "X" or "Y"} thus can change from cell value to other value for import.
  • +
+

+ Note: +

+ For code block ${...}, following object are available, +
    +
  • value: value from Cell
  • +
  • model: active model, e.g., self.env['my.model']
  • +
  • date, datetime, time: some useful python classes
  • +
+
+
+ + + + +
+
+
+
+
+ + XLSX Templates + ir.actions.act_window + xlsx.template + list,form + +

+ Click to create a XLSX Template Object. +

+
+
+ + +
diff --git a/excel_import_export/wizard/__init__.py b/excel_import_export/wizard/__init__.py new file mode 100644 index 00000000000..ffdeb0d0aa3 --- /dev/null +++ b/excel_import_export/wizard/__init__.py @@ -0,0 +1,3 @@ +from . import export_xlsx_wizard +from . import import_xlsx_wizard +from . import report_xlsx_wizard diff --git a/excel_import_export/wizard/export_xlsx_wizard.py b/excel_import_export/wizard/export_xlsx_wizard.py new file mode 100644 index 00000000000..331afac5f7a --- /dev/null +++ b/excel_import_export/wizard/export_xlsx_wizard.py @@ -0,0 +1,77 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo import api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools.safe_eval import safe_eval + + +class ExportXLSXWizard(models.TransientModel): + """This wizard is used with the template (xlsx.template) to export + xlsx template filled with data form the active record""" + + _name = "export.xlsx.wizard" + _description = "Wizard for exporting excel" + + def _domain_template_id(self): + return ( + "[" + "('res_model', '=', res_model), " + "('export_action_id', '!=', False), " + "('gname', '=', False)" + "]" + ) + + name = fields.Char(string="File Name", readonly=True, size=500) + data = fields.Binary(string="File", readonly=True) + template_id = fields.Many2one( + "xlsx.template", + string="Template", + required=True, + ondelete="cascade", + domain=lambda self: self._domain_template_id(), + ) + res_ids = fields.Char(string="Resource IDs", readonly=True, required=True) + res_model = fields.Char( + string="Resource Model", readonly=True, required=True, size=500 + ) + state = fields.Selection( + [("choose", "Choose"), ("get", "Get")], + default="choose", + help="* Choose: wizard show in user selection mode" + "\n* Get: wizard show results from user action", + ) + + @api.model + def default_get(self, fields): + res_model = self.env.context.get("active_model", False) + res_ids = self.env.context.get("active_ids", False) + template_domain = self.env.context.get("template_domain", []) + templates = self.env["xlsx.template"].search(template_domain) + if not templates: + raise ValidationError(self.env._("No template found")) + defaults = super().default_get(fields) + for template in templates: + if not template.datas: + raise ValidationError(self.env._("No file in %s", template.name)) + defaults["template_id"] = len(templates) == 1 and templates.id or False + defaults["res_ids"] = ",".join([str(x) for x in res_ids]) + defaults["res_model"] = res_model + return defaults + + def action_export(self): + self.ensure_one() + Export = self.env["xlsx.export"] + out_file, out_name = Export.export_xlsx( + self.template_id, self.res_model, safe_eval(self.res_ids) + ) + self.write({"state": "get", "data": out_file, "name": out_name}) + return { + "name": self.env._("Excel Report"), + "type": "ir.actions.act_window", + "res_model": "export.xlsx.wizard", + "view_mode": "form", + "res_id": self.id, + "views": [(False, "form")], + "target": "new", + } diff --git a/excel_import_export/wizard/export_xlsx_wizard.xml b/excel_import_export/wizard/export_xlsx_wizard.xml new file mode 100644 index 00000000000..5248c7e4374 --- /dev/null +++ b/excel_import_export/wizard/export_xlsx_wizard.xml @@ -0,0 +1,46 @@ + + + + + export.xlsx.wizard + export.xlsx.wizard + +
+ + + + + + + +
+

Complete Prepare File (.xlsx)

+

Here is the exported file:

+
+
+
+
+
+ +
+
+
diff --git a/excel_import_export/wizard/import_xlsx_wizard.py b/excel_import_export/wizard/import_xlsx_wizard.py new file mode 100644 index 00000000000..7492aea9e62 --- /dev/null +++ b/excel_import_export/wizard/import_xlsx_wizard.py @@ -0,0 +1,167 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + + +from odoo import api, fields, models +from odoo.exceptions import RedirectWarning, ValidationError + + +class ImportXLSXWizard(models.TransientModel): + """This wizard is used with the template (xlsx.template) to import + xlsx template back to active record""" + + _name = "import.xlsx.wizard" + _description = "Wizard for importing excel" + + def _domain_template_id(self): + return ( + "[" + "('res_model', '=', res_model), " + "('fname', '=', fname), " + "('gname', '=', False)" + "] if fname and res_model else []" + ) + + import_file = fields.Binary(string="Import File (*.xlsx)") + filename = fields.Char("Import File Name") + template_id = fields.Many2one( + "xlsx.template", + string="Template", + required=True, + ondelete="cascade", + domain=lambda self: self._domain_template_id(), + ) + res_id = fields.Integer(string="Resource ID", readonly=True) + res_model = fields.Char(string="Resource Model", readonly=True, size=500) + datas = fields.Binary(string="Sample", related="template_id.datas", readonly=True) + fname = fields.Char( + string="Template Name", related="template_id.fname", readonly=True + ) + attachment_ids = fields.Many2many( + "ir.attachment", + string="Import File(s) (*.xlsx)", + required=True, + help="You can select multiple files to import.", + ) + state = fields.Selection( + [("choose", "Choose"), ("get", "Get")], + default="choose", + help="* Choose: wizard show in user selection mode" + "\n* Get: wizard show results from user action", + ) + + def check_view_init(self, context): + """This template only works on some context of active record""" + res_model = context.get("active_model", False) + res_id = context.get("active_id", False) + if not res_model or not res_id: + return + record = self.env[res_model].browse(res_id) + messages = [] + valid = True + # For all import, only allow import in draft state (for documents) + import_states = context.get("template_import_states", []) + if import_states: # states specified in context, test this + if "state" in record and record["state"] not in import_states: + messages.append( + self.env._("Document must be in %s states", import_states) + ) + valid = False + else: # no specific state specified, test with draft + if "state" in record and "draft" not in record["state"]: # not in + messages.append(self.env._("Document must be in draft state")) + valid = False + # Context testing + if context.get("template_context", False): + template_context = context["template_context"] + for key, value in template_context.items(): + if ( + key not in record + or ( + record._fields[key].type == "many2one" + and record[key].id + or record[key] + ) + != value + ): + valid = False + messages.append( + self.env._( + "This import action is not usable in this document context" + ) + ) + break + if not valid: + raise ValidationError("\n".join(messages)) + return + + @api.model + def default_get(self, fields_list): + context = self.env.context + res_model = context.get("active_model", False) + res_id = context.get("active_id", False) + template_domain = context.get("template_domain", []) + templates = self.env["xlsx.template"].search(template_domain) + if not templates: + raise ValidationError(self.env._("No template found")) + res = super().default_get(fields_list) + for template in templates: + if not template.datas: + act = self.env.ref("excel_import_export.action_xlsx_template") + raise RedirectWarning( + self.env._( + 'File "%(fname)s" not found in template, %(name)s.', + fname=template.fname, + name=template.name, + ), + act.id, + self.env._("Set Templates"), + ) + self.check_view_init(context) + res["template_id"] = len(templates) == 1 and template.id or False + res["res_id"] = res_id + res["res_model"] = res_model + return res + + def get_import_sample(self): + self.ensure_one() + return { + "name": self.env._("Import Excel"), + "type": "ir.actions.act_window", + "res_model": "import.xlsx.wizard", + "view_mode": "form", + "res_id": self.id, + "views": [(False, "form")], + "target": "new", + "context": self.env.context.copy(), + } + + def action_import(self): + self.ensure_one() + Import = self.env["xlsx.import"] + res_ids = [] + if self.import_file: + record = Import.import_xlsx( + self.import_file, self.template_id, self.res_model, self.res_id + ) + res_ids = [record.id] + elif self.attachment_ids: + for attach in self.attachment_ids: + record = Import.import_xlsx(attach.datas, self.template_id) + res_ids.append(record.id) + else: + raise ValidationError(self.env._("Please select Excel file to import")) + # If redirect_action is specified, do redirection + if self.template_id.redirect_action: + vals = self.template_id.redirect_action.read()[0] + vals["domain"] = [("id", "in", res_ids)] + return vals + self.write({"state": "get"}) + return { + "type": "ir.actions.act_window", + "res_model": self._name, + "view_mode": "form", + "res_id": self.id, + "views": [(False, "form")], + "target": "new", + } diff --git a/excel_import_export/wizard/import_xlsx_wizard.xml b/excel_import_export/wizard/import_xlsx_wizard.xml new file mode 100644 index 00000000000..4e44b17b544 --- /dev/null +++ b/excel_import_export/wizard/import_xlsx_wizard.xml @@ -0,0 +1,61 @@ + + + + + import.xlsx.wizard + import.xlsx.wizard + +
+ + + + + + + + + +
+
+ +
+
+ +

+ Import Successful! +

+
+
+
+
+
+ +
+
+
diff --git a/excel_import_export/wizard/report_xlsx_wizard.py b/excel_import_export/wizard/report_xlsx_wizard.py new file mode 100644 index 00000000000..ef61332711e --- /dev/null +++ b/excel_import_export/wizard/report_xlsx_wizard.py @@ -0,0 +1,22 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo import fields, models +from odoo.fields import Domain + + +class ReportXLSXWizard(models.TransientModel): + _name = "report.xlsx.wizard" + _description = "Generic Report Wizard, used with template reporting option" + + res_model = fields.Char() + domain = fields.Char(string="Search Criterias") + + def action_report(self): + action_id = self.env.context.get("report_action_id") + action = self.env["ir.actions.report"].browse(action_id) + res = action.read()[0] + return res + + def safe_domain(self, str_domain): + return Domain(str_domain) or Domain() diff --git a/excel_import_export/wizard/report_xlsx_wizard.xml b/excel_import_export/wizard/report_xlsx_wizard.xml new file mode 100644 index 00000000000..f27f3416eb8 --- /dev/null +++ b/excel_import_export/wizard/report_xlsx_wizard.xml @@ -0,0 +1,31 @@ + + + + + report.xlsx.wizard + report.xlsx.wizard + +
+ + + + + +
+
+
+
diff --git a/requirements.txt b/requirements.txt index dfd6b25509f..352a737ea3a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ dataclasses numpy odoorpc +openpyxl openupgradelib