diff --git a/.copier-answers.yml b/.copier-answers.yml index a9ca7243..ba065f90 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Do NOT update manually; changes here will be overwritten by Copier -_commit: v1.21.1 +_commit: v1.24 _src_path: https://github.com/OCA/oca-addons-repo-template.git additional_ruff_rules: [] ci: GitHub diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..0b382039 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,188 @@ +env: + browser: true + es6: true + +# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449 +parserOptions: + ecmaVersion: 2022 + +overrides: + - files: + - "**/*.esm.js" + parserOptions: + sourceType: module + +# Globals available in Odoo that shouldn't produce errorings +globals: + _: readonly + $: readonly + fuzzy: readonly + jQuery: readonly + moment: readonly + odoo: readonly + openerp: readonly + owl: readonly + luxon: readonly + +# Styling is handled by Prettier, so we only need to enable AST rules; +# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890 +rules: + accessor-pairs: warn + array-callback-return: warn + callback-return: warn + capitalized-comments: + - warn + - always + - ignoreConsecutiveComments: true + ignoreInlineComments: true + complexity: + - warn + - 15 + constructor-super: warn + dot-notation: warn + eqeqeq: warn + global-require: warn + handle-callback-err: warn + id-blacklist: warn + id-match: warn + init-declarations: error + max-depth: warn + max-nested-callbacks: warn + max-statements-per-line: warn + no-alert: warn + no-array-constructor: warn + no-caller: warn + no-case-declarations: warn + no-class-assign: warn + no-cond-assign: error + no-const-assign: error + no-constant-condition: warn + no-control-regex: warn + no-debugger: error + no-delete-var: warn + no-div-regex: warn + no-dupe-args: error + no-dupe-class-members: error + no-dupe-keys: error + no-duplicate-case: error + no-duplicate-imports: error + no-else-return: warn + no-empty-character-class: warn + no-empty-function: error + no-empty-pattern: error + no-empty: warn + no-eq-null: error + no-eval: error + no-ex-assign: error + no-extend-native: warn + no-extra-bind: warn + no-extra-boolean-cast: warn + no-extra-label: warn + no-fallthrough: warn + no-func-assign: error + no-global-assign: error + no-implicit-coercion: + - warn + - allow: ["~"] + no-implicit-globals: warn + no-implied-eval: warn + no-inline-comments: warn + no-inner-declarations: warn + no-invalid-regexp: warn + no-irregular-whitespace: warn + no-iterator: warn + no-label-var: warn + no-labels: warn + no-lone-blocks: warn + no-lonely-if: error + no-mixed-requires: error + no-multi-str: warn + no-native-reassign: error + no-negated-condition: warn + no-negated-in-lhs: error + no-new-func: warn + no-new-object: warn + no-new-require: warn + no-new-symbol: warn + no-new-wrappers: warn + no-new: warn + no-obj-calls: warn + no-octal-escape: warn + no-octal: warn + no-param-reassign: warn + no-path-concat: warn + no-process-env: warn + no-process-exit: warn + no-proto: warn + no-prototype-builtins: warn + no-redeclare: warn + no-regex-spaces: warn + no-restricted-globals: warn + no-restricted-imports: warn + no-restricted-modules: warn + no-restricted-syntax: warn + no-return-assign: error + no-script-url: warn + no-self-assign: warn + no-self-compare: warn + no-sequences: warn + no-shadow-restricted-names: warn + no-shadow: warn + no-sparse-arrays: warn + no-sync: warn + no-this-before-super: warn + no-throw-literal: warn + no-undef-init: warn + no-undef: error + no-unmodified-loop-condition: warn + no-unneeded-ternary: error + no-unreachable: error + no-unsafe-finally: error + no-unused-expressions: error + no-unused-labels: error + no-unused-vars: error + no-use-before-define: error + no-useless-call: warn + no-useless-computed-key: warn + no-useless-concat: warn + no-useless-constructor: warn + no-useless-escape: warn + no-useless-rename: warn + no-void: warn + no-with: warn + operator-assignment: [error, always] + prefer-const: warn + radix: warn + require-yield: warn + sort-imports: warn + spaced-comment: [error, always] + strict: [error, function] + use-isnan: error + valid-jsdoc: + - warn + - prefer: + arg: param + argument: param + augments: extends + constructor: class + exception: throws + func: function + method: function + prop: property + return: returns + virtual: abstract + yield: yields + preferType: + array: Array + bool: Boolean + boolean: Boolean + number: Number + object: Object + str: String + string: String + requireParamDescription: false + requireReturn: false + requireReturnDescription: false + requireReturnType: false + valid-typeof: warn + yoda: warn diff --git a/.gitignore b/.gitignore index 0090721f..2b045db3 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,15 @@ var/ *.egg *.eggs +# Debian packages +*.deb + +# Redhat packages +*.rpm + +# MacOS packages +*.dmg + # Installer logs pip-log.txt pip-delete-this-directory.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ebd31027..31036037 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: hooks: - id: whool-init - repo: https://github.com/oca/maintainer-tools - rev: 9a170331575a265c092ee6b24b845ec508e8ef75 + rev: d5fab7ee87fceee858a3d01048c78a548974d935 hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons diff --git a/spreadsheet_oca/README.rst b/spreadsheet_oca/README.rst new file mode 100644 index 00000000..820e4a88 --- /dev/null +++ b/spreadsheet_oca/README.rst @@ -0,0 +1,186 @@ +=============== +Spreadsheet Oca +=============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7063862a00cfdcd251fbd166dc46a127b4e47aeca1c9bc3788930bf7716c6ffa + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fspreadsheet-lightgray.png?logo=github + :target: https://github.com/OCA/spreadsheet/tree/17.0/spreadsheet_oca + :alt: OCA/spreadsheet +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/spreadsheet-17-0/spreadsheet-17-0-spreadsheet_oca + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/spreadsheet&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds a functionality for adding and editing Spreadsheets +using Odoo CE. + +It is an alternative to the proprietary module ``spreadsheet_edition`` +of Odoo Enterprise Edition. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +**Create a new spreadsheet** +---------------------------- + +- Go to 'Spreadsheet' menu +- Click on 'Create' +- Put a name, then click on the "Edit" button + +|image1| + +- At this point you switch to spreadsheet editing mode. The editor is + named ``o-spreadsheet`` and looks like another common spreadsheet web + editors. (OnlyOffice, Ethercalc, Google Sheets (non-free)). + +|image2| + +- You can use common functions ``SUM()``, ``AVERAGE()``, etc. in the + cells. For a complete list of functions and their syntax, Refer to + the documentation https://github.com/odoo/o-spreadsheet/ or go to + https://odoo.github.io/o-spreadsheet/ and click on "Insert > + Function". + +|image3| + +- Note: Business Odoo module can add "business functions". This is + currently the case for the accounting module, which adds the + following features: + + - ``ODOO.CREDIT(account_codes, date_range)``: Get the total + credit for the specified account(s) and period. + - ``ODOO.DEBIT(account_codes, date_range)``: Get the total debit + for the specified account(s) and period. + - ``ODOO.BALANCE(account_codes, date_range)``: Get the total + balance for the specified account(s) and period. + - ``ODOO.FISCALYEAR.START(day)``: Returns the starting date of + the fiscal year encompassing the provided date. + - ``ODOO.FISCALYEAR.END(day)``: Returns the ending date of the + fiscal year encompassing the provided date. + - ``ODOO.ACCOUNT.GROUP(type)``: Returns the account ids of a + given group where type should be a value of the + ``account_type`` field of ``account.account`` model. + (``income``, ``asset_receivable``, etc.) + +**Create a new dynamic spreadsheet from pivot** +----------------------------------------------- + +- Go to any pivot +- Press on insert button +- Select the dynamic option and set a number of rows + +A new table that will be updated with the actual or filtered values will +be added. + +- Note: When a pivot has multiple levels of aggrupations in the rows, + the number of rows selected will be transfered to each level. + + Example: number of groups -> 2 number of rows -> 3 + + - val1 + + - subval1.1 + - subval1.2 + - subval1.3 + + - val2 + + - subval2.1 + - subval2.2 + - subval2.3 + + - val3 + + - subval3.1 + - subval3.2 + - subval3.3 + +https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/Hhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/rhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ihttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/shttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ahttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/vhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ihttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/shttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/uhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ahttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/lhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/xhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ahttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/phttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/lhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ohttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/fhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/uhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/shttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/:https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/.https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/.https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/fhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ihttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ghttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/uhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/rhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/:https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/:https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ +https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/../static/description/spreadsheet_dynamic_table.gif + +.. |image1| image:: https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/static/description/spreadsheet_create.png +.. |image2| image:: https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/static/description/spreadsheet_edit.png +.. |image3| image:: https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/static/description/o-spreadsheet.png + +Development +=========== + +If you want to develop custom business functions, you can add others, +based on the file +https://github.com/odoo/odoo/blob/16.0/addons/spreadsheet_account/static/src/accounting_functions.js + +Known issues / Roadmap +====================== + +Adding new lines on pivot tables +-------------------------------- + +When we add a pivot table, the number of rows is predefined according to +the current data. + +In order to add new rows, we need to reinsert the pivot table. + +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 +------- + +* CreuBlanca + +Contributors +------------ + +- Enric Tobella +- `Tecnativa `__: + + - Carlos Roca + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/spreadsheet `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/spreadsheet_oca/__init__.py b/spreadsheet_oca/__init__.py new file mode 100644 index 00000000..ada0b87b --- /dev/null +++ b/spreadsheet_oca/__init__.py @@ -0,0 +1,3 @@ +from . import controllers +from . import models +from . import wizards diff --git a/spreadsheet_oca/__manifest__.py b/spreadsheet_oca/__manifest__.py new file mode 100644 index 00000000..be38cd52 --- /dev/null +++ b/spreadsheet_oca/__manifest__.py @@ -0,0 +1,45 @@ +# Copyright 2022 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Spreadsheet Oca", + "summary": """ + Allow to edit spreadsheets""", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "author": "CreuBlanca,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/spreadsheet", + "depends": ["spreadsheet", "base_sparse_field", "bus"], + "data": [ + "security/security.xml", + "security/ir.model.access.csv", + "views/spreadsheet_spreadsheet.xml", + "data/spreadsheet_spreadsheet_import_mode.xml", + "wizards/spreadsheet_select_row_number.xml", + "wizards/spreadsheet_spreadsheet_import.xml", + ], + "demo": ["demo/spreadsheet_spreadsheet.xml"], + "assets": { + "web.assets_backend": [ + "spreadsheet_oca/static/src/spreadsheet/spreadsheet.scss", + "spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml", + "spreadsheet_oca/static/src/spreadsheet/spreadsheet_action.esm.js", + "spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js", + "spreadsheet_oca/static/src/spreadsheet/graph_controller.esm.js", + "spreadsheet_oca/static/src/spreadsheet/list_controller.esm.js", + "spreadsheet_oca/static/src/spreadsheet/list_renderer.esm.js", + ], + "spreadsheet.o_spreadsheet": [ + "spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml", + "spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_renderer.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_controlpanel.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_action.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/odoo_panels.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/chart_panels.esm.js", + "spreadsheet_oca/static/src/spreadsheet/bundle/chart_panel.esm.js", + "spreadsheet_oca/static/src/spreadsheet/utils/dynamic_row_generator.esm.js", + ], + }, +} diff --git a/spreadsheet_oca/controllers/__init__.py b/spreadsheet_oca/controllers/__init__.py new file mode 100644 index 00000000..12a7e529 --- /dev/null +++ b/spreadsheet_oca/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/spreadsheet_oca/controllers/main.py b/spreadsheet_oca/controllers/main.py new file mode 100644 index 00000000..7ea7168f --- /dev/null +++ b/spreadsheet_oca/controllers/main.py @@ -0,0 +1,27 @@ +# Copyright 2024 Tecnativa - Carlos Roca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import json +from io import BytesIO +from zipfile import ZipFile + +from odoo.http import Controller, content_disposition, request, route + + +class SpreadsheetDownloadXLSX(Controller): + @route("/spreadsheet/xlsx", type="http", auth="user", methods=["POST"]) + def download_spreadsheet_xlsx(self, zip_name, files, **kw): + files = json.loads(files) + file_bytes = BytesIO() + with ZipFile(file_bytes, "w") as zip_file: + for file in files: + zip_file.writestr(file["path"], file["content"]) + file_content = file_bytes.getvalue() + return request.make_response( + file_bytes.getvalue(), + [ + ("Content-Length", len(file_content)), + ("Content-Type", "application/vnd.ms-excel"), + ("X-Content-Type-Options", "nosniff"), + ("Content-Disposition", content_disposition(zip_name)), + ], + ) diff --git a/spreadsheet_oca/data/spreadsheet_spreadsheet_import_mode.xml b/spreadsheet_oca/data/spreadsheet_spreadsheet_import_mode.xml new file mode 100644 index 00000000..14335c7f --- /dev/null +++ b/spreadsheet_oca/data/spreadsheet_spreadsheet_import_mode.xml @@ -0,0 +1,39 @@ + + + + new + Create spreadsheet + + + + + add + Add to spreadsheet + + + + + add_sheet + Add sheet to spreadsheet + + + + diff --git a/spreadsheet_oca/demo/demo_spreadsheet.json b/spreadsheet_oca/demo/demo_spreadsheet.json new file mode 100644 index 00000000..fde6c594 --- /dev/null +++ b/spreadsheet_oca/demo/demo_spreadsheet.json @@ -0,0 +1,54 @@ +{ + "version": 12.5, + "sheets": [ + { + "id": "Sheet1", + "name": "Demo Sheet 1", + "colNumber": 26, + "rowNumber": 100, + "rows": {}, + "cols": {}, + "merges": [], + "cells": { + "A1": { "style": 1, "content": "First Value", "border": 1 }, + "A2": { "format": 1, "content": "30.55", "border": 1 }, + "B1": { "style": 1, "content": "Second Value", "border": 1 }, + "B2": { "format": 1, "content": "50", "border": 1 }, + "C1": { "style": 1, "content": "Total", "border": 1 }, + "C2": { "format": 1, "content": "=sum(A2:B2)", "border": 1 }, + "A3": { "border": 2 }, + "B3": { "border": 2 }, + "C3": { "border": 2 }, + "D1": { "border": 3 }, + "D2": { "border": 3 } + }, + "conditionalFormats": [], + "figures": [], + "filterTables": [], + "areGridLinesVisible": true, + "isVisible": true + } + ], + "entities": {}, + "styles": { "1": { "bold": true, "align": "center" } }, + "formats": { "1": "[$$]#,##0.00" }, + "borders": { + "1": { + "top": ["thin", "#000"], + "bottom": ["thin", "#000"], + "left": ["thin", "#000"], + "right": ["thin", "#000"] + }, + "2": { "top": ["thin", "#000"] }, + "3": { "left": ["thin", "#000"] } + }, + "revisionId": "START_REVISION", + "uniqueFigureIds": true, + "odooVersion": 5, + "globalFilters": [], + "pivots": {}, + "pivotNextId": 1, + "lists": {}, + "listNextId": 1, + "chartOdooMenusReferences": {} +} diff --git a/spreadsheet_oca/demo/spreadsheet_spreadsheet.xml b/spreadsheet_oca/demo/spreadsheet_spreadsheet.xml new file mode 100644 index 00000000..cefcc320 --- /dev/null +++ b/spreadsheet_oca/demo/spreadsheet_spreadsheet.xml @@ -0,0 +1,12 @@ + + + + Demo spreadsheet + + + + diff --git a/spreadsheet_oca/i18n/es.po b/spreadsheet_oca/i18n/es.po new file mode 100644 index 00000000..cbab95df --- /dev/null +++ b/spreadsheet_oca/i18n/es.po @@ -0,0 +1,640 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * spreadsheet_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-18 13:08+0000\n" +"PO-Revision-Date: 2024-07-18 15:09+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add date" +msgstr "Añadir fecha" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add relation" +msgstr "Añadir relación" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add_sheet +msgid "Add sheet to spreadsheet" +msgstr "Añadir hoja a la hoja de cálculo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add text" +msgstr "Añadir texto" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#, python-format +msgid "Add to spreadesheet" +msgstr "Añadir a hoja de cálculo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add +#, python-format +msgid "Add to spreadsheet" +msgstr "Añadir a hoja de cálculo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "After next" +msgstr "Después del siguiente" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Automatically filter on the current period" +msgstr "Filtrar automáticamente en el período actual" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Before Previous" +msgstr "Antes del anterior" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__can_be_dynamic +msgid "Can Be Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +#, python-format +msgid "Cancel" +msgstr "Cancelar" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Change name" +msgstr "Cambiar nombre" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__client_id +msgid "Client" +msgstr "Cliente" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__code +msgid "Code" +msgstr "Código" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__commands +msgid "Commands" +msgstr "Comandos" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Comparisons in pivot are not supprted" +msgstr "Las comparaciones en la vista pivot no están soportadas" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Confirm" +msgstr "Confirmar" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__contributor_ids +msgid "Contributors" +msgstr "Colaboradores" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_new +msgid "Create spreadsheet" +msgstr "Crear hoja de cálculo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__data +msgid "Data" +msgstr "Datos" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__datasource_name +msgid "Datasource Name" +msgstr "Nombre de datos" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Default value" +msgstr "Valor por defecto" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Dimensions" +msgstr "Dimensiones" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Domain" +msgstr "Dominio" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Download XLSX" +msgstr "Descargar XLSX" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Duplicated groupbys in pivot are not supprted" +msgstr "Las agrupaciones duplicadas en la vista pivot no están soportadas" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "Dynamic" +msgstr "Dinámico" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_tree_view +msgid "Edit" +msgstr "Editar" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Edit domain" +msgstr "Editar dominio" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "File" +msgstr "Archivo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__filename +msgid "Filename" +msgstr "Nombre de archivo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Filters" +msgstr "Filtros" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__group_ids +msgid "Group" +msgstr "Agrupado por" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__id +msgid "ID" +msgstr "ID" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__import_data +msgid "Import Data" +msgstr "Importar datos" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import_mode +msgid "Import Mode" +msgstr "Modo de importación" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_import_act_window +msgid "Import Pivot" +msgstr "Importar Pivot" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import +msgid "Import data to spreadsheet" +msgstr "Importar datos a hoja de cálculo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert dynamic pivot" +msgstr "Insertar pivot dinámica" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert pivot" +msgstr "Insertar pivot" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__is_tree +msgid "Is Tree" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Label" +msgstr "Etiqueta" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_uid +msgid "Last Updated by" +msgstr "Última modificación por" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Last updated at" +msgstr "Última Actualización el" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Link to Odoo menu" +msgstr "Enlazar al menú de Odoo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "List name" +msgstr "Lista de nombres" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_manager +msgid "Manager" +msgstr "Administrador" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Measures" +msgstr "Medidas" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode_id +msgid "Mode" +msgstr "Modo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__model +#, python-format +msgid "Model" +msgstr "Modelo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Month" +msgstr "Mes" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__name +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +msgid "Name" +msgstr "Nombre" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Next" +msgstr "Siguiente" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__next_revision_id +msgid "Next Revision" +msgstr "Siguiente revisión" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__number_of_rows +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__number_of_rows +msgid "Number Of Rows" +msgstr "Número de filas" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +msgid "OK" +msgstr "Vale" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__owner_id +msgid "Owner" +msgstr "Propietario" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Pivot name" +msgstr "Nombre de pivot" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Previous" +msgstr "Anterior" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Quarter" +msgstr "Trimestre" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__reader_ids +msgid "Readers" +msgstr "Lectores" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Refresh all data" +msgstr "Actualizar todos los datos" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Related model" +msgstr "Modelo relacionado" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Relative Period" +msgstr "Periodo relativo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Remove" +msgstr "Eliminar" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__res_id +msgid "Res" +msgstr "Res" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Save" +msgstr "Guardar" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_select_row_number +msgid "Select number of rows to duplicate row" +msgstr "Seleccione el número de filas a duplicar" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Select the quantity of rows" +msgstr "Seleccione la cantidad de filas" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__sequence +msgid "Sequence" +msgstr "Secuencia" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__server_revision_id +msgid "Server Revision" +msgstr "Revisión del servidor" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Sorting" +msgstr "Ordenando" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__spreadsheet_id +#: model:ir.module.category,name:spreadsheet_oca.module_category_spreedsheet +msgid "Spreadsheet" +msgstr "Hoja de cálculo" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_oca_revision +msgid "Spreadsheet Oca Revision" +msgstr "Revisión de hoja de cálculo OCA" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_raw +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_raw +msgid "Spreadsheet Raw" +msgstr "Hoja de cálculo Raw" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_revision_ids +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_revision_ids +msgid "Spreadsheet Revision" +msgstr "Revisión de hoja de cálculo" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_abstract +msgid "Spreadsheet abstract for inheritance" +msgstr "Hoja de cálculo abstracta para herencia" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_act_window +#: model:ir.ui.menu,name:spreadsheet_oca.spreadsheet_spreadsheet_menu +msgid "Spreadsheets" +msgstr "Hojas de cálculo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Stacked" +msgstr "Apilados" + +#. module: spreadsheet_oca +#: model:ir.model.fields,help:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "" +"This field allows you to generate tables that are updated with the filters " +"set in the spreadsheets." +msgstr "" +"Este campo permite generar tablas que se actualizan con los filtros " +"establecidos en las hojas de cálculo." + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Time range" +msgstr "Intervalo de tiempo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__type +msgid "Type" +msgstr "Tipo" + +#. module: spreadsheet_oca +#. odoo-javascript +#. odoo-python +#: code:addons/spreadsheet_oca/models/spreadsheet_spreadsheet.py:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Unnamed" +msgstr "Sin nombre" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_user +msgid "User" +msgstr "Usuario" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Year" +msgstr "Año" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "ascending" +msgstr "ascendiendo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "descending" +msgstr "descendiendo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "name is required" +msgstr "el nombre es requerido" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "not updated" +msgstr "no actualizado" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_ir_websocket +msgid "websocket message handling" +msgstr "gestión de mensajes websocket" diff --git a/spreadsheet_oca/i18n/fr_FR.po b/spreadsheet_oca/i18n/fr_FR.po new file mode 100644 index 00000000..7da06aaa --- /dev/null +++ b/spreadsheet_oca/i18n/fr_FR.po @@ -0,0 +1,635 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * spreadsheet_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr_FR\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" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add date" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add relation" +msgstr "" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add_sheet +msgid "Add sheet to spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add text" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#, python-format +msgid "Add to spreadesheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add +#, python-format +msgid "Add to spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "After next" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Automatically filter on the current period" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Before Previous" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__can_be_dynamic +msgid "Can Be Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +#, python-format +msgid "Cancel" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Change name" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__client_id +msgid "Client" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__code +msgid "Code" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__commands +msgid "Commands" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Comparisons in pivot are not supprted" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Confirm" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__contributor_ids +msgid "Contributors" +msgstr "" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_new +msgid "Create spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_uid +msgid "Created by" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_date +msgid "Created on" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__data +msgid "Data" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__datasource_name +msgid "Datasource Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Default value" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Dimensions" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__display_name +msgid "Display Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Domain" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Download XLSX" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Duplicated groupbys in pivot are not supprted" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_tree_view +msgid "Edit" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Edit domain" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "File" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__filename +msgid "Filename" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Filters" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__group_ids +msgid "Group" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__id +msgid "ID" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__import_data +msgid "Import Data" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import_mode +msgid "Import Mode" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_import_act_window +msgid "Import Pivot" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import +msgid "Import data to spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert dynamic pivot" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert pivot" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__is_tree +msgid "Is Tree" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Label" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode____last_update +msgid "Last Modified on" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_date +msgid "Last Updated on" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Last updated at" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Link to Odoo menu" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "List name" +msgstr "" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_manager +msgid "Manager" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Measures" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode_id +msgid "Mode" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__model +#, python-format +msgid "Model" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Month" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__name +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +msgid "Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Next" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__next_revision_id +msgid "Next Revision" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__number_of_rows +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__number_of_rows +msgid "Number Of Rows" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +msgid "OK" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__owner_id +msgid "Owner" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Pivot name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Previous" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Quarter" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__reader_ids +msgid "Readers" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Refresh all data" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Related model" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Relative Period" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Remove" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__res_id +msgid "Res" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Save" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_select_row_number +msgid "Select number of rows to duplicate row" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Select the quantity of rows" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__sequence +msgid "Sequence" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__server_revision_id +msgid "Server Revision" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Sorting" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__spreadsheet_id +#: model:ir.module.category,name:spreadsheet_oca.module_category_spreedsheet +msgid "Spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_oca_revision +msgid "Spreadsheet Oca Revision" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_raw +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_raw +msgid "Spreadsheet Raw" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_revision_ids +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_revision_ids +msgid "Spreadsheet Revision" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_abstract +msgid "Spreadsheet abstract for inheritance" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_act_window +#: model:ir.ui.menu,name:spreadsheet_oca.spreadsheet_spreadsheet_menu +msgid "Spreadsheets" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Stacked" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,help:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "" +"This field allows you to generate tables that are updated with the filters " +"set in the spreadsheets." +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Time range" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__type +msgid "Type" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#. odoo-python +#: code:addons/spreadsheet_oca/models/spreadsheet_spreadsheet.py:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Unnamed" +msgstr "" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_user +msgid "User" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Year" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "ascending" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "descending" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "name is required" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "not updated" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_ir_websocket +msgid "websocket message handling" +msgstr "" diff --git a/spreadsheet_oca/i18n/it.po b/spreadsheet_oca/i18n/it.po new file mode 100644 index 00000000..82adf294 --- /dev/null +++ b/spreadsheet_oca/i18n/it.po @@ -0,0 +1,637 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * spreadsheet_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-06-24 14:35+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 4.17\n" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add date" +msgstr "Aggiungi data" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add relation" +msgstr "Aggiungi relazione" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add_sheet +msgid "Add sheet to spreadsheet" +msgstr "Aggiungi scheda a foglIo di calcolo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add text" +msgstr "Aggiungi testo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#, python-format +msgid "Add to spreadesheet" +msgstr "Aggiungi al foglio di calcolo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add +#, python-format +msgid "Add to spreadsheet" +msgstr "Aggiungi al foglio di calcolo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "After next" +msgstr "Dopo il sucessivo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Automatically filter on the current period" +msgstr "Filtra automaticamente sul periodo attuale" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Before Previous" +msgstr "Prima del precedente" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__can_be_dynamic +msgid "Can Be Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +#, python-format +msgid "Cancel" +msgstr "Annulla" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Change name" +msgstr "Modifica nome" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__client_id +msgid "Client" +msgstr "Client" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__code +msgid "Code" +msgstr "Codice" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__commands +msgid "Commands" +msgstr "Comandi" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Comparisons in pivot are not supprted" +msgstr "Le comparazioni nella vista pivot non sono supportate" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Confirm" +msgstr "Conferma" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__contributor_ids +msgid "Contributors" +msgstr "Contributori" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_new +msgid "Create spreadsheet" +msgstr "Crea foglio di calcolo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__data +msgid "Data" +msgstr "Dati" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__datasource_name +msgid "Datasource Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Default value" +msgstr "Valore predefinito" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Dimensions" +msgstr "Dimensioni" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Domain" +msgstr "Dominio" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Download XLSX" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Duplicated groupbys in pivot are not supprted" +msgstr "Nelle viste pivot Non sono supportati i raggruppamenti duplicati" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_tree_view +msgid "Edit" +msgstr "Modifica" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Edit domain" +msgstr "Modifica dominio" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "File" +msgstr "File" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__filename +msgid "Filename" +msgstr "Nome file" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Filters" +msgstr "Filtri" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__group_ids +msgid "Group" +msgstr "Gruppo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__id +msgid "ID" +msgstr "ID" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__import_data +msgid "Import Data" +msgstr "Importa dati" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import_mode +msgid "Import Mode" +msgstr "Modo importazione" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_import_act_window +msgid "Import Pivot" +msgstr "Importa pivot" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import +msgid "Import data to spreadsheet" +msgstr "Importa dati nel foglio di calcolo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert dynamic pivot" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert pivot" +msgstr "Inserisci pivot" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__is_tree +msgid "Is Tree" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Label" +msgstr "Etichetta" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Last updated at" +msgstr "Ultimo aggiornamento il" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Link to Odoo menu" +msgstr "Collegamento al menu Odoo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "List name" +msgstr "Nome elenco" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_manager +msgid "Manager" +msgstr "Responsabile" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Measures" +msgstr "Misure" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode_id +msgid "Mode" +msgstr "Modo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__model +#, python-format +msgid "Model" +msgstr "Modello" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Month" +msgstr "Mese" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__name +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +msgid "Name" +msgstr "Nome" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Next" +msgstr "Successiva" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__next_revision_id +msgid "Next Revision" +msgstr "Revisione successiva" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__number_of_rows +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__number_of_rows +msgid "Number Of Rows" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +msgid "OK" +msgstr "OK" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__owner_id +msgid "Owner" +msgstr "Proprietario" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Pivot name" +msgstr "Nome pivot" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Previous" +msgstr "Precedente" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Quarter" +msgstr "Trimestre" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__reader_ids +msgid "Readers" +msgstr "Lettori" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Refresh all data" +msgstr "Aggiorna tutti i dati" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Related model" +msgstr "Modello collegato" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Relative Period" +msgstr "Periodo relativo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Remove" +msgstr "Rimuovi" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__res_id +msgid "Res" +msgstr "Res" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Save" +msgstr "Salva" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_select_row_number +msgid "Select number of rows to duplicate row" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Select the quantity of rows" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__sequence +msgid "Sequence" +msgstr "Sequenza" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__server_revision_id +msgid "Server Revision" +msgstr "Revisione server" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Sorting" +msgstr "Ordinamento" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__spreadsheet_id +#: model:ir.module.category,name:spreadsheet_oca.module_category_spreedsheet +msgid "Spreadsheet" +msgstr "Foglio di calcolo" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_oca_revision +msgid "Spreadsheet Oca Revision" +msgstr "Revisione OCA foglio di calcolo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_raw +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_raw +msgid "Spreadsheet Raw" +msgstr "Foglio di calcolo grezzo" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_revision_ids +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_revision_ids +msgid "Spreadsheet Revision" +msgstr "Revisione foglio di calcolo" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_abstract +msgid "Spreadsheet abstract for inheritance" +msgstr "Foglio di calcolo astratto per ereditarietà" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_act_window +#: model:ir.ui.menu,name:spreadsheet_oca.spreadsheet_spreadsheet_menu +msgid "Spreadsheets" +msgstr "Fogli di calcolo" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Stacked" +msgstr "In coda" + +#. module: spreadsheet_oca +#: model:ir.model.fields,help:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "" +"This field allows you to generate tables that are updated with the filters " +"set in the spreadsheets." +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Time range" +msgstr "Intervallo orario" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__type +msgid "Type" +msgstr "Tipo" + +#. module: spreadsheet_oca +#. odoo-javascript +#. odoo-python +#: code:addons/spreadsheet_oca/models/spreadsheet_spreadsheet.py:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Unnamed" +msgstr "Senza nome" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_user +msgid "User" +msgstr "Utente" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Year" +msgstr "Anno" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "ascending" +msgstr "crescente" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "descending" +msgstr "decrescente" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "name is required" +msgstr "è richiesto il nome" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "not updated" +msgstr "non aggiornato" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_ir_websocket +msgid "websocket message handling" +msgstr "gestione messaggio websocket" diff --git a/spreadsheet_oca/i18n/nl.po b/spreadsheet_oca/i18n/nl.po new file mode 100644 index 00000000..5055a8fe --- /dev/null +++ b/spreadsheet_oca/i18n/nl.po @@ -0,0 +1,637 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * spreadsheet_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-10-09 08:25+0000\n" +"Last-Translator: \"Jan Tapper [Onestein]\" \n" +"Language-Team: none\n" +"Language: nl\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: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add date" +msgstr "Datum toevoegen" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add relation" +msgstr "Relatie toevoegen" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add_sheet +msgid "Add sheet to spreadsheet" +msgstr "Blad toevoegen aan spreadsheet" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add text" +msgstr "Tekst toevoegen" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#, python-format +msgid "Add to spreadesheet" +msgstr "Toevoegen aan spreadsheet" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add +#, python-format +msgid "Add to spreadsheet" +msgstr "Toevoegen aan spreadsheet" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "After next" +msgstr "Na volgende" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Automatically filter on the current period" +msgstr "Automatisch filteren op de huidige periode" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Before Previous" +msgstr "Vóór Vorige" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__can_be_dynamic +msgid "Can Be Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +#, python-format +msgid "Cancel" +msgstr "Annuleren" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Change name" +msgstr "Verander naam" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__client_id +msgid "Client" +msgstr "Cliënt" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__code +msgid "Code" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__commands +msgid "Commands" +msgstr "Commando's" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Comparisons in pivot are not supprted" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Confirm" +msgstr "Bevestigen" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__contributor_ids +msgid "Contributors" +msgstr "Bijdragers" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_new +msgid "Create spreadsheet" +msgstr "Spreadsheet maken" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_uid +msgid "Created by" +msgstr "Gemaakt door" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_date +msgid "Created on" +msgstr "Gemaakt op" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__data +msgid "Data" +msgstr "Gegevens" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__datasource_name +msgid "Datasource Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Default value" +msgstr "Standaardwaarde" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Dimensions" +msgstr "Dimensies" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__display_name +msgid "Display Name" +msgstr "Weergavenaam" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Domain" +msgstr "Domein" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Download XLSX" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Duplicated groupbys in pivot are not supprted" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_tree_view +msgid "Edit" +msgstr "Bewerking" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Edit domain" +msgstr "Bewerk domein" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "File" +msgstr "Bestand" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__filename +msgid "Filename" +msgstr "Bestandsnaam" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Filters" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__group_ids +msgid "Group" +msgstr "Groep" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__id +msgid "ID" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__import_data +msgid "Import Data" +msgstr "Gegevens importeren" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import_mode +msgid "Import Mode" +msgstr "Importmodus" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_import_act_window +msgid "Import Pivot" +msgstr "Importeer draaipunt" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import +msgid "Import data to spreadsheet" +msgstr "Gegevens importeren naar spreadsheet" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert dynamic pivot" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert pivot" +msgstr "Draaipunt invoegen" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__is_tree +msgid "Is Tree" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Label" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode____last_update +msgid "Last Modified on" +msgstr "Laatst aangepast op" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_uid +msgid "Last Updated by" +msgstr "Laatst aangepast door" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_date +msgid "Last Updated on" +msgstr "Laatst bijgewerkt op" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Last updated at" +msgstr "Laatst bijgewerkt op" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Link to Odoo menu" +msgstr "Link naar het Odoo-menu" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "List name" +msgstr "Naam van lijst" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_manager +msgid "Manager" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Measures" +msgstr "Afmetingen" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode_id +msgid "Mode" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__model +#, python-format +msgid "Model" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Month" +msgstr "Maand" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__name +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +msgid "Name" +msgstr "Naam" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Next" +msgstr "Volgende" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__next_revision_id +msgid "Next Revision" +msgstr "Volgende revisie" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__number_of_rows +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__number_of_rows +msgid "Number Of Rows" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +msgid "OK" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__owner_id +msgid "Owner" +msgstr "Eigenaar" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Pivot name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Previous" +msgstr "Vorig" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Quarter" +msgstr "Kwartaal" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__reader_ids +msgid "Readers" +msgstr "Lezers" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Refresh all data" +msgstr "Ververs alle gegevens" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Related model" +msgstr "Gerelateerd model" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Relative Period" +msgstr "Relatieve periode" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Remove" +msgstr "Verwijderen" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__res_id +msgid "Res" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Save" +msgstr "Opslaan" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_select_row_number +msgid "Select number of rows to duplicate row" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Select the quantity of rows" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__sequence +msgid "Sequence" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__server_revision_id +msgid "Server Revision" +msgstr "Serverversie" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Sorting" +msgstr "Sortering" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__spreadsheet_id +#: model:ir.module.category,name:spreadsheet_oca.module_category_spreedsheet +msgid "Spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_oca_revision +msgid "Spreadsheet Oca Revision" +msgstr "Spreadsheet Oca-revisie" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_raw +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_raw +msgid "Spreadsheet Raw" +msgstr "Spreadsheet onbewerkt" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_revision_ids +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_revision_ids +msgid "Spreadsheet Revision" +msgstr "Revisie van spreadsheets" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_abstract +msgid "Spreadsheet abstract for inheritance" +msgstr "Spreadsheetsamenvatting voor overerving" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_act_window +#: model:ir.ui.menu,name:spreadsheet_oca.spreadsheet_spreadsheet_menu +msgid "Spreadsheets" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Stacked" +msgstr "Gestapeld" + +#. module: spreadsheet_oca +#: model:ir.model.fields,help:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "" +"This field allows you to generate tables that are updated with the filters " +"set in the spreadsheets." +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Time range" +msgstr "Tijdsbestek" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__type +msgid "Type" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#. odoo-python +#: code:addons/spreadsheet_oca/models/spreadsheet_spreadsheet.py:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Unnamed" +msgstr "Naamloos" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_user +msgid "User" +msgstr "Gebruiker" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Year" +msgstr "Jaar" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "ascending" +msgstr "oplopend" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "descending" +msgstr "aflopend" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "name is required" +msgstr "Naam is vereist" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "not updated" +msgstr "niet geüpdate" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_ir_websocket +msgid "websocket message handling" +msgstr "afhandeling van websocket-berichten" diff --git a/spreadsheet_oca/i18n/spreadsheet_oca.pot b/spreadsheet_oca/i18n/spreadsheet_oca.pot new file mode 100644 index 00000000..b30cd1a2 --- /dev/null +++ b/spreadsheet_oca/i18n/spreadsheet_oca.pot @@ -0,0 +1,648 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * spreadsheet_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add date" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add relation" +msgstr "" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add_sheet +msgid "Add sheet to spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Add text" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#, python-format +msgid "Add to spreadesheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml:0 +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_add +#, python-format +msgid "Add to spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "After next" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Automatically filter on the current period" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Before Previous" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__can_be_dynamic +msgid "Can Be Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +#, python-format +msgid "Cancel" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Change name" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__client_id +msgid "Client" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__code +msgid "Code" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__commands +msgid "Commands" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Comparisons in pivot are not supprted" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Confirm" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__contributor_ids +msgid "Contributors" +msgstr "" + +#. module: spreadsheet_oca +#: model:spreadsheet.spreadsheet.import.mode,name:spreadsheet_oca.spreadsheet_import_mode_new +msgid "Create spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_uid +msgid "Created by" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__create_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__create_date +msgid "Created on" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__data +msgid "Data" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__datasource_name +msgid "Datasource Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Default value" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Dimensions" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__display_name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__display_name +msgid "Display Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Domain" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Download XLSX" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js:0 +#, python-format +msgid "Duplicated groupbys in pivot are not supprted" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "Dynamic" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_tree_view +msgid "Edit" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Edit domain" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "File" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__filename +msgid "Filename" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Filters" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__group_ids +msgid "Group" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__id +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__id +msgid "ID" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__import_data +msgid "Import Data" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import_mode +msgid "Import Mode" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_import_act_window +msgid "Import Pivot" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet_import +msgid "Import data to spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert dynamic pivot" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Insert pivot" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__is_tree +msgid "Is Tree" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Label" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import____last_update +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode____last_update +msgid "Last Modified on" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_uid +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__write_date +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__write_date +msgid "Last Updated on" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Last updated at" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Link to Odoo menu" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "List name" +msgstr "" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_manager +msgid "Manager" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Measures" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__mode_id +msgid "Mode" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__model +#, python-format +msgid "Model" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Month" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__name +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__name +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_form_view +msgid "Name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Next" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__next_revision_id +msgid "Next Revision" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_select_row_number__number_of_rows +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__number_of_rows +msgid "Number Of Rows" +msgstr "" + +#. module: spreadsheet_oca +#: model_terms:ir.ui.view,arch_db:spreadsheet_oca.spreadsheet_spreadsheet_import_form_view +msgid "OK" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__owner_id +msgid "Owner" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Pivot name" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Previous" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Quarter" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__reader_ids +msgid "Readers" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Refresh all data" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Related model" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Relative Period" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Remove" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__res_id +msgid "Res" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Save" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_select_row_number +msgid "Select number of rows to duplicate row" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "Select the quantity of rows" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import_mode__sequence +msgid "Sequence" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__server_revision_id +msgid "Server Revision" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Sorting" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_spreadsheet +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet_import__spreadsheet_id +#: model:ir.module.category,name:spreadsheet_oca.module_category_spreedsheet +msgid "Spreadsheet" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_oca_revision +msgid "Spreadsheet Oca Revision" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_raw +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_raw +msgid "Spreadsheet Raw" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_abstract__spreadsheet_revision_ids +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_spreadsheet__spreadsheet_revision_ids +msgid "Spreadsheet Revision" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_spreadsheet_abstract +msgid "Spreadsheet abstract for inheritance" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.actions.act_window,name:spreadsheet_oca.spreadsheet_spreadsheet_act_window +#: model:ir.ui.menu,name:spreadsheet_oca.spreadsheet_spreadsheet_menu +msgid "Spreadsheets" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Stacked" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,help:spreadsheet_oca.field_spreadsheet_spreadsheet_import__dynamic +msgid "" +"This field allows you to generate tables that are updated with the filters " +"set in the spreadsheets." +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Time range" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model.fields,field_description:spreadsheet_oca.field_spreadsheet_oca_revision__type +msgid "Type" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#. odoo-python +#: code:addons/spreadsheet_oca/models/spreadsheet_spreadsheet.py:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "Unnamed" +msgstr "" + +#. module: spreadsheet_oca +#: model:res.groups,name:spreadsheet_oca.group_user +msgid "User" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js:0 +#, python-format +msgid "Year" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "ascending" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "descending" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml:0 +#, python-format +msgid "name is required" +msgstr "" + +#. module: spreadsheet_oca +#. odoo-javascript +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#: code:addons/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js:0 +#, python-format +msgid "not updated" +msgstr "" + +#. module: spreadsheet_oca +#: model:ir.model,name:spreadsheet_oca.model_ir_websocket +msgid "websocket message handling" +msgstr "" diff --git a/spreadsheet_oca/models/__init__.py b/spreadsheet_oca/models/__init__.py new file mode 100644 index 00000000..60d31886 --- /dev/null +++ b/spreadsheet_oca/models/__init__.py @@ -0,0 +1,5 @@ +from . import spreadsheet_abstract +from . import spreadsheet_spreadsheet +from . import spreadsheet_oca_revision +from . import ir_websocket +from . import spreadsheet_spreadsheet_import_mode diff --git a/spreadsheet_oca/models/ir_websocket.py b/spreadsheet_oca/models/ir_websocket.py new file mode 100644 index 00000000..d1b643ba --- /dev/null +++ b/spreadsheet_oca/models/ir_websocket.py @@ -0,0 +1,66 @@ +# Copyright 2023 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import re + +from odoo import models +from odoo.exceptions import AccessDenied + + +class IrWebsocket(models.AbstractModel): + _inherit = "ir.websocket" + + def _build_bus_channel_list(self, channels): + """ + With this change we are adding an extra layer of security. + Without it, any user was able to sniff how all happened using something like: + + const any_spreadsheet_id = 1234; + const channel = "spreadsheet_oca;spreadsheet.spreadsheet" + + ";" + any_spreadsheet_id; + bus_service.addChannel(channel); + bus_service.addEventListener( + "spreadsheet_oca", + (message) => /* every revision arrives here */ + ) + + """ + if self.env.uid: + # Do not alter original list. + channels = list(channels) + for channel in channels: + if isinstance(channel, str): + match = re.match(r"spreadsheet_oca;(\w+(?:\.\w+)*);(\d+)", channel) + if match: + model_name = match[1] + res_id = int(match[2]) + + # Verify access to the edition channel. + if not self.env.user._is_internal(): + raise AccessDenied() + + if not self.env["ir.model.access"].check( + model_name, "read", raise_exception=False + ): + continue + # If user don't have access to the model, we don't + # even try to read + + document = self.env[model_name].search( + [("id", "=", res_id)], limit=1 + ) + # We do a search in order to apply the access rules. + # We just need to ensure that the user can read it + + if not document.exists(): + continue + + channels.append( + ( + self.env.registry.db_name, + "spreadsheet_oca", + model_name, + res_id, + ) + ) + return super()._build_bus_channel_list(channels) diff --git a/spreadsheet_oca/models/spreadsheet_abstract.py b/spreadsheet_oca/models/spreadsheet_abstract.py new file mode 100644 index 00000000..3c00d04b --- /dev/null +++ b/spreadsheet_oca/models/spreadsheet_abstract.py @@ -0,0 +1,85 @@ +# Copyright 2022 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import json + +from odoo import api, fields, models +from odoo.exceptions import AccessError + + +class SpreadsheetAbstract(models.AbstractModel): + _name = "spreadsheet.abstract" + _description = "Spreadsheet abstract for inheritance" + + name = fields.Char(required=True) + spreadsheet_raw = fields.Serialized() + spreadsheet_revision_ids = fields.One2many( + "spreadsheet.oca.revision", + inverse_name="res_id", + domain=lambda r: [("model", "=", r._name)], + ) + + def get_spreadsheet_data(self): + self.ensure_one() + mode = "normal" + try: + self.check_access_rights("write") + self.check_access_rule("write") + except AccessError: + mode = "readonly" + return { + "name": self.name, + "spreadsheet_raw": self.spreadsheet_raw, + "revisions": [ + dict( + json.loads(revision.commands), + nextRevisionId=revision.next_revision_id, + serverRevisionId=revision.server_revision_id, + ) + for revision in self.spreadsheet_revision_ids + ], + "mode": mode, + } + + def open_spreadsheet(self): + self.ensure_one() + return { + "type": "ir.actions.client", + "tag": "action_spreadsheet_oca", + "params": {"spreadsheet_id": self.id, "model": self._name}, + } + + def send_spreadsheet_message(self, message): + self.ensure_one() + channel = (self.env.cr.dbname, "spreadsheet_oca", self._name, self.id) + message.update({"res_model": self._name, "res_id": self.id}) + if message["type"] in ["REVISION_UNDONE", "REMOTE_REVISION", "REVISION_REDONE"]: + self.env["spreadsheet.oca.revision"].create( + { + "model": self._name, + "res_id": self.id, + "type": message["type"], + "client_id": message.get("clientId"), + "next_revision_id": message["nextRevisionId"], + "server_revision_id": message["serverRevisionId"], + "commands": json.dumps( + self._build_spreadsheet_revision_commands_data(message) + ), + } + ) + self.env["bus.bus"]._sendone(channel, "spreadsheet_oca", message) + return True + + @api.model + def _build_spreadsheet_revision_commands_data(self, message): + """Prepare spreadsheet revision commands data from the message""" + commands = dict(message) + commands.pop("serverRevisionId", None) + commands.pop("nextRevisionId", None) + commands.pop("clientId", None) + return commands + + def write(self, vals): + if "spreadsheet_raw" in vals: + self.spreadsheet_revision_ids.unlink() + return super().write(vals) diff --git a/spreadsheet_oca/models/spreadsheet_oca_revision.py b/spreadsheet_oca/models/spreadsheet_oca_revision.py new file mode 100644 index 00000000..b445b598 --- /dev/null +++ b/spreadsheet_oca/models/spreadsheet_oca_revision.py @@ -0,0 +1,17 @@ +# Copyright 2022 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class SpreadsheetOcaRevision(models.Model): + _name = "spreadsheet.oca.revision" + _description = "Spreadsheet Oca Revision" # TODO + + model = fields.Char(required=True) + res_id = fields.Integer(required=True, index=True) + type = fields.Char() + client_id = fields.Char() + server_revision_id = fields.Char() + next_revision_id = fields.Char() + commands = fields.Char() diff --git a/spreadsheet_oca/models/spreadsheet_spreadsheet.py b/spreadsheet_oca/models/spreadsheet_spreadsheet.py new file mode 100644 index 00000000..88b57380 --- /dev/null +++ b/spreadsheet_oca/models/spreadsheet_spreadsheet.py @@ -0,0 +1,57 @@ +# Copyright 2022 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import base64 +import json + +from odoo import _, api, fields, models + + +class SpreadsheetSpreadsheet(models.Model): + _name = "spreadsheet.spreadsheet" + _inherit = "spreadsheet.abstract" + _description = "Spreadsheet" + + data = fields.Binary() + filename = fields.Char(compute="_compute_filename") + spreadsheet_raw = fields.Serialized( + compute="_compute_spreadsheet_raw", inverse="_inverse_spreadsheet_raw" + ) + owner_id = fields.Many2one( + "res.users", required=True, default=lambda r: r.env.user.id + ) + contributor_ids = fields.Many2many( + "res.users", + relation="spreadsheet_contributor", + column1="spreadsheet_id", + column2="user_id", + string="Contributors", + ) + reader_ids = fields.Many2many( + "res.users", + relation="spreadsheet_reader", + column1="spreadsheet_id", + column2="user_id", + string="Readers", + ) + + @api.depends("name") + def _compute_filename(self): + for record in self: + record.filename = "%s.json" % (self.name or _("Unnamed")) + + @api.depends("data") + def _compute_spreadsheet_raw(self): + for dashboard in self: + if dashboard.data: + dashboard.spreadsheet_raw = json.loads( + base64.decodebytes(dashboard.data).decode("UTF-8") + ) + else: + dashboard.spreadsheet_raw = {} + + def _inverse_spreadsheet_raw(self): + for record in self: + record.data = base64.encodebytes( + json.dumps(record.spreadsheet_raw).encode("UTF-8") + ) diff --git a/spreadsheet_oca/models/spreadsheet_spreadsheet_import_mode.py b/spreadsheet_oca/models/spreadsheet_spreadsheet_import_mode.py new file mode 100644 index 00000000..6bbad836 --- /dev/null +++ b/spreadsheet_oca/models/spreadsheet_spreadsheet_import_mode.py @@ -0,0 +1,16 @@ +# Copyright 2022 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class SpreadsheetSpreadsheetImportMode(models.Model): + _name = "spreadsheet.spreadsheet.import.mode" + _description = "Import Mode" + _order = "sequence asc, id" + _rec_name = "name" + + sequence = fields.Integer(default=20) + name = fields.Char(required=True, translate=True) + code = fields.Char(required=True) + group_ids = fields.Many2many("res.groups") diff --git a/spreadsheet_oca/pyproject.toml b/spreadsheet_oca/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/spreadsheet_oca/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/spreadsheet_oca/readme/CONTRIBUTORS.md b/spreadsheet_oca/readme/CONTRIBUTORS.md new file mode 100644 index 00000000..0e0bfeaa --- /dev/null +++ b/spreadsheet_oca/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Enric Tobella +- [Tecnativa](https://www.tecnativa.com): + - Carlos Roca diff --git a/spreadsheet_oca/readme/DESCRIPTION.md b/spreadsheet_oca/readme/DESCRIPTION.md new file mode 100644 index 00000000..afee06c5 --- /dev/null +++ b/spreadsheet_oca/readme/DESCRIPTION.md @@ -0,0 +1,5 @@ +This module adds a functionality for adding and editing Spreadsheets +using Odoo CE. + +It is an alternative to the proprietary module `spreadsheet_edition` of +Odoo Enterprise Edition. diff --git a/spreadsheet_oca/readme/DEVELOP.md b/spreadsheet_oca/readme/DEVELOP.md new file mode 100644 index 00000000..0afb4a08 --- /dev/null +++ b/spreadsheet_oca/readme/DEVELOP.md @@ -0,0 +1,3 @@ +If you want to develop custom business functions, you can add others, +based on the file + diff --git a/spreadsheet_oca/readme/ROADMAP.md b/spreadsheet_oca/readme/ROADMAP.md new file mode 100644 index 00000000..df941c4d --- /dev/null +++ b/spreadsheet_oca/readme/ROADMAP.md @@ -0,0 +1,6 @@ +## Adding new lines on pivot tables + +When we add a pivot table, the number of rows is predefined according to +the current data. + +In order to add new rows, we need to reinsert the pivot table. diff --git a/spreadsheet_oca/readme/USAGE.md b/spreadsheet_oca/readme/USAGE.md new file mode 100644 index 00000000..0e7073f0 --- /dev/null +++ b/spreadsheet_oca/readme/USAGE.md @@ -0,0 +1,69 @@ +## **Create a new spreadsheet** + +- Go to 'Spreadsheet' menu +- Click on 'Create' +- Put a name, then click on the "Edit" button + +![](../static/description/spreadsheet_create.png) + +- At this point you switch to spreadsheet editing mode. The editor is + named `o-spreadsheet` and looks like another common spreadsheet web + editors. (OnlyOffice, Ethercalc, Google Sheets (non-free)). + +![](../static/description/spreadsheet_edit.png) + +- You can use common functions `SUM()`, `AVERAGE()`, etc. in the cells. + For a complete list of functions and their syntax, Refer to the + documentation or go to + and click on "Insert \> + Function". + +![](../static/description/o-spreadsheet.png) + +- Note: Business Odoo module can add "business functions". This is + currently the case for the accounting module, which adds the following + features: + + > - `ODOO.CREDIT(account_codes, date_range)`: Get the total credit for + > the specified account(s) and period. + > - `ODOO.DEBIT(account_codes, date_range)`: Get the total debit for + > the specified account(s) and period. + > - `ODOO.BALANCE(account_codes, date_range)`: Get the total balance + > for the specified account(s) and period. + > - `ODOO.FISCALYEAR.START(day)`: Returns the starting date of the + > fiscal year encompassing the provided date. + > - `ODOO.FISCALYEAR.END(day)`: Returns the ending date of the fiscal + > year encompassing the provided date. + > - `ODOO.ACCOUNT.GROUP(type)`: Returns the account ids of a given + > group where type should be a value of the `account_type` field of + > `account.account` model. (`income`, `asset_receivable`, etc.) + +## **Create a new dynamic spreadsheet from pivot** + +- Go to any pivot +- Press on insert button +- Select the dynamic option and set a number of rows + +A new table that will be updated with the actual or filtered values will +be added. + +- Note: When a pivot has multiple levels of aggrupations in the rows, + the number of rows selected will be transfered to each level. + + Example: number of groups -\> 2 number of rows -\> 3 + + - val1 + - subval1.1 + - subval1.2 + - subval1.3 + - val2 + - subval2.1 + - subval2.2 + - subval2.3 + - val3 + - subval3.1 + - subval3.2 + - subval3.3 + +Here is a visual exaple of use: .. figure:: +../static/description/spreadsheet_dynamic_table.gif diff --git a/spreadsheet_oca/security/ir.model.access.csv b/spreadsheet_oca/security/ir.model.access.csv new file mode 100644 index 00000000..f25d2e12 --- /dev/null +++ b/spreadsheet_oca/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_spreadsheet_spreadsheet,access_spreadsheet_spreadsheet,model_spreadsheet_spreadsheet,group_user,1,1,1,1 +access_spreadsheet_oca_revision,access_spreadsheet_oca_revision,model_spreadsheet_oca_revision,base.group_user,1,1,1,1 +spreadsheet_oca.access_spreadsheet_spreadsheet_import,access_spreadsheet_spreadsheet_import,spreadsheet_oca.model_spreadsheet_spreadsheet_import,base.group_user,1,1,1,1 +access_spreadsheet_import_mode,access_spreadsheet_oca_revision,model_spreadsheet_spreadsheet_import_mode,base.group_user,1,0,0,0 +access_spreadsheet_select_row_number,access_spreadsheet_select_row_number,model_spreadsheet_select_row_number,base.group_user,1,1,1,1 diff --git a/spreadsheet_oca/security/security.xml b/spreadsheet_oca/security/security.xml new file mode 100644 index 00000000..3b9abdc7 --- /dev/null +++ b/spreadsheet_oca/security/security.xml @@ -0,0 +1,65 @@ + + + + + + Spreadsheet + 99 + + + User + + + + Manager + + + + + + Spreadsheet Owner + + + [('owner_id','=', user.id)] + + + Spreadsheet Contributor + + + [('contributor_ids','=', user.id)] + + + + + Spreadsheet Reader + + + [('reader_ids','=', user.id)] + + + + + + Spreadsheet Manager + + + [(1,'=', 1)] + + + Spreadsheet Import mode + + [('group_ids','in', user.groups_id.ids)] + + diff --git a/spreadsheet_oca/static/description/icon.png b/spreadsheet_oca/static/description/icon.png new file mode 100644 index 00000000..34b37aba Binary files /dev/null and b/spreadsheet_oca/static/description/icon.png differ diff --git a/spreadsheet_oca/static/description/icon.svg b/spreadsheet_oca/static/description/icon.svg new file mode 100644 index 00000000..ba496774 --- /dev/null +++ b/spreadsheet_oca/static/description/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/spreadsheet_oca/static/description/index.html b/spreadsheet_oca/static/description/index.html new file mode 100644 index 00000000..17637bc5 --- /dev/null +++ b/spreadsheet_oca/static/description/index.html @@ -0,0 +1,543 @@ + + + + + +Spreadsheet Oca + + + +
+

Spreadsheet Oca

+ + +

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

+

This module adds a functionality for adding and editing Spreadsheets +using Odoo CE.

+

It is an alternative to the proprietary module spreadsheet_edition +of Odoo Enterprise Edition.

+

Table of contents

+ +
+

Usage

+
+

Create a new spreadsheet

+
    +
  • Go to ‘Spreadsheet’ menu
  • +
  • Click on ‘Create’
  • +
  • Put a name, then click on the “Edit” button
  • +
+

image1

+
    +
  • At this point you switch to spreadsheet editing mode. The editor is +named o-spreadsheet and looks like another common spreadsheet web +editors. (OnlyOffice, Ethercalc, Google Sheets (non-free)).
  • +
+

image2

+ +

image3

+
    +
  • Note: Business Odoo module can add “business functions”. This is +currently the case for the accounting module, which adds the +following features:

    +
    +
      +
    • ODOO.CREDIT(account_codes, date_range): Get the total +credit for the specified account(s) and period.
    • +
    • ODOO.DEBIT(account_codes, date_range): Get the total debit +for the specified account(s) and period.
    • +
    • ODOO.BALANCE(account_codes, date_range): Get the total +balance for the specified account(s) and period.
    • +
    • ODOO.FISCALYEAR.START(day): Returns the starting date of +the fiscal year encompassing the provided date.
    • +
    • ODOO.FISCALYEAR.END(day): Returns the ending date of the +fiscal year encompassing the provided date.
    • +
    • ODOO.ACCOUNT.GROUP(type): Returns the account ids of a +given group where type should be a value of the +account_type field of account.account model. +(income, asset_receivable, etc.)
    • +
    +
    +
  • +
+
+
+

Create a new dynamic spreadsheet from pivot

+
    +
  • Go to any pivot
  • +
  • Press on insert button
  • +
  • Select the dynamic option and set a number of rows
  • +
+

A new table that will be updated with the actual or filtered values will +be added.

+
    +
  • Note: When a pivot has multiple levels of aggrupations in the rows, +the number of rows selected will be transfered to each level.

    +

    Example: number of groups -> 2 number of rows -> 3

    +
      +
    • val1
        +
      • subval1.1
      • +
      • subval1.2
      • +
      • subval1.3
      • +
      +
    • +
    • val2
        +
      • subval2.1
      • +
      • subval2.2
      • +
      • subval2.3
      • +
      +
    • +
    • val3
        +
      • subval3.1
      • +
      • subval3.2
      • +
      • subval3.3
      • +
      +
    • +
    +
  • +
+

https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/Hhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/rhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ihttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/shttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ahttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/vhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ihttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/shttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/uhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ahttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/lhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/xhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ahttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/phttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/lhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ohttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/fhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/uhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/shttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/:https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/.https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/.https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/fhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ihttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ghttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/uhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/rhttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ehttps://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/:https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/:https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/ +https://raw.githubusercontent.com/OCA/spreadsheet/17.0/spreadsheet_oca/../static/description/spreadsheet_dynamic_table.gif

+
+
+
+

Development

+

If you want to develop custom business functions, you can add others, +based on the file +https://github.com/odoo/odoo/blob/16.0/addons/spreadsheet_account/static/src/accounting_functions.js

+
+
+

Known issues / Roadmap

+
+

Adding new lines on pivot tables

+

When we add a pivot table, the number of rows is predefined according to +the current data.

+

In order to add new rows, we need to reinsert the pivot table.

+
+
+
+

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

+
    +
  • CreuBlanca
  • +
+
+
+

Contributors

+
    +
  • Enric Tobella
  • +
  • Tecnativa:
      +
    • Carlos Roca
    • +
    +
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

This module is part of the OCA/spreadsheet project on GitHub.

+

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

+
+
+
+ + diff --git a/spreadsheet_oca/static/description/o-spreadsheet.png b/spreadsheet_oca/static/description/o-spreadsheet.png new file mode 100644 index 00000000..5d8c9e28 Binary files /dev/null and b/spreadsheet_oca/static/description/o-spreadsheet.png differ diff --git a/spreadsheet_oca/static/description/spreadsheet_create.png b/spreadsheet_oca/static/description/spreadsheet_create.png new file mode 100644 index 00000000..7e94ba1d Binary files /dev/null and b/spreadsheet_oca/static/description/spreadsheet_create.png differ diff --git a/spreadsheet_oca/static/description/spreadsheet_dynamic_table.gif b/spreadsheet_oca/static/description/spreadsheet_dynamic_table.gif new file mode 100644 index 00000000..2beb7324 Binary files /dev/null and b/spreadsheet_oca/static/description/spreadsheet_dynamic_table.gif differ diff --git a/spreadsheet_oca/static/description/spreadsheet_edit.png b/spreadsheet_oca/static/description/spreadsheet_edit.png new file mode 100644 index 00000000..e4a57314 Binary files /dev/null and b/spreadsheet_oca/static/description/spreadsheet_edit.png differ diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/chart_panel.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/chart_panel.esm.js new file mode 100644 index 00000000..dc422f8d --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/chart_panel.esm.js @@ -0,0 +1,43 @@ +/** @odoo-module */ + +import { patch } from "@web/core/utils/patch"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +const { chartRegistry } = spreadsheet.registries; + +const { ChartPanel } = spreadsheet.components; +export function isOdooKey(code) { + return code.startsWith("odoo_"); +} + +patch(ChartPanel.prototype, { + get chartTypes() { + return this.filterChartTypes(isOdooKey(this.getChartDefinition().type)); + }, + + filterChartTypes(isOdoo) { + var result = {}; + for (const key of chartRegistry.getKeys()) { + if ((isOdoo && isOdooKey(key)) || (!isOdoo && !isOdooKey(key))) { + result[key] = chartRegistry.get(key).name; + } + } + return result; + }, + onTypeChange(type) { + if (isOdooKey(this.getChartDefinition().type)) { + const definition = { + stacked: false, + verticalAxisPosition: "left", + ...this.env.model.getters.getChartDefinition(this.figureId), + type, + }; + this.env.model.dispatch("UPDATE_CHART", { + definition, + id: this.figureId, + sheetId: this.env.model.getters.getActiveSheetId(), + }); + } else { + this._super(type); + } + }, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/chart_panels.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/chart_panels.esm.js new file mode 100644 index 00000000..c3cc1c24 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/chart_panels.esm.js @@ -0,0 +1,73 @@ +/** @odoo-module */ + +import { Domain } from "@web/core/domain"; +import { Many2OneField } from "@web/views/fields/many2one/many2one_field"; +import { patch } from "@web/core/utils/patch"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +import { useService } from "@web/core/utils/hooks"; + +const { + LineBarPieConfigPanel, + ScorecardChartConfigPanel, + GaugeChartConfigPanel, +} = spreadsheet.components; + +const menuChartProps = { + setup() { + this._super.apply(this, arguments); + this.menus = useService("menu"); + }, + get menuId() { + const menu = this.env.model.getters.getChartOdooMenu(this.props.figureId); + if (menu) { + return [menu.id, menu.name]; + } + return false; + }, + updateMenu(menuId) { + if (!menuId) { + this.env.model.dispatch("LINK_ODOO_MENU_TO_CHART", { + chartId: this.props.figureId, + odooMenuId: false, + }); + return; + } + const menu = this.env.model.getters.getIrMenu(menuId[0]); + this.env.model.dispatch("LINK_ODOO_MENU_TO_CHART", { + chartId: this.props.figureId, + odooMenuId: menu.xmlid || menu.id, + }); + }, + get record() { + const menus = this.menus + .getAll() + .map((menu) => menu.id) + .filter((menuId) => menuId !== "root"); + return { + getFieldDomain: function () { + return new Domain([["id", "in", menus]]); + }, + getFieldContext: function () { + return {}; + }, + }; + }, +}; + +patch(LineBarPieConfigPanel.prototype, menuChartProps); +LineBarPieConfigPanel.components = { + ...LineBarPieConfigPanel.components, + Many2OneField, +}; + +patch(ScorecardChartConfigPanel.prototype, menuChartProps); +ScorecardChartConfigPanel.components = { + ...ScorecardChartConfigPanel.components, + Many2OneField, +}; + +patch(GaugeChartConfigPanel.prototype, menuChartProps); +GaugeChartConfigPanel.components = { + ...GaugeChartConfigPanel.components, + Many2OneField, +}; diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js new file mode 100644 index 00000000..3fdca888 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/filter.esm.js @@ -0,0 +1,187 @@ +/** @odoo-module **/ + +import { Component, onWillStart, useState } from "@odoo/owl"; +import { _lt, _t } from "@web/core/l10n/translation"; + +import { FilterValue } from "@spreadsheet/global_filters/components/filter_value/filter_value"; +import { ModelFieldSelector } from "@web/core/model_field_selector/model_field_selector"; +import { ModelSelector } from "@web/core/model_selector/model_selector"; +import { RELATIVE_DATE_RANGE_TYPES } from "@spreadsheet/helpers/constants"; +import { globalFiltersFieldMatchers } from "@spreadsheet/global_filters/plugins/global_filters_core_plugin"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +import { useService } from "@web/core/utils/hooks"; + +const { topbarMenuRegistry } = spreadsheet.registries; +const uuidGenerator = new spreadsheet.helpers.UuidGenerator(); + +topbarMenuRegistry.add("file", { name: _t("File"), sequence: 10 }); +topbarMenuRegistry.addChild("filters", ["file"], { + name: _t("Filters"), + sequence: 70, + action: (env) => env.openSidePanel("FilterPanel", {}), +}); +topbarMenuRegistry.addChild("save", ["file"], { + name: _t("Save"), + // Description: "Ctrl+S", // This is not working, so removing it from the view for now... + sequence: 10, + action: (env) => env.saveSpreadsheet(), +}); +topbarMenuRegistry.addChild("download", ["file"], { + name: _t("Download XLSX"), + sequence: 20, + action: (env) => env.downloadAsXLXS(), +}); + +const { sidePanelRegistry } = spreadsheet.registries; + +export class FilterPanel extends Component { + onEditFilter(filter) { + this.env.openSidePanel("EditFilterPanel", { filter }); + } + onAddFilter(type) { + this.env.openSidePanel("EditFilterPanel", { filter: { type: type } }); + } +} + +FilterPanel.template = "spreadsheet_oca.FilterPanel"; +FilterPanel.components = { + FilterValue, +}; + +sidePanelRegistry.add("FilterPanel", { + title: "Filters", + Body: FilterPanel, +}); + +export class EditFilterPanel extends Component { + setup() { + this.filterId = this.props.filter; + this.orm = useService("orm"); + this.state = useState({ + label: this.props.filter.label, + type: this.props.filter.type, + defaultValue: this.props.filter.defaultValue, + defaultsToCurrentPeriod: this.props.filter.defaultsToCurrentPeriod, + rangeType: this.props.filter.rangeType || "year", + modelName: { technical: this.props.filter.modelName, label: null }, + objects: {}, + }); + this.relativeDateRangeTypes = RELATIVE_DATE_RANGE_TYPES; + onWillStart(this.willStart.bind(this)); + } + async willStart() { + if (this.state.modelName.technical !== undefined) { + const modelLabel = await this.orm.call("ir.model", "display_name_for", [ + [this.state.modelName.technical], + ]); + this.state.modelName.label = modelLabel[0] && modelLabel[0].display_name; + } + var ModelFields = []; + for (var [objectType, objectClass] of Object.entries( + globalFiltersFieldMatchers + )) { + for (const objectId of objectClass.geIds()) { + var fields = objectClass.getFields(objectId); + this.state.objects[objectType + "_" + objectId] = { + id: objectType + "_" + objectId, + objectId: objectId, + name: objectClass.getDisplayName(objectId), + tag: await objectClass.getTag(objectId), + fieldMatch: + objectClass.getFieldMatching(objectId, this.props.filter.id) || {}, + fields: fields, + type: objectType, + model: objectClass.getModel(objectId), + }; + ModelFields.push(fields); + } + } + this.models = [ + ...new Set( + ModelFields.map((field_items) => Object.values(field_items)) + .flat() + .filter((field) => field.relation) + .map((field) => field.relation) + ), + ]; + } + get dateRangeTypes() { + return [ + { type: "year", description: _t("Year") }, + { type: "quarter", description: _t("Quarter") }, + { type: "month", description: _t("Month") }, + { type: "relative", description: _t("Relative Period") }, + ]; + } + get dateOffset() { + return [ + { value: 0, name: "" }, + { value: -1, name: _lt("Previous") }, + { value: -2, name: _lt("Before Previous") }, + { value: 1, name: _lt("Next") }, + { value: 2, name: _lt("After next") }, + ]; + } + onChangeFieldMatchOffset(object, ev) { + this.state.objects[object.id].fieldMatch.offset = parseInt( + ev.target.value, + 10 + ); + } + onModelSelected(ev) { + this.state.modelName.technical = ev.technical; + this.state.modelName.label = ev.label; + } + onDateRangeChange(ev) { + this.state.rangeType = ev.target.value; + } + onSave() { + const action = this.props.filter.id + ? "EDIT_GLOBAL_FILTER" + : "ADD_GLOBAL_FILTER"; + this.env.openSidePanel("FilterPanel", {}); + var filter = { + id: this.props.filter.id || uuidGenerator.uuidv4(), + type: this.state.type, + label: this.state.label, + defaultValue: this.state.defaultValue, + rangeType: this.state.rangeType, + defaultsToCurrentPeriod: this.state.defaultsToCurrentPeriod, + modelName: this.state.modelName.technical, + }; + var filterMatching = {}; + Object.values(this.state.objects).forEach((object) => { + filterMatching[object.type] = filterMatching[object.type] || {}; + filterMatching[object.type][object.objectId] = { ...object.fieldMatch }; + }); + this.env.model.dispatch(action, { + id: filter.id, + filter, + ...filterMatching, + }); + + this.env.openSidePanel("FilterPanel", {}); + } + onCancel() { + this.env.openSidePanel("FilterPanel", {}); + } + onRemove() { + if (this.props.filter.id) { + this.env.model.dispatch("REMOVE_GLOBAL_FILTER", { + id: this.props.filter.id, + }); + } + this.env.openSidePanel("FilterPanel", {}); + } + onFieldMatchUpdate(object, name) { + this.state.objects[object.id].fieldMatch.chain = name; + } +} + +EditFilterPanel.template = "spreadsheet_oca.EditFilterPanel"; +EditFilterPanel.components = { ModelSelector, ModelFieldSelector }; + +sidePanelRegistry.add("EditFilterPanel", { + title: "Edit Filter", + Body: EditFilterPanel, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js new file mode 100644 index 00000000..f2d48afc --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/filter_panel_datasources.esm.js @@ -0,0 +1,264 @@ +/** @odoo-module **/ + +import { Component, onWillStart, onWillUpdateProps } from "@odoo/owl"; +import { Domain } from "@web/core/domain"; +import { DomainSelector } from "@web/core/domain_selector/domain_selector"; +import { DomainSelectorDialog } from "@web/core/domain_selector_dialog/domain_selector_dialog"; +import { _t } from "@web/core/l10n/translation"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +import { formatDateTime } from "@web/core/l10n/dates"; +import { useService } from "@web/core/utils/hooks"; +import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog"; +import { makeDynamicRows } from "../utils/dynamic_row_generator.esm"; + +const { sidePanelRegistry, topbarMenuRegistry } = spreadsheet.registries; +const { createFullMenuItem } = spreadsheet.helpers; + +topbarMenuRegistry.addChild("data_sources", ["data"], (env) => { + const children = env.model.getters.getPivotIds().map((pivotId, index) => + createFullMenuItem(`data_source_pivot_ ${pivotId}`, { + name: env.model.getters.getPivotDisplayName(pivotId), + sequence: 100, + action: (child_env) => { + child_env.model.dispatch("SELECT_PIVOT", { + pivotId: pivotId, + }); + child_env.openSidePanel("PivotPanel", {}); + }, + icon: "fa fa-table", + separator: index === env.model.getters.getPivotIds().length - 1, + }) + ); + const lists = env.model.getters.getListIds().map((listId, index) => { + return createFullMenuItem(`data_source_list_${listId}`, { + name: env.model.getters.getListDisplayName(listId), + sequence: 1010, + action: (child_env) => { + child_env.model.dispatch("SELECT_ODOO_LIST", { listId: listId }); + child_env.openSidePanel("ListPanel", {}); + }, + icon: "fa fa-list", + separator: index === env.model.getters.getListIds().length - 1, + }); + }); + return children.concat(lists).concat([ + createFullMenuItem(`refresh_all_data`, { + name: _t("Refresh all data"), + sequence: 110, + action: (child_env) => { + child_env.model.dispatch("REFRESH_ALL_DATA_SOURCES"); + }, + separator: true, + }), + ]); +}); + +export class PivotPanelDisplay extends Component { + setup() { + this.dialog = useService("dialog"); + onWillStart(this.modelData.bind(this)); + onWillUpdateProps(this.modelData.bind(this)); + } + async modelData() { + this.PivotDataSource = await this.env.model.getters.getAsyncPivotDataSource( + this.props.pivotId + ); + this.modelLabel = await this.PivotDataSource.getModelLabel(); + } + get domain() { + return new Domain(this.props.pivotDefinition.domain).toString(); + } + get pivotDimensions() { + return [ + ...this.props.pivotDefinition.rowGroupBys, + ...this.props.pivotDefinition.colGroupBys, + ].map((fieldName) => this.PivotDataSource.getFormattedGroupBy(fieldName)); + } + get sortInformation() { + const sortedColumn = this.props.pivotDefinition.sortedColumn; + const orderTranslate = + sortedColumn.order === "asc" ? _t("ascending") : _t("descending"); + const GroupByDisplayLabel = this.PivotDataSource.getGroupByDisplayLabel( + "measure", + sortedColumn.measure + ); + return `${GroupByDisplayLabel} (${orderTranslate})`; + } + get lastUpdate() { + const lastUpdate = this.PivotDataSource.lastUpdate; + if (lastUpdate) { + return formatDateTime(new Date(lastUpdate), { format: "HH:mm:ss" }); + } + return _t("not updated"); + } + editDomain() { + this.dialog.add(DomainSelectorDialog, { + resModel: this.props.pivotDefinition.model, + initialValue: this.domain, + readonly: false, + isDebugMode: Boolean(this.env.debug), + onSelected: this.onSelectDomain.bind(this), + }); + } + onSelectDomain(domain) { + this.env.model.dispatch("UPDATE_ODOO_PIVOT_DOMAIN", { + pivotId: this.props.pivotId, + domain: new Domain(domain).toList(), + }); + } + async insertPivot() { + const datasourceModel = await this.env.model.getters + .getPivotDataSource(this.props.pivotId) + .copyModelWithOriginalDomain(); + const tableStructure = datasourceModel.getTableStructure().export(); + const selectedZone = this.env.model.getters.getSelectedZone(); + this.env.model.dispatch("RE_INSERT_PIVOT", { + id: this.props.pivotId, + col: selectedZone.left, + row: selectedZone.top, + sheetId: this.env.model.getters.getActiveSheetId(), + table: tableStructure, + }); + this.env.model.dispatch("REFRESH_PIVOT", { id: this.props.pivotId }); + } + + async insertDynamicPivot() { + const datasourceModel = await this.env.model.getters + .getPivotDataSource(this.props.pivotId) + .copyModelWithOriginalDomain(); + var { cols, rows, measures } = datasourceModel.getTableStructure().export(); + const number_of_rows = await new Promise((resolve) => { + this.dialog.add( + FormViewDialog, + { + title: this.env._t("Select the quantity of rows"), + resModel: "spreadsheet.select.row.number", + onRecordSaved: async (record) => { + resolve(record.data.number_of_rows); + }, + }, + { onClose: () => resolve(false) } + ); + }); + if (!number_of_rows) { + return; + } + const indentations = rows.map((r) => r.indent); + const max_indentation = Math.max(...indentations); + rows = makeDynamicRows( + this.props.pivotDefinition.rowGroupBys, + number_of_rows, + 1, + max_indentation + ); + const table = { + cols, + rows, + measures, + }; + const selectedZone = this.env.model.getters.getSelectedZone(); + this.env.model.dispatch("RE_INSERT_PIVOT", { + id: this.props.pivotId, + col: selectedZone.left, + row: selectedZone.top, + sheetId: this.env.model.getters.getActiveSheetId(), + table, + }); + this.env.model.dispatch("REFRESH_PIVOT", { id: this.props.pivotId }); + } +} + +PivotPanelDisplay.template = "spreadsheet_oca.PivotPanelDisplay"; +PivotPanelDisplay.components = { + DomainSelector, +}; +PivotPanelDisplay.properties = { + pivotId: String, + pivotDefinition: Object, +}; + +export class PivotPanel extends Component { + get pivotId() { + return this.env.model.getters.getSelectedPivotId(); + } + get pivotDefinition() { + return this.env.model.getters.getPivotDefinition(this.pivotId); + } +} + +PivotPanel.template = "spreadsheet_oca.PivotPanel"; +PivotPanel.components = { + PivotPanelDisplay, +}; + +sidePanelRegistry.add("PivotPanel", { + title: "Pivot table information", + Body: PivotPanel, +}); + +export class ListPanelDisplay extends Component { + setup() { + this.dialog = useService("dialog"); + onWillStart(this.modelData.bind(this)); + onWillUpdateProps(this.modelData.bind(this)); + } + async modelData() { + this.ListDataSource = await this.env.model.getters.getAsyncListDataSource( + this.props.listId + ); + this.modelLabel = await this.ListDataSource.getModelLabel(); + } + get domain() { + return new Domain(this.props.listDefinition.domain).toString(); + } + get lastUpdate() { + const lastUpdate = this.ListDataSource.lastUpdate; + if (lastUpdate) { + return formatDateTime(new Date(lastUpdate), { format: "HH:mm:ss" }); + } + return _t("not updated"); + } + editDomain() { + this.dialog.add(DomainSelectorDialog, { + resModel: this.props.listDefinition.model, + initialValue: this.domain, + readonly: false, + isDebugMode: Boolean(this.env.debug), + onSelected: this.onSelectDomain.bind(this), + }); + } + onSelectDomain(domain) { + this.env.model.dispatch("UPDATE_ODOO_LIST_DOMAIN", { + listId: this.props.listId, + domain: new Domain(domain).toList(), + }); + } +} + +ListPanelDisplay.template = "spreadsheet_oca.ListPanelDisplay"; +ListPanelDisplay.components = { + DomainSelector, +}; +ListPanelDisplay.properties = { + listId: String, + listDefinition: Object, +}; + +export class ListPanel extends Component { + get listId() { + return this.env.model.getters.getSelectedListId(); + } + get listDefinition() { + return this.env.model.getters.getListDefinition(this.listId); + } +} + +ListPanel.template = "spreadsheet_oca.ListPanel"; +ListPanel.components = { + ListPanelDisplay, +}; + +sidePanelRegistry.add("ListPanel", { + title: "List information", + Body: ListPanel, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/odoo_panels.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/odoo_panels.esm.js new file mode 100644 index 00000000..98cf26f0 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/odoo_panels.esm.js @@ -0,0 +1,76 @@ +/** @odoo-module */ + +import { Domain } from "@web/core/domain"; +import { Many2OneField } from "@web/views/fields/many2one/many2one_field"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +import { useService } from "@web/core/utils/hooks"; + +const { chartSidePanelComponentRegistry } = spreadsheet.registries; +const { LineBarPieDesignPanel } = spreadsheet.components; +const { Component } = owl; + +export class OdooPanel extends Component { + setup() { + this.menus = useService("menu"); + } + get menuId() { + const menu = this.env.model.getters.getChartOdooMenu(this.props.figureId); + if (menu) { + return [menu.id, menu.name]; + } + return false; + } + updateMenu(menuId) { + if (!menuId) { + this.env.model.dispatch("LINK_ODOO_MENU_TO_CHART", { + chartId: this.props.figureId, + odooMenuId: false, + }); + return; + } + const menu = this.env.model.getters.getIrMenu(menuId[0]); + this.env.model.dispatch("LINK_ODOO_MENU_TO_CHART", { + chartId: this.props.figureId, + odooMenuId: menu.xmlid || menu.id, + }); + } + get record() { + const menus = this.menus + .getAll() + .map((menu) => menu.id) + .filter((menuId) => menuId !== "root"); + return { + getFieldDomain: function () { + return new Domain([["id", "in", menus]]); + }, + getFieldContext: function () { + return {}; + }, + }; + } +} +OdooPanel.template = "spreadsheet_oca.OdooPanel"; +OdooPanel.components = { Many2OneField }; + +class OdooStackablePanel extends OdooPanel { + onChangeStacked(ev) { + this.props.updateChart(this.props.figureId, { + stacked: ev.target.checked, + }); + } +} +OdooStackablePanel.template = "spreadsheet_oca.OdooStackablePanel"; + +chartSidePanelComponentRegistry + .add("odoo_line", { + configuration: OdooStackablePanel, + design: LineBarPieDesignPanel, + }) + .add("odoo_bar", { + configuration: OdooStackablePanel, + design: LineBarPieDesignPanel, + }) + .add("odoo_pie", { + configuration: OdooPanel, + design: LineBarPieDesignPanel, + }); diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml new file mode 100644 index 00000000..ca01a07a --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet.xml @@ -0,0 +1,575 @@ + + + + +
+ + +
+
+ + + + +
+
+
Pivot name
+ +
+
+
Model
+
()
+
+
+
Domain
+ + +
+
+
Dimensions
+ +
+ +
+
+
Sorting
+
+
+
+
Measures
+ +
+ +
+
+ Last updated at +
+
+ + +
+
+ + + + + + + +
+
+
List name
+ +
+
+
Model
+
()
+
+
+
Domain
+ + +
+
+ Last updated at +
+
+ +
+ +
+
+ +
+
+ + +
+
+
+ + + +
+
+ +
+
+ Label +
+
+ +
+
+
+
Time range
+
+ +
+
+
+
Default value
+
+ + +
+
+ +
+ +
+ +
+
Related model
+
+ +
+
+
+
+ - +
+
+ +
+ +
+ +
+
+
+ + + +
+
+ + + + + + + + + + + + + + + name is required + + + + + + + + + + + + +
+
+
+ + + + + + + + + + +
+
+
+
+ +
+
Link to Odoo menu
+
+ +
+
+
+ + +
+ +
+
+
+ + +
+
Link to Odoo menu
+
+ +
+
+
+
+ + +
+
Link to Odoo menu
+
+ +
+
+
+
+ + +
+
Link to Odoo menu
+
+ +
+
+
+
+ + +
+
Link to Odoo menu
+
+ +
+
+
+
+ + +
+
Link to Odoo menu
+
+ +
+
+
+
+ + diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_action.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_action.esm.js new file mode 100644 index 00000000..5d8e4723 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_action.esm.js @@ -0,0 +1,255 @@ +/** @odoo-module **/ + +import ListDataSource from "@spreadsheet/list/list_data_source"; +import PivotDataSource from "@spreadsheet/pivot/pivot_data_source"; +import { SpreadsheetControlPanel } from "./spreadsheet_controlpanel.esm"; +import { SpreadsheetRenderer } from "./spreadsheet_renderer.esm"; +import { registry } from "@web/core/registry"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +import { useService } from "@web/core/utils/hooks"; +import { makeDynamicRows } from "../utils/dynamic_row_generator.esm"; + +const uuidGenerator = new spreadsheet.helpers.UuidGenerator(); +const actionRegistry = registry.category("actions"); +const { Component, onMounted, onWillStart, useSubEnv } = owl; + +export class ActionSpreadsheetOca extends Component { + setup() { + this.router = useService("router"); + this.orm = useService("orm"); + const params = this.props.action.params || this.props.action.context.params; + this.spreadsheetId = params.spreadsheet_id; + this.model = params.model || "spreadsheet.spreadsheet"; + this.import_data = params.import_data || {}; + onMounted(() => { + this.router.pushState({ + spreadsheet_id: this.spreadsheetId, + model: this.model, + }); + }); + onWillStart(async () => { + this.record = + (await this.orm.call( + this.model, + "get_spreadsheet_data", + [[this.spreadsheetId]], + { context: { bin_size: false } } + )) || {}; + }); + useSubEnv({ + saveRecord: this.saveRecord.bind(this), + importData: this.importData.bind(this), + }); + } + async saveRecord(data) { + if (this.record.mode === "readonly") { + return; + } + if (this.spreadsheetId) { + this.orm.call(this.model, "write", [this.spreadsheetId, data]); + } else { + this.spreadsheetId = await this.orm.call(this.model, "create", [data]); + this.router.pushState({ spreadsheet_id: this.spreadsheetId }); + } + } + + async importDataGraph(spreadsheet_model) { + var sheetId = spreadsheet_model.getters.getActiveSheetId(); + var y = 0; + if (this.import_data.new === undefined && this.import_data.new_sheet) { + sheetId = uuidGenerator.uuidv4(); + spreadsheet_model.dispatch("CREATE_SHEET", { + sheetId, + position: spreadsheet_model.getters.getSheetIds().length, + }); + // We want to open the new sheet + const sheetIdFrom = spreadsheet_model.getters.getActiveSheetId(); + spreadsheet_model.dispatch("ACTIVATE_SHEET", { + sheetIdFrom, + sheetIdTo: sheetId, + }); + } else if (this.import_data.new === undefined) { + // TODO: Add a way to detect the last row total height + } + const dataSourceId = uuidGenerator.uuidv4(); + const definition = { + title: this.import_data.name, + type: "odoo_" + this.import_data.metaData.mode, + background: "#FFFFFF", + stacked: this.import_data.metaData.stacked, + metaData: this.import_data.metaData, + searchParams: this.import_data.searchParams, + dataSourceId: dataSourceId, + legendPosition: "top", + verticalAxisPosition: "left", + }; + spreadsheet_model.dispatch("CREATE_CHART", { + sheetId, + id: dataSourceId, + position: { + x: 0, + y: y, + }, + definition, + }); + } + importCreateOrReuseSheet(spreadsheet_model) { + var sheetId = spreadsheet_model.getters.getActiveSheetId(); + var row = 0; + if (this.import_data.new === undefined && this.import_data.new_sheet) { + sheetId = uuidGenerator.uuidv4(); + spreadsheet_model.dispatch("CREATE_SHEET", { + sheetId, + position: spreadsheet_model.getters.getSheetIds().length, + }); + // We want to open the new sheet + const sheetIdFrom = spreadsheet_model.getters.getActiveSheetId(); + spreadsheet_model.dispatch("ACTIVATE_SHEET", { + sheetIdFrom, + sheetIdTo: sheetId, + }); + } else if (this.import_data.new === undefined) { + row = spreadsheet_model.getters.getNumberRows(sheetId); + var maxcols = spreadsheet_model.getters.getNumberCols(sheetId); + var filled = false; + while (row >= 0) { + for (var col = maxcols; col >= 0; col--) { + if ( + spreadsheet_model.getters.getCell(sheetId, col, row) !== + undefined && + !spreadsheet_model.getters.getCell(sheetId, col, row).isEmpty() + ) { + filled = true; + break; + } + } + if (filled) { + break; + } + row -= 1; + } + row += 1; + } + return { sheetId, row }; + } + async importDataList(spreadsheet_model) { + var { sheetId, row } = this.importCreateOrReuseSheet(spreadsheet_model); + const dataSourceId = uuidGenerator.uuidv4(); + var list_info = { + metaData: { + resModel: this.import_data.metaData.model, + columns: this.import_data.metaData.columns.map((column) => column.name), + fields: this.import_data.metaData.fields, + }, + searchParams: { + domain: this.import_data.metaData.domain, + context: this.import_data.metaData.context, + orderBy: this.import_data.metaData.orderBy, + }, + name: this.import_data.name, + }; + const dataSource = spreadsheet_model.config.dataSources.add( + dataSourceId, + ListDataSource, + list_info + ); + await dataSource.load(); + spreadsheet_model.dispatch("INSERT_ODOO_LIST", { + sheetId, + col: 0, + row: row, + id: spreadsheet_model.getters.getNextListId(), + dataSourceId, + definition: list_info, + linesNumber: this.import_data.dyn_number_of_rows, + columns: this.import_data.metaData.columns, + }); + const columns = []; + for (let col = 0; col < this.import_data.metaData.columns.length; col++) { + columns.push(col); + } + spreadsheet_model.dispatch("AUTORESIZE_COLUMNS", { + sheetId, + cols: columns, + }); + } + async importDataPivot(spreadsheet_model) { + var { sheetId, row } = this.importCreateOrReuseSheet(spreadsheet_model); + const dataSourceId = uuidGenerator.uuidv4(); + const colGroupBys = this.import_data.metaData.colGroupBys.concat( + this.import_data.metaData.expandedColGroupBys + ); + const rowGroupBys = this.import_data.metaData.rowGroupBys.concat( + this.import_data.metaData.expandedRowGroupBys + ); + const pivot_info = { + metaData: { + colGroupBys, + rowGroupBys, + activeMeasures: this.import_data.metaData.activeMeasures, + resModel: this.import_data.metaData.resModel, + sortedColumn: this.import_data.metaData.sortedColumn, + }, + searchParams: this.import_data.searchParams, + name: this.import_data.name, + }; + const dataSource = spreadsheet_model.config.dataSources.add( + dataSourceId, + PivotDataSource, + pivot_info + ); + await dataSource.load(); + var { cols, rows, measures } = dataSource.getTableStructure().export(); + if (this.import_data.dyn_number_of_rows) { + const indentations = rows.map((r) => r.indent); + const max_indentation = Math.max(...indentations); + rows = makeDynamicRows( + rowGroupBys, + this.import_data.dyn_number_of_rows, + 1, + max_indentation + ); + } + const table = { + cols, + rows, + measures, + }; + spreadsheet_model.dispatch("INSERT_PIVOT", { + sheetId, + col: 0, + row: row, + id: spreadsheet_model.getters.getNextPivotId(), + table, + dataSourceId, + definition: pivot_info, + }); + const columns = []; + for (let col = 0; col < table.cols[table.cols.length - 1].length; col++) { + columns.push(col); + } + spreadsheet_model.dispatch("AUTORESIZE_COLUMNS", { + sheetId, + cols: columns, + }); + } + async importData(spreadsheet_model) { + if (this.import_data.mode === "pivot") { + await this.importDataPivot(spreadsheet_model); + } + if (this.import_data.mode === "graph") { + await this.importDataGraph(spreadsheet_model); + } + if (this.import_data.mode === "list") { + await this.importDataList(spreadsheet_model); + } + } +} +ActionSpreadsheetOca.template = "spreadsheet_oca.ActionSpreadsheetOca"; +ActionSpreadsheetOca.components = { + SpreadsheetRenderer, + // SpreadsheetControlPanel, +}; +actionRegistry.add("action_spreadsheet_oca", ActionSpreadsheetOca, { + force: true, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_controlpanel.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_controlpanel.esm.js new file mode 100644 index 00000000..37a92b5b --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_controlpanel.esm.js @@ -0,0 +1,31 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; +import { ControlPanel } from "@web/search/control_panel/control_panel"; + +const { useState } = owl; + +export class SpreadsheetName extends Component { + setup() { + this.state = useState({ + name: this.props.name, + }); + } + _onNameChanged(ev) { + if (ev.target.value) { + this.env.saveRecord({ name: ev.target.value }); + } + this.state.name = ev.target.value; + } +} +SpreadsheetName.template = "spreadsheet_oca.SpreadsheetName"; + +export class SpreadsheetControlPanel extends ControlPanel {} +SpreadsheetControlPanel.template = "spreadsheet_oca.SpreadsheetControlPanel"; +SpreadsheetControlPanel.props = { + ...ControlPanel.props, + record: Object, +}; +SpreadsheetControlPanel.components = { + SpreadsheetName, +}; diff --git a/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_renderer.esm.js b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_renderer.esm.js new file mode 100644 index 00000000..66dd7d80 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/bundle/spreadsheet_renderer.esm.js @@ -0,0 +1,167 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; +import { DataSources } from "@spreadsheet/data_sources/data_sources"; +import Dialog from "@web/core/dialog/dialog"; +import { Field } from "@web/views/fields/field"; +import { loadSpreadsheetDependencies } from "@spreadsheet/assets_backend/helpers"; +import { migrate } from "@spreadsheet/o_spreadsheet/migration"; +import * as spreadsheet from "@odoo/o-spreadsheet"; +import { useService } from "@web/core/utils/hooks"; +import { useSetupAction } from "@web/webclient/actions/action_hook"; +import { waitForDataLoaded } from "@spreadsheet/actions/spreadsheet_download_action"; + +const { Spreadsheet, Model } = spreadsheet; +const { useSubEnv, useState, onWillStart } = owl; +const uuidGenerator = new spreadsheet.helpers.UuidGenerator(); + +class SpreadsheetTransportService { + constructor(orm, bus_service, model, res_id) { + this.orm = orm; + this.bus_service = bus_service; + this.model = model; + this.res_id = res_id; + this.channel = "spreadsheet_oca;" + this.model + ";" + this.res_id; + this.bus_service.addChannel(this.channel); + this.bus_service.addEventListener( + "notification", + this.onNotification.bind(this) + ); + this.listeners = []; + } + onNotification({ detail: notifications }) { + for (const { payload, type } of notifications) { + if ( + type === "spreadsheet_oca" && + payload.res_model === this.model && + payload.res_id === this.res_id + ) { + // What shall we do if no callback is defined (empty until onNewMessage...) :/ + for (const { callback } of this.listeners) { + callback(payload); + } + } + } + } + sendMessage(message) { + this.orm.call(this.model, "send_spreadsheet_message", [ + [this.res_id], + message, + ]); + } + onNewMessage(id, callback) { + this.listeners.push({ id, callback }); + } + leave(id) { + this.listeners = this.listeners.filter((listener) => listener.id !== id); + } +} + +export class SpreadsheetRenderer extends Component { + setup() { + this.orm = useService("orm"); + this.bus_service = this.env.services.bus_service; + this.user = useService("user"); + this.ui = useService("ui"); + this.action = useService("action"); + const dataSources = new DataSources(this.env); + this.state = useState({ + dialogDisplayed: false, + dialogTitle: "Spreadsheet", + dialogContent: undefined, + }); + this.confirmDialog = this.closeDialog; + this.spreadsheet_model = new Model( + migrate(this.props.record.spreadsheet_raw), + { + evalContext: { env: this.env, orm: this.orm }, + transportService: new SpreadsheetTransportService( + this.orm, + this.bus_service, + this.props.model, + this.props.res_id + ), + client: { + id: uuidGenerator.uuidv4(), + name: this.user.name, + }, + mode: this.props.record.mode, + dataSources, + }, + this.props.record.revisions + ); + useSubEnv({ + saveSpreadsheet: this.onSpreadsheetSaved.bind(this), + editText: this.editText.bind(this), + askConfirmation: this.askConfirmation.bind(this), + downloadAsXLXS: this.downloadAsXLXS.bind(this), + }); + onWillStart(async () => { + await loadSpreadsheetDependencies(); + await dataSources.waitForAllLoaded(); + await this.env.importData(this.spreadsheet_model); + }); + useSetupAction({ + beforeLeave: () => this.onSpreadsheetSaved(), + }); + dataSources.addEventListener("data-source-updated", () => { + const sheetId = this.spreadsheet_model.getters.getActiveSheetId(); + this.spreadsheet_model.dispatch("EVALUATE_CELLS", { sheetId }); + }); + } + closeDialog() { + this.state.dialogDisplayed = false; + this.state.dialogTitle = "Spreadsheet"; + this.state.dialogContent = undefined; + this.state.dialogHideInputBox = false; + } + onSpreadsheetSaved() { + const data = this.spreadsheet_model.exportData(); + this.env.saveRecord({ spreadsheet_raw: data }); + this.spreadsheet_model.leaveSession(); + } + editText(title, callback, options) { + this.state.dialogContent = options.placeholder; + this.state.dialogTitle = title; + this.state.dialogDisplayed = true; + this.confirmDialog = () => { + callback(this.state.dialogContent); + this.closeDialog(); + }; + } + askConfirmation(content, confirm) { + this.state.dialogContent = content; + this.state.dialogDisplayed = true; + this.state.dialogHideInputBox = true; + this.confirmDialog = () => { + confirm(); + this.closeDialog(); + }; + } + async downloadAsXLXS() { + this.ui.block(); + await waitForDataLoaded(this.spreadsheet_model); + await this.action.doAction({ + type: "ir.actions.client", + tag: "action_download_spreadsheet", + params: { + name: this.props.record.name, + xlsxData: this.spreadsheet_model.exportXLSX(), + }, + }); + this.ui.unblock(); + } +} + +SpreadsheetRenderer.template = "spreadsheet_oca.SpreadsheetRenderer"; +SpreadsheetRenderer.components = { + Spreadsheet, + Field, + Dialog, +}; +SpreadsheetRenderer.props = { + record: Object, + res_id: { type: Number, optional: true }, + model: String, + importData: { type: Function, optional: true }, +}; diff --git a/spreadsheet_oca/static/src/spreadsheet/graph_controller.esm.js b/spreadsheet_oca/static/src/spreadsheet/graph_controller.esm.js new file mode 100644 index 00000000..37959bb7 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/graph_controller.esm.js @@ -0,0 +1,23 @@ +/** @odoo-module **/ +import { GraphController } from "@web/views/graph/graph_controller"; + +import { patch } from "@web/core/utils/patch"; + +patch(GraphController.prototype, { + onSpreadsheetButtonClicked() { + this.actionService.doAction( + "spreadsheet_oca.spreadsheet_spreadsheet_import_act_window", + { + additionalContext: { + default_name: this.model.metaData.title, + default_datasource_name: this.model.metaData.title, + default_import_data: { + mode: "graph", + metaData: JSON.parse(JSON.stringify(this.model.metaData)), + searchParams: JSON.parse(JSON.stringify(this.model.searchParams)), + }, + }, + } + ); + }, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/list_controller.esm.js b/spreadsheet_oca/static/src/spreadsheet/list_controller.esm.js new file mode 100644 index 00000000..28a124f2 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/list_controller.esm.js @@ -0,0 +1,10 @@ +/** @odoo-module **/ +import { ListController } from "@web/views/list/list_controller"; + +import { patch } from "@web/core/utils/patch"; + +patch(ListController.prototype, { + onSpreadsheetButtonClicked() { + this.env.bus.trigger("addListOnSpreadsheet"); + }, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/list_renderer.esm.js b/spreadsheet_oca/static/src/spreadsheet/list_renderer.esm.js new file mode 100644 index 00000000..ace2b3eb --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/list_renderer.esm.js @@ -0,0 +1,58 @@ +/** @odoo-module **/ +import { useBus, useService } from "@web/core/utils/hooks"; +import { ListRenderer } from "@web/views/list/list_renderer"; +import { omit } from "@web/core/utils/objects"; +import { patch } from "@web/core/utils/patch"; + +patch(ListRenderer.prototype, { + setup() { + super.setup(...arguments); + this.userService = useService("user"); + this.actionService = useService("action"); + useBus( + this.env.bus, + "addListOnSpreadsheet", + this.onAddListOnSpreadsheet.bind(this) + ); + }, + onAddListOnSpreadsheet() { + const model = this.env.model.root; + this.actionService.doAction( + "spreadsheet_oca.spreadsheet_spreadsheet_import_act_window", + { + additionalContext: { + default_name: this.env.config.getDisplayName(), + default_datasource_name: this.env.config.getDisplayName(), + default_can_be_dynamic: true, + default_dynamic: true, + default_is_tree: true, + default_number_of_rows: Math.min(model.count, model.limit), + default_import_data: { + mode: "list", + metaData: { + model: model.resModel, + domain: model.domain, + orderBy: model.orderBy, + context: omit( + model.context, + ...Object.keys(this.userService.context) + ), + columns: this.getSpreadsheetColumns(), + fields: model.fields, + name: this.env.config.getDisplayName(), + }, + }, + }, + } + ); + }, + getSpreadsheetColumns() { + const fields = this.env.model.root.fields; + return this.state.columns + .filter( + (col) => col.type === "field" && fields[col.name].type !== "binary" + // We want to avoid binary fields + ) + .map((col) => ({ name: col.name, type: fields[col.name].type })); + }, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js b/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js new file mode 100644 index 00000000..e7af3030 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js @@ -0,0 +1,59 @@ +/** @odoo-module **/ + +import { _lt } from "@web/core/l10n/translation"; +import { PivotController } from "@web/views/pivot/pivot_controller"; + +import { patch } from "@web/core/utils/patch"; + +patch(PivotController.prototype, { + isComparingInfo() { + return Boolean(this.model.searchParams.comparison); + }, + containsDuplicatedGroupBys() { + const colGroupBys = new Set( + this.model.metaData.colGroupBys + .concat(this.model.metaData.expandedColGroupBys) + .map((el) => el.split(":")[0]) + ); + const rowGroupBys = new Set( + this.model.metaData.rowGroupBys + .concat(this.model.metaData.expandedRowGroupBys) + .map((el) => el.split(":")[0]) + ); + return Boolean(colGroupBys.intersection(rowGroupBys).size); + }, + disableSpreadsheetInsertion() { + return ( + !this.model.hasData() || + !this.model.metaData.activeMeasures.length || + this.containsDuplicatedGroupBys() || + this.isComparingInfo() + ); + }, + getSpreadsheetInsertionTooltip() { + var message = _lt("Add to spreadsheet"); + if (this.containsDuplicatedGroupBys()) { + message = _lt("Duplicated groupbys in pivot are not supprted"); + } else if (this.isComparingInfo()) { + message = _lt("Comparisons in pivot are not supprted"); + } + return message; + }, + onSpreadsheetButtonClicked() { + this.actionService.doAction( + "spreadsheet_oca.spreadsheet_spreadsheet_import_act_window", + { + additionalContext: { + default_name: this.model.metaData.title, + default_datasource_name: this.model.metaData.title, + default_can_be_dynamic: true, + default_import_data: { + mode: "pivot", + metaData: JSON.parse(JSON.stringify(this.model.metaData)), + searchParams: JSON.parse(JSON.stringify(this.model.searchParams)), + }, + }, + } + ); + }, +}); diff --git a/spreadsheet_oca/static/src/spreadsheet/spreadsheet.scss b/spreadsheet_oca/static/src/spreadsheet/spreadsheet.scss new file mode 100644 index 00000000..837d6075 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/spreadsheet.scss @@ -0,0 +1,65 @@ +.o_spreadsheet_oca_container { + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: flex; + flex-flow: column; + height: 100%; + .o_spreadsheet_oca_name { + border: none; + padding: 0px 5px 0px 2px; + color: $breadcrumb-active-color; + border-color: var(--o-input-border-color); + &:focus { + border: $input-border-width solid var(--o-input-border-color); + border-width: 0 0 $input-border-width 0; + @include print-variable(o-input-border-color, $o-brand-primary); + @include print-variable(o-caret-color, $o-brand-primary); + } + } + .o_spreadsheet_oca_name_warning { + font-size: 0.8em; + } + + .o_spreadsheet_oca_datasource_panel { + padding: 16px; + .o_spreadsheet_oca_datasource_panel_field { + .o_spreadsheet_oca_datasource_panel_field_title { + font-weight: bold; + } + } + } + .o_spreadsheet_oca_pivot_panel_info { + font-style: italic; + color: $o-gray-600; + } + .o_spreadsheet_oca_filter { + padding: 16px; + .spreadsheet_oca_filter_label { + font-weight: bold; + } + .spreadsheet_oca_filter_value { + display: flex; + .o_field_widget { + width: 100%; + .o_field_tags { + width: 100%; + } + } + .o_field_selector { + width: 100%; + } + .spreadsheet_oca_filter_value_edit { + width: 15px; + margin-left: 1rem; + padding: 0; + cursor: pointer; + } + } + } + .o-section-value { + .o_field_many2one_selection { + width: 100%; + } + } +} diff --git a/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml b/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml new file mode 100644 index 00000000..aa98d195 --- /dev/null +++ b/spreadsheet_oca/static/src/spreadsheet/spreadsheet.xml @@ -0,0 +1,48 @@ + + + + + +
+
+
+
+ + + + +
+

+ +

+ + + + + + + + + + + + + + Spreadsheets + spreadsheet.spreadsheet + tree,form + [] + {} + + + + Spreadsheets + + spreadsheet_oca,static/description/icon.png + + + + + diff --git a/spreadsheet_oca/wizards/__init__.py b/spreadsheet_oca/wizards/__init__.py new file mode 100644 index 00000000..845f1a3e --- /dev/null +++ b/spreadsheet_oca/wizards/__init__.py @@ -0,0 +1,2 @@ +from . import spreadsheet_select_row_number +from . import spreadsheet_spreadsheet_import diff --git a/spreadsheet_oca/wizards/spreadsheet_select_row_number.py b/spreadsheet_oca/wizards/spreadsheet_select_row_number.py new file mode 100644 index 00000000..0bd60de8 --- /dev/null +++ b/spreadsheet_oca/wizards/spreadsheet_select_row_number.py @@ -0,0 +1,11 @@ +# Copyright 2024 Tecnativa - Carlos Roca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class SpreadsheetSelectRowNumber(models.TransientModel): + _name = "spreadsheet.select.row.number" + _description = "Select number of rows to duplicate row" + + number_of_rows = fields.Integer() diff --git a/spreadsheet_oca/wizards/spreadsheet_select_row_number.xml b/spreadsheet_oca/wizards/spreadsheet_select_row_number.xml new file mode 100644 index 00000000..93541b74 --- /dev/null +++ b/spreadsheet_oca/wizards/spreadsheet_select_row_number.xml @@ -0,0 +1,18 @@ + + + + + spreadsheet.select.row.number.form + spreadsheet.select.row.number + +
+ + + + + +
+
+
+ +
diff --git a/spreadsheet_oca/wizards/spreadsheet_spreadsheet_import.py b/spreadsheet_oca/wizards/spreadsheet_spreadsheet_import.py new file mode 100644 index 00000000..3119f199 --- /dev/null +++ b/spreadsheet_oca/wizards/spreadsheet_spreadsheet_import.py @@ -0,0 +1,76 @@ +# Copyright 2022 CreuBlanca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class SpreadsheetSpreadsheetImport(models.TransientModel): + _name = "spreadsheet.spreadsheet.import" + _description = "Import data to spreadsheet" + + @api.model + def _default_mode_id(self): + return self.env["spreadsheet.spreadsheet.import.mode"].search([], limit=1).id + + name = fields.Char() + datasource_name = fields.Char() + mode_id = fields.Many2one( + "spreadsheet.spreadsheet.import.mode", + required=True, + default=lambda r: r._default_mode_id(), + ) + mode = fields.Char(related="mode_id.code") + import_data = fields.Serialized() + spreadsheet_id = fields.Many2one("spreadsheet.spreadsheet") + can_be_dynamic = fields.Boolean() + is_tree = fields.Boolean() + dynamic = fields.Boolean( + help="This field allows you to generate tables that are updated with the " + "filters set in the spreadsheets." + ) + number_of_rows = fields.Integer() + + def insert_pivot(self): + self.ensure_one() + return getattr(self, "_insert_pivot_%s" % self.mode_id.code)() + + def _create_spreadsheet_vals(self): + return {"name": self.name} + + def _insert_pivot_new(self): + spreadsheet = self.env["spreadsheet.spreadsheet"].create( + self._create_spreadsheet_vals() + ) + import_data = self.import_data + import_data["name"] = self.datasource_name + import_data["new"] = 1 + if self.dynamic: + import_data["dyn_number_of_rows"] = self.number_of_rows + return { + "type": "ir.actions.client", + "tag": "action_spreadsheet_oca", + "params": { + "model": spreadsheet._name, + "spreadsheet_id": spreadsheet.id, + "import_data": import_data, + }, + } + + def _insert_pivot_add(self, new_sheet=False): + import_data = self.import_data + import_data["name"] = self.datasource_name + import_data["new_sheet"] = new_sheet + if self.dynamic: + import_data["dyn_number_of_rows"] = self.number_of_rows + return { + "type": "ir.actions.client", + "tag": "action_spreadsheet_oca", + "params": { + "model": "spreadsheet.spreadsheet", + "spreadsheet_id": self.spreadsheet_id.id, + "import_data": import_data, + }, + } + + def _insert_pivot_add_sheet(self): + return self._insert_pivot_add(True) diff --git a/spreadsheet_oca/wizards/spreadsheet_spreadsheet_import.xml b/spreadsheet_oca/wizards/spreadsheet_spreadsheet_import.xml new file mode 100644 index 00000000..99359fd6 --- /dev/null +++ b/spreadsheet_oca/wizards/spreadsheet_spreadsheet_import.xml @@ -0,0 +1,75 @@ + + + + + + spreadsheet.spreadsheet.import.form (in spreadsheet_oca) + spreadsheet.spreadsheet.import + +
+ + + + + + + + + + + + + + +
+
+
+
+
+ + + Import Pivot + spreadsheet.spreadsheet.import + form + {} + new + + + +