From 6ab0a4cecdd826fc81e28e738483e919839c784d Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Mon, 27 Nov 2023 10:14:15 +0100 Subject: [PATCH 1/5] fix test --- edi_webservice_oca/demo/edi_backend.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/edi_webservice_oca/demo/edi_backend.xml b/edi_webservice_oca/demo/edi_backend.xml index 37dd503fda..8f9f4dd35c 100644 --- a/edi_webservice_oca/demo/edi_backend.xml +++ b/edi_webservice_oca/demo/edi_backend.xml @@ -6,6 +6,9 @@ http https://foo.test/{endpoint} application/xml + user_pwd + user + pwd Demo backend type ws From 0af198ff212509502f13a86be7a7e9fc67237fca Mon Sep 17 00:00:00 2001 From: pcastelovigo Date: Mon, 27 Nov 2023 10:16:28 +0100 Subject: [PATCH 2/5] base_business_document_import setup files --- .../odoo/addons/base_business_document_import | 1 + setup/base_business_document_import/setup.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 120000 setup/base_business_document_import/odoo/addons/base_business_document_import create mode 100644 setup/base_business_document_import/setup.py diff --git a/setup/base_business_document_import/odoo/addons/base_business_document_import b/setup/base_business_document_import/odoo/addons/base_business_document_import new file mode 120000 index 0000000000..5e41f0a0b5 --- /dev/null +++ b/setup/base_business_document_import/odoo/addons/base_business_document_import @@ -0,0 +1 @@ +../../../../base_business_document_import \ No newline at end of file diff --git a/setup/base_business_document_import/setup.py b/setup/base_business_document_import/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/base_business_document_import/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 927c008426dc04bec44928d1e2defee03faf0eed Mon Sep 17 00:00:00 2001 From: pcastelovigo Date: Mon, 27 Nov 2023 10:16:55 +0100 Subject: [PATCH 3/5] fix test requirements --- test-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test-requirements.txt b/test-requirements.txt index 43172676f0..9349b88b08 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1 +1,2 @@ odoo-test-helper>=2.0.1 +responses From c0fbb81ec30c0e70bea556c167eb8ac22a03229c Mon Sep 17 00:00:00 2001 From: Goncalo Brito Date: Mon, 27 Nov 2023 10:23:26 +0100 Subject: [PATCH 4/5] backport from 16 --- base_business_document_import/README.rst | 93 ++ base_business_document_import/__init__.py | 1 + base_business_document_import/__manifest__.py | 20 + .../i18n/base_business_document_import.pot | 372 +++++ base_business_document_import/i18n/cs_CZ.po | 445 ++++++ base_business_document_import/i18n/es.po | 498 ++++++ base_business_document_import/i18n/fr.po | 554 +++++++ base_business_document_import/i18n/fr_FR.po | 598 +++++++ base_business_document_import/i18n/nl.po | 598 +++++++ .../models/__init__.py | 1 + .../models/business_document_import.py | 1398 +++++++++++++++++ .../readme/CONTRIBUTORS.rst | 5 + .../readme/DESCRIPTION.rst | 5 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 432 +++++ .../tests/__init__.py | 1 + .../tests/test_business_document_import.py | 482 ++++++ 17 files changed, 5503 insertions(+) create mode 100644 base_business_document_import/README.rst create mode 100644 base_business_document_import/__init__.py create mode 100644 base_business_document_import/__manifest__.py create mode 100644 base_business_document_import/i18n/base_business_document_import.pot create mode 100644 base_business_document_import/i18n/cs_CZ.po create mode 100644 base_business_document_import/i18n/es.po create mode 100644 base_business_document_import/i18n/fr.po create mode 100644 base_business_document_import/i18n/fr_FR.po create mode 100644 base_business_document_import/i18n/nl.po create mode 100644 base_business_document_import/models/__init__.py create mode 100644 base_business_document_import/models/business_document_import.py create mode 100644 base_business_document_import/readme/CONTRIBUTORS.rst create mode 100644 base_business_document_import/readme/DESCRIPTION.rst create mode 100644 base_business_document_import/static/description/icon.png create mode 100644 base_business_document_import/static/description/index.html create mode 100644 base_business_document_import/tests/__init__.py create mode 100644 base_business_document_import/tests/test_business_document_import.py diff --git a/base_business_document_import/README.rst b/base_business_document_import/README.rst new file mode 100644 index 0000000000..a0dbd9e366 --- /dev/null +++ b/base_business_document_import/README.rst @@ -0,0 +1,93 @@ +============================= +Base Business Document Import +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e0687319afa4e196bd4d8087afd6a7f63b64265200a8e5837fb7658d8ef8dd95 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fedi-lightgray.png?logo=github + :target: https://github.com/OCA/edi/tree/16.0/base_business_document_import + :alt: OCA/edi +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/edi-16-0/edi-16-0-base_business_document_import + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/edi&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This is a technical module ; it doesn't bring any useful feature by itself. This module is the base modules for 2 other modules : + +* *account_invoice_import* which imports supplier invoices as PDF or XML files (this module also requires some additional modules such as *account_invoice_import_invoice2data*, *account_invoice_import_ubl*, etc... to support specific invoice formats), + +* *sale_invoice_import* which imports sale orders as CSV, XML or PDF files (this module also requires some additional modules such as *sale_invoice_import_csv* or *sale_invoice_import_ubl* to support specific order formats) + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Akretion +* Nicolas JEUDY + +Contributors +~~~~~~~~~~~~ + +* Alexis de Lattre +* Nicolas JEUDY +* Jacques-Etienne Baudoux +* Phuc (Tran Thanh) +* Simone Orsi + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-alexis-via| image:: https://github.com/alexis-via.png?size=40px + :target: https://github.com/alexis-via + :alt: alexis-via + +Current `maintainer `__: + +|maintainer-alexis-via| + +This module is part of the `OCA/edi `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_business_document_import/__init__.py b/base_business_document_import/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/base_business_document_import/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/base_business_document_import/__manifest__.py b/base_business_document_import/__manifest__.py new file mode 100644 index 0000000000..aea2e4c4a6 --- /dev/null +++ b/base_business_document_import/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2016-2021 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Base Business Document Import", + "version": "15.0.1.0.0", + "category": "Tools", + "license": "AGPL-3", + "summary": "Provides technical tools to import sale orders or supplier invoices", + "author": "Akretion, Nicolas JEUDY, Odoo Community Association (OCA)", + "maintainers": ["alexis-via"], + "website": "https://github.com/OCA/edi", + "depends": [ + # OCA/community-data-files + "account_tax_unece", + "uom_unece", + "pdf_helper", + ], +} diff --git a/base_business_document_import/i18n/base_business_document_import.pot b/base_business_document_import/i18n/base_business_document_import.pot new file mode 100644 index 0000000000..7faebfefee --- /dev/null +++ b/base_business_document_import/i18n/base_business_document_import.pot @@ -0,0 +1,372 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_business_document_import +# +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: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "(fixed)" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in file %s:" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in imported document:" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"

Odoo couldn't find any unit of measure corresponding to the following " +"information extracted from the business document:

  • UNECE code: " +"%(code)s
  • Name of the unit of measure: %(name)s

So the " +"unit of measure 'Unit(s)' has been used. You may have to change it " +"manually.

" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Approximate match: account %(account)s has been matched with account " +"%(matched_account)s" +msgstr "" + +#. module: base_business_document_import +#: model:ir.model,name:base_business_document_import.model_business_document_import +msgid "Common methods to import business documents" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Could not find any Incoterm in Odoo corresponding to '%s'" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"For product '%(product)s', the unit of measure is %(uom_product)s on the " +"existing line, but it is %(uom_imported)s on the imported line.We don't " +"support this scenario for the moment, so the lines haven't been " +"updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "IBAN %s is not valid, so it has been ignored." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "ID {id} of '{model}' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Missing VAT number on company '%s'" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "No currency specified, so Odoo used the company currency (%s)" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any %(label)s corresponding to the following information extracted from the business document:\n" +"Name: %(name)s \n" +"VAT number: %(vat)s \n" +"Reference: %(ref)s \n" +"E-mail: %(email)s \n" +"Website: %(website)s \n" +"State code: %(state)s \n" +"Country code: %(country)s \n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any account corresponding to the following information extracted from the business document:\n" +"Account code: %s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any analytic account corresponding to the following information extracted from the business document:\n" +"Analytic account code: %s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any journal corresponding to the following information extracted from the business document:\n" +"Journal code: %s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any product corresponding to the following information extracted from the business document:\n" +"Barcode: %(barcode)s\n" +"Product code: %(product_code)s\n" +"Supplier: %(supplier)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any shipping partner corresponding to the following information extracted from the business document:\n" +"Name: %(name)s\n" +"VAT number: %(vat)s\n" +"Reference: %(ref)s\n" +"E-mail: %(email)s\n" +"Website: %(website)s\n" +"Street: %(street)s\n" +"Street2: %(street2)s\n" +"City: %(city)s\n" +"ZIP: %(zip)s\n" +"State code: %(state)s\n" +"Country code: %(country)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax Included in Price' = '%(price)s' which correspond to the following information extracted from the business document:\n" +"UNECE Tax Type code: %(tax_type)s\n" +"UNECE Tax Category code: %(tax_cat)s\n" +"UNECE Due Date code: %(tax_due_date)s\n" +"Tax amount: %(amount)s %(amount_type)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"One of the imported lines doesn't have any product, so the lines haven't " +"been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The %(label)s has been identified by the domain name '%(domain)s' so please " +"check carefully that the %(label)s is correct." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The VAT number of the customer written in the business document " +"(%(parsed_vat)s) doesn't match the VAT number of the company '%(company)s' " +"(%(vat)s) in which you are trying to import this document." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "The XMLID '%s' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the country " +"code to find the related currency. But the country '%(name)s' doesn't have " +"any related currency configured in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the currency " +"symbol or ISO code. But there are none or several currencies with the " +"symbol/ISO code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the unit of " +"measure UNECE code, but there is no unit of measure with that UNECE code in " +"Odoo. Please check the configuration of the units of measures in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as country code. But " +"there are no country with that code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the country code to " +"find the related currency. But there is no country with that code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency ISO " +"code. But there are no currency with that code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency symbol. " +"But there are none or several currencies with that symbol in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned IBAN %(iban)s as bank " +"account, but there is no such bank account in Odoo linked to partner %(partner)s " +"and the option to automatically create bank accounts upon import is " +"disabled." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The bank account IBAN %(iban)s has been automatically added on the " +"supplier %(partner)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The existing line '%s' doesn't have any product, so the lines haven't " +"been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several existing lines, so the lines haven't " +"been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several imported lines, so the lines haven't " +"been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The record '{record}' is an instance of '{record_model}', not of " +"'{target_model}'." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "customer" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "partner" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "supplier" +msgstr "" diff --git a/base_business_document_import/i18n/cs_CZ.po b/base_business_document_import/i18n/cs_CZ.po new file mode 100644 index 0000000000..a7795f89cf --- /dev/null +++ b/base_business_document_import/i18n/cs_CZ.po @@ -0,0 +1,445 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_business_document_import +# +# Translators: +# Lukáš Spurný , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-22 03:40+0000\n" +"PO-Revision-Date: 2018-02-22 03:40+0000\n" +"Last-Translator: Lukáš Spurný , 2018\n" +"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/" +"teams/23907/cs_CZ/)\n" +"Language: cs_CZ\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "(fixed)" +msgstr "(Úprávy)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in file %s:" +msgstr "Poznámky v souboru %s:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in imported document:" +msgstr "Poznámky v importovaném dokumentu:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"

Odoo couldn't find any unit of measure corresponding to the following " +"information extracted from the business document:

  • UNECE code: " +"%(code)s
  • Name of the unit of measure: %(name)s

So the " +"unit of measure 'Unit(s)' has been used. You may have to change it " +"manually.

" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Approximate match: account %(account)s has been matched with account " +"%(matched_account)s" +msgstr "" + +#. module: base_business_document_import +#: model:ir.model,name:base_business_document_import.model_business_document_import +msgid "Common methods to import business documents" +msgstr "Společné metody importu obchodních dokumentů" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Could not find any Incoterm in Odoo corresponding to '%s'" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"For product '%(product)s', the unit of measure is %(uom_product)s on the " +"existing line, but it is %(uom_imported)s on the imported line.We don't " +"support this scenario for the moment, so the lines haven't been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "IBAN %s is not valid, so it has been ignored." +msgstr "IBAN %s není platný, takže byl ignorován." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "ID {id} of '{model}' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Missing VAT number on company '%s'" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "No currency specified, so Odoo used the company currency (%s)" +msgstr "Není uvedena žádná měna, takže Odoo použil měnu společnosti (%s)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any %(label)s corresponding to the following information " +"extracted from the business document:\n" +"Name: %(name)s \n" +"VAT number: %(vat)s \n" +"Reference: %(ref)s \n" +"E-mail: %(email)s \n" +"Website: %(website)s \n" +"State code: %(state)s \n" +"Country code: %(country)s \n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any account corresponding to the following information " +"extracted from the business document:\n" +"Account code: %s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any analytic account corresponding to the following " +"information extracted from the business document:\n" +"Analytic account code: %s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any journal corresponding to the following information " +"extracted from the business document:\n" +"Journal code: %s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any product corresponding to the following information " +"extracted from the business document:\n" +"Barcode: %(barcode)s\n" +"Product code: %(product_code)s\n" +"Supplier: %(supplier)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any shipping partner corresponding to the following " +"information extracted from the business document:\n" +"Name: %(name)s\n" +"VAT number: %(vat)s\n" +"Reference: %(ref)s\n" +"E-mail: %(email)s\n" +"Website: %(website)s\n" +"Street: %(street)s\n" +"Street2: %(street2)s\n" +"City: %(city)s\n" +"ZIP: %(zip)s\n" +"State code: %(state)s\n" +"Country code: %(country)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax " +"Included in Price' = '%(price)s' which correspond to the following " +"information extracted from the business document:\n" +"UNECE Tax Type code: %(tax_type)s\n" +"UNECE Tax Category code: %(tax_cat)s\n" +"UNECE Due Date code: %(tax_due_date)s\n" +"Tax amount: %(amount)s %(amount_type)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"One of the imported lines doesn't have any product, so the lines haven't " +"been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The %(label)s has been identified by the domain name '%(domain)s' so please " +"check carefully that the %(label)s is correct." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The VAT number of the customer written in the business document " +"(%(parsed_vat)s) doesn't match the VAT number of the company " +"'%(company)s' (%(vat)s) in which you are trying to import this document." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "The XMLID '%s' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the country " +"code to find the related currency. But the country '%(name)s' doesn't have " +"any related currency configured in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the currency " +"symbol or ISO code. But there are none or several currencies with the symbol/" +"ISO code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the unit of " +"measure UNECE code, but there is no unit of measure with that UNECE code in " +"Odoo. Please check the configuration of the units of measures in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as country code. But " +"there are no country with that code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the country code to " +"find the related currency. But there is no country with that code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency ISO " +"code. But there are no currency with that code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency symbol. " +"But there are none or several currencies with that symbol in Odoo." +msgstr "" +"Analýza obchodního dokladu vrátila jako symbol měny symbol '%s'. Ale v Odoo " +"neexistuje žádný nebo několik měn s tímto symbolem." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned IBAN %(iban)s as bank " +"account, but there is no such bank account in Odoo linked to partner %(partner)s " +"and the option to automatically create bank accounts upon import is disabled." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The bank account IBAN %(iban)s has been automatically added on the " +"supplier " +"%(partner)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The existing line '%s' doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"Existující řádek '%s' nemá žádný produkt, takže 1 řádky nebyly aktualizovány." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several existing lines, so the lines haven't " +"been updated." +msgstr "" +"Produkt '%s' se používá na několika existujících linkách, takže řádky nebyly " +"aktualizovány." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several imported lines, so the lines haven't " +"been updated." +msgstr "" +"Produkt '%s' se používá na několika importovaných řádcích, takže 1 řádky " +"nebyly aktualizovány." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The record '{record}' is an instance of '{record_model}', not of " +"'{target_model}'." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "customer" +msgstr "zákazník" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "partner" +msgstr "partner" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "supplier" +msgstr "dodavatele" + +#, python-format +#~ msgid "" +#~ "

Odoo couldn't find any unit of measure corresponding to the following " +#~ "information extracted from the business document:

  • UNECE code: " +#~ "%s
  • Name of the unit of measure: %s

So the unit of " +#~ "measure 'Unit(s)' has been used. You may have to change it manually.

" +#~ msgstr "" +#~ "Společnost Odoo nemohla najít žádnou měrnou jednotku, která by odpovídala " +#~ "těmto informacím získaným z obchodního dokladu: Kód UNECE %s Náměrová " +#~ "jednotka: %s Je použita měrná jednotka 'Jednotky)' Musíte ji ručně změnit." + +#, python-format +#~ msgid "Approximate match: account %s has been matched with account %s" +#~ msgstr "Přibližná shoda: účet %s byl přiřazen účtu %s" + +#~ msgid "Display Name" +#~ msgstr "Zobrazovaný název" + +#, python-format +#~ msgid "" +#~ "For product '%s', the unit of measure is %s on the existing line, but it " +#~ "is %s on the imported line. We don't support this scenario for the " +#~ "moment, so the lines haven't been updated." +#~ msgstr "" +#~ "U produktu '%s' je měrnou jednotkou %s na existujícím řádku, ale na " +#~ "importované řádce je %s. Momentálně nepodporujeme tento scénář, takže 1 " +#~ "řádky nebyly aktualizovány." + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Poslední změna dne" + +#, fuzzy, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the currency " +#~ "symbol or ISO code. But there are none or several currencies with the " +#~ "symbol/ISO code in Odoo." +#~ msgstr "" +#~ "Analýza obchodního dokladu vrátila hodnotu \"%s\" jako symbol měny nebo " +#~ "kód ISO. Neexistuje však žádná měna se symbolem ani kódem ISO v Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the unit of " +#~ "measure UNECE code, but there is no unit of measure with that UNECE code " +#~ "in Odoo. Please check the configuration of the units of measures in Odoo." +#~ msgstr "" +#~ "Analýza obchodního dokladu vrátila \"%s\" jako měrnou jednotku UNECE, " +#~ "avšak s tímto kódem UNECE v Odoo neexistuje žádná měrná jednotka. " +#~ "Zkontrolujte prosím konfiguraci jednotek opatření v Odoo." diff --git a/base_business_document_import/i18n/es.po b/base_business_document_import/i18n/es.po new file mode 100644 index 0000000000..121da667fb --- /dev/null +++ b/base_business_document_import/i18n/es.po @@ -0,0 +1,498 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_business_document_import +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-03 20:37+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "(fixed)" +msgstr "(fijado)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in file %s:" +msgstr "Notas en el archivo %s:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in imported document:" +msgstr "Notas en el documento importado:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"

Odoo couldn't find any unit of measure corresponding to the following " +"information extracted from the business document:

  • UNECE code: " +"%(code)s
  • Name of the unit of measure: %(name)s

So the " +"unit of measure 'Unit(s)' has been used. You may have to change it " +"manually.

" +msgstr "" +"

Odoo no pudo encontrar ninguna unidad de medida correspondiente a la " +"siguiente información extraída del documento comercial:

  • Código " +"UNECE: %(code)s
  • Nombre de la unidad de medida: %(name)s
  • Entonces se ha utilizado la unidad de medida 'Unidad(es)'. Puede " +"que tenga que cambiarlo manualmente.

    " + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Approximate match: account %(account)s has been matched with account " +"%(matched_account)s" +msgstr "" +"Coincidencia aproximada: la cuenta %(account)s ha coincidido con la cuenta " +"%(matched_account)s" + +#. module: base_business_document_import +#: model:ir.model,name:base_business_document_import.model_business_document_import +msgid "Common methods to import business documents" +msgstr "Métodos habituales para importar documentos comerciales" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Could not find any Incoterm in Odoo corresponding to '%s'" +msgstr "No se pudo encontrar ningún Incotérmino en Odoo que corresponda a '%s'" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"For product '%(product)s', the unit of measure is %(uom_product)s on the " +"existing line, but it is %(uom_imported)s on the imported line.We don't " +"support this scenario for the moment, so the lines haven't been updated." +msgstr "" +"Para el producto '%(product)s', la unidad de medida es %(uom_product)s en la " +"línea existente, pero es %(uom_imported)s en la línea importada. No " +"admitimos este escenario por el momento, por lo que las líneas no se han " +"actualizado." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "IBAN %s is not valid, so it has been ignored." +msgstr "El IBAN %s no es válido, por lo que se ha ignorado." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "ID {id} of '{model}' doesn't exist in Odoo." +msgstr "La ID {id} de '{model}' no existe en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Missing VAT number on company '%s'" +msgstr "Falta el número de IVA de la compañía \"%s\"" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "No currency specified, so Odoo used the company currency (%s)" +msgstr "" +"No se especificó la moneda, por lo que Odoo utilizó la moneda de la compañía " +"(%s)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any %(label)s corresponding to the following information " +"extracted from the business document:\n" +"Name: %(name)s \n" +"VAT number: %(vat)s \n" +"Reference: %(ref)s \n" +"E-mail: %(email)s \n" +"Website: %(website)s \n" +"State code: %(state)s \n" +"Country code: %(country)s \n" +msgstr "" +"Odoo no pudo encontrar ningún %(label)s correspondiente a la siguiente " +"información extraída del documento comercial:\n" +"Nombre: %(name)s\n" +"Número de IVA: %(vat)s\n" +"Referencia: %(ref)s\n" +"Correo electrónico: %(email)s\n" +"Sitio web: %(website)s\n" +"Código de estado: %(state)s\n" +"Código de país: %(country)s \n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any account corresponding to the following information " +"extracted from the business document:\n" +"Account code: %s" +msgstr "" +"Odoo no pudo encontrar ninguna cuenta correspondiente a la siguiente " +"información extraída del documento comercial:\n" +"Código de cuenta: %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any analytic account corresponding to the following " +"information extracted from the business document:\n" +"Analytic account code: %s" +msgstr "" +"Odoo no pudo encontrar ninguna cuenta analítica correspondiente a la " +"siguiente información extraída del documento comercial:\n" +"Código de cuenta analítica: %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any journal corresponding to the following information " +"extracted from the business document:\n" +"Journal code: %s" +msgstr "" +"Odoo no pudo encontrar ningún diario correspondiente a la siguiente " +"información extraída del documento comercial:\n" +"Código de diario: %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any product corresponding to the following information " +"extracted from the business document:\n" +"Barcode: %(barcode)s\n" +"Product code: %(product_code)s\n" +"Supplier: %(supplier)s\n" +msgstr "" +"Odoo no pudo encontrar ningún producto correspondiente a la siguiente " +"información extraída del documento comercial:\n" +"Código de barras: %(barcode)s\n" +"Código de producto: %(product_code)s\n" +"Proveedor: %(supplier)s\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any shipping partner corresponding to the following " +"information extracted from the business document:\n" +"Name: %(name)s\n" +"VAT number: %(vat)s\n" +"Reference: %(ref)s\n" +"E-mail: %(email)s\n" +"Website: %(website)s\n" +"Street: %(street)s\n" +"Street2: %(street2)s\n" +"City: %(city)s\n" +"ZIP: %(zip)s\n" +"State code: %(state)s\n" +"Country code: %(country)s\n" +msgstr "" +"Odoo no pudo encontrar ningún socio de envío correspondiente a la siguiente " +"información extraída del documento comercial:\n" +"Nombre: %(name)s\n" +"Número de IVA: %(vat)s\n" +"Referencia: %(ref)s\n" +"Correo electrónico: %(email)s\n" +"Sitio web: %(website)s\n" +"Calle: %(street)s\n" +"Calle2: %(street2)s\n" +"Ciudad: %(city)s\n" +"Código postal: %(zip)s\n" +"Código de estado: %(state)s\n" +"Código de país: %(country)s\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax " +"Included in Price' = '%(price)s' which correspond to the following " +"information extracted from the business document:\n" +"UNECE Tax Type code: %(tax_type)s\n" +"UNECE Tax Category code: %(tax_cat)s\n" +"UNECE Due Date code: %(tax_due_date)s\n" +"Tax amount: %(amount)s %(amount_type)s" +msgstr "" +"Odoo no pudo encontrar ningún impuesto con 'Aplicación de impuestos' = " +"'%(tax)s' e 'Impuesto incluido en el precio' = '%(price)s' que corresponden " +"a la siguiente información extraída del documento comercial:\n" +"Código de tipo de impuesto CEPE: %(tax_type)s\n" +"Código de categoría fiscal de la CEPE: %(tax_cat)s\n" +"Código de fecha de vencimiento de la CEPE: %(tax_due_date)s\n" +"Monto del impuesto: %(amount)s %(amount_type)s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"One of the imported lines doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"Una de las líneas importadas no tiene ningún producto, por lo que las " +"líneas no se han actualizado." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The %(label)s has been identified by the domain name '%(domain)s' so please " +"check carefully that the %(label)s is correct." +msgstr "" +"El %(label)s ha sido identificado por el nombre de dominio '%(domain)s' así " +"que por favor compruebe cuidadosamente que el %(label)s es correcto." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The VAT number of the customer written in the business document " +"(%(parsed_vat)s) doesn't match the VAT number of the company " +"'%(company)s' (%(vat)s) in which you are trying to import this document." +msgstr "" +"El número de IVA del cliente escrito en el documento comercial " +"(%(parsed_vat)s) no coincide con el número de IVA de la empresa " +"'%(company)s' (%(vat)s) en la que intenta importar esto documento." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "The XMLID '%s' doesn't exist in Odoo." +msgstr "El XMLID '%s' no existe en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the country " +"code to find the related currency. But the country '%(name)s' doesn't have " +"any related currency configured in Odoo." +msgstr "" +"El análisis del documento comercial arrojó '%(code)s' como el código de país " +"para encontrar la moneda relacionada. Pero el país '%(name)s' no tiene " +"ninguna moneda relacionada configurada en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the currency " +"symbol or ISO code. But there are none or several currencies with the symbol/" +"ISO code in Odoo." +msgstr "" +"El análisis del documento comercial arrojó '%(code)s' como símbolo de moneda " +"o código ISO. Pero no hay ninguna o varias monedas con el símbolo/código ISO " +"en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the unit of " +"measure UNECE code, but there is no unit of measure with that UNECE code in " +"Odoo. Please check the configuration of the units of measures in Odoo." +msgstr "" +"El análisis del documento comercial arrojó '%(code)s' como la unidad de " +"medida del código UNECE, pero no hay ninguna unidad de medida con ese código " +"UNECE en Odoo. Por favor revise la configuración de las unidades de medidas " +"en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as country code. But " +"there are no country with that code in Odoo." +msgstr "" +"El análisis del documento de negocio devolvió '%s' como código de país. Pero " +"no hay ningún país con ese código en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the country code to " +"find the related currency. But there is no country with that code in Odoo." +msgstr "" +"El análisis del documento comercial arrojó '%s' como código de país para " +"encontrar la moneda relacionada. Pero no hay ningún país con ese código en " +"Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency ISO " +"code. But there are no currency with that code in Odoo." +msgstr "" +"El análisis del documento comercial devolvió '%s' como el código ISO de " +"divisa. Pero no hay divisa con ese código en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency symbol. " +"But there are none or several currencies with that symbol in Odoo." +msgstr "" +"El análisis del documento comercial arrojó '%s' como símbolo de divisa. Pero " +"no hay ninguna o varias divisas con ese símbolo en Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned IBAN %(iban)s as bank " +"account, but there is no such bank account in Odoo linked to partner %(partner)s " +"and the option to automatically create bank accounts upon import is disabled." +msgstr "" +"El análisis del documento comercial deolvió IBAN %(iban)s como cuenta " +"bancaria, pero no existe tal cuenta bancaria en Odoo vinculada al socio %(partner)s y " +"la opción de crear automáticamente cuentas bancarias al importar está " +"deshabilitada." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The bank account IBAN %(iban)s has been automatically added on the " +"supplier " +"%(partner)s" +msgstr "" +"La cuenta bancaria IBAN %(iban)s se ha añadido automáticamente al " +"proveedor " +"%(partner)s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The existing line '%s' doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"La línea existente '%s' no tiene ningún producto, por lo que las líneas " +"no se han actualizado." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several existing lines, so the lines haven't " +"been updated." +msgstr "" +"El producto '%s' se utiliza en varias líneas existentes, por lo que las " +"líneas no se han actualizado." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several imported lines, so the lines haven't " +"been updated." +msgstr "" +"El producto '%s' se utiliza en varias líneas importadas, por lo que las " +"líneas no se han actualizado." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The record '{record}' is an instance of '{record_model}', not of " +"'{target_model}'." +msgstr "" +"El registro '{record}' es una instancia de '{record_model}', no de " +"'{target_model}'." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "customer" +msgstr "Cliente" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "partner" +msgstr "socio" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "supplier" +msgstr "proveedor" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax " +#~ "Included in Price' = '%(price)s' which correspond to the following " +#~ "information extracted from the business document:\n" +#~ "UNECE Tax Type code: %(tax_type)s\n" +#~ "UNECE Tax Category code: %(tax_cat)s\n" +#~ "UNECE Due Date code: %s(tax_due_date)\n" +#~ "Tax amount: %(amount)s %(amount_type)s" +#~ msgstr "" +#~ "Odoo no pudo encontrar ningún impuesto con 'Aplicación de impuestos' = " +#~ "'%(tax)s' e 'Impuestos incluidos en el precio' = '%(price)s' que " +#~ "corresponden a la siguiente información extraída del documento " +#~ "comercial:\n" +#~ "Código de tipo de impuesto de la UNECE (CEPE): %(tax_type)s\n" +#~ "Código de categoría fiscal de la UNECE (CEPE): %(tax_cat)s\n" +#~ "Código de fecha de vencimiento de la UNECE (CEPE): %s(tax_due_date)\n" +#~ "Monto del impuesto: %(amount)s %(amount_type)s" diff --git a/base_business_document_import/i18n/fr.po b/base_business_document_import/i18n/fr.po new file mode 100644 index 0000000000..b0e5f8deba --- /dev/null +++ b/base_business_document_import/i18n/fr.po @@ -0,0 +1,554 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_business_document_import +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-22 03:40+0000\n" +"PO-Revision-Date: 2022-08-07 07:06+0000\n" +"Last-Translator: Claude R Perrin \n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"Language: 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" +"X-Generator: Weblate 4.3.2\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "(fixed)" +msgstr "(fixe)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in file %s:" +msgstr "Notes dans le fichier %s:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in imported document:" +msgstr "Notes dans le document importé :" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"

    Odoo couldn't find any unit of measure corresponding to the following " +"information extracted from the business document:

    • UNECE code: " +"%(code)s
    • Name of the unit of measure: %(name)s

    So the " +"unit of measure 'Unit(s)' has been used. You may have to change it " +"manually.

    " +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Approximate match: account %(account)s has been matched with account " +"%(matched_account)s" +msgstr "" + +#. module: base_business_document_import +#: model:ir.model,name:base_business_document_import.model_business_document_import +msgid "Common methods to import business documents" +msgstr "Méthodes courantes d'importation de documents commerciaux" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Could not find any Incoterm in Odoo corresponding to '%s'" +msgstr "Impossible de trouver un Incoterm dans Odoo correspondant à '%s'" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"For product '%(product)s', the unit of measure is %(uom_product)s on the " +"existing line, but it is %(uom_imported)s on the imported line.We don't " +"support this scenario for the moment, so the lines haven't been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "IBAN %s is not valid, so it has been ignored." +msgstr "IBAN %s n’est pas valide, il a donc été ignoré." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "ID {id} of '{model}' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Missing VAT number on company '%s'" +msgstr "Numéro de TVA manquant pour la société \"%s\"" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "No currency specified, so Odoo used the company currency (%s)" +msgstr "" +"Aucune devise n'a été spécifiée, Odoo a donc utilisé la devise de la société " +"(%s)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any %(label)s corresponding to the following information " +"extracted from the business document:\n" +"Name: %(name)s \n" +"VAT number: %(vat)s \n" +"Reference: %(ref)s \n" +"E-mail: %(email)s \n" +"Website: %(website)s \n" +"State code: %(state)s \n" +"Country code: %(country)s \n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any account corresponding to the following information " +"extracted from the business document:\n" +"Account code: %s" +msgstr "" +"Odoo n'a pas trouvé de compte correspondant aux informations suivantes " +"extraites du document commercial :\n" +"Code du compte : %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any analytic account corresponding to the following " +"information extracted from the business document:\n" +"Analytic account code: %s" +msgstr "" +"Odoo n'a pas trouvé de compte analytique correspondant aux informations " +"suivantes extraites du document commercial :\n" +"Code du compte analytique : %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any journal corresponding to the following information " +"extracted from the business document:\n" +"Journal code: %s" +msgstr "" +"Odoo n'a pas trouvé de journal correspondant aux informations suivantes " +"extraites du document commercial :\n" +"Code journal : %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any product corresponding to the following information " +"extracted from the business document:\n" +"Barcode: %(barcode)s\n" +"Product code: %(product_code)s\n" +"Supplier: %(supplier)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any shipping partner corresponding to the following " +"information extracted from the business document:\n" +"Name: %(name)s\n" +"VAT number: %(vat)s\n" +"Reference: %(ref)s\n" +"E-mail: %(email)s\n" +"Website: %(website)s\n" +"Street: %(street)s\n" +"Street2: %(street2)s\n" +"City: %(city)s\n" +"ZIP: %(zip)s\n" +"State code: %(state)s\n" +"Country code: %(country)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax " +"Included in Price' = '%(price)s' which correspond to the following " +"information extracted from the business document:\n" +"UNECE Tax Type code: %(tax_type)s\n" +"UNECE Tax Category code: %(tax_cat)s\n" +"UNECE Due Date code: %(tax_due_date)s\n" +"Tax amount: %(amount)s %(amount_type)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"One of the imported lines doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"Une des lignes importées n'a pas de produit, donc les lignes n'ont pas " +"été mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The %(label)s has been identified by the domain name '%(domain)s' so please " +"check carefully that the %(label)s is correct." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The VAT number of the customer written in the business document " +"(%(parsed_vat)s) doesn't match the VAT number of the company " +"'%(company)s' (%(vat)s) in which you are trying to import this document." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "The XMLID '%s' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the country " +"code to find the related currency. But the country '%(name)s' doesn't have " +"any related currency configured in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the currency " +"symbol or ISO code. But there are none or several currencies with the symbol/" +"ISO code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the unit of " +"measure UNECE code, but there is no unit of measure with that UNECE code in " +"Odoo. Please check the configuration of the units of measures in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as country code. But " +"there are no country with that code in Odoo." +msgstr "" +"L'analyse du document commercial a retourné '%s' comme code de pays. Mais il " +"n'y a pas de pays avec ce code dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the country code to " +"find the related currency. But there is no country with that code in Odoo." +msgstr "" +"L'analyse du document commercial a renvoyé '%s' comme code de pays pour " +"trouver la devise correspondante. Mais il n'y a pas de pays avec ce code " +"dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency ISO " +"code. But there are no currency with that code in Odoo." +msgstr "" +"L'analyse du document commercial a renvoyé '%s' comme code de pays pour " +"trouver la devise correspondante. Mais il n'y a pas de pays avec ce code " +"dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency symbol. " +"But there are none or several currencies with that symbol in Odoo." +msgstr "" +"L'analyse du document commercial a donné '%s' comme symbole de devise. Mais " +"il n'y a pas ou plusieurs devises avec ce symbole dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned IBAN %(iban)s as bank " +"account, but there is no such bank account in Odoo linked to partner %(partner)s " +"and the option to automatically create bank accounts upon import is disabled." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The bank account IBAN %(iban)s has been automatically added on the " +"supplier " +"%(partner)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The existing line '%s' doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"La ligne existante '%s' n'a pas de produit, donc les lignes n'ont pas été " +"mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several existing lines, so the lines haven't " +"been updated." +msgstr "" +"Le produit '%s' est utilisé sur plusieurs lignes existantes, donc les " +"lignes n'ont pas été mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several imported lines, so the lines haven't " +"been updated." +msgstr "" +"Le produit '%s' est utilisé sur plusieurs lignes importées, donc les " +"lignes n'ont pas été mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The record '{record}' is an instance of '{record_model}', not of " +"'{target_model}'." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "customer" +msgstr "client" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "partner" +msgstr "partenaire" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "supplier" +msgstr "sournisseur" + +#, python-format +#~ msgid "" +#~ "

    Odoo couldn't find any unit of measure corresponding to the following " +#~ "information extracted from the business document:

    • UNECE code: " +#~ "%s
    • Name of the unit of measure: %s

    So the unit of " +#~ "measure 'Unit(s)' has been used. You may have to change it manually.

    " +#~ msgstr "" +#~ "

    Odoo n'a pas trouvé d'unité de mesure correspondant aux informations " +#~ "suivantes extraites du document métier :

    • Code UNECE : %s
    • Nom de l'unité de mesure : %s

    L'unité de mesure " +#~ "'Unité(s)' a donc été utilisée. Vous devrez peut-être la modifier " +#~ "manuellement.

    " + +#, python-format +#~ msgid "Approximate match: account %s has been matched with account %s" +#~ msgstr "" +#~ "Correspondance approximative : le compte %s a été mis en correspondance " +#~ "avec le compte %s" + +#~ msgid "Display Name" +#~ msgstr "Afficher Nom" + +#, python-format +#~ msgid "" +#~ "For product '%s', the unit of measure is %s on the existing line, but it " +#~ "is %s on the imported line. We don't support this scenario for the " +#~ "moment, so the lines haven't been updated." +#~ msgstr "" +#~ "Pour le produit ' %s ', l’unité de mesure est %s sur la ligne existante, " +#~ "mais elle est sur %s la ligne importée. Nous ne prenons pas en charge ce " +#~ "scénario pour le moment, donc les lignes n’ont pas été mises à jour." + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification le" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any product corresponding to the following information " +#~ "extracted from the business document:\n" +#~ "Barcode: %s\n" +#~ "Product code: %s\n" +#~ "Supplier: %s\n" +#~ msgstr "" +#~ "Odoo n'a pas pu trouver de produit correspondant aux informations " +#~ "suivantes extraites du document commercial :\n" +#~ "Barcode : %s\n" +#~ "Code produit : %s\n" +#~ "Fournisseur : %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any tax with 'Tax Application' = '%s' and 'Tax " +#~ "Included in Price' = '%s' which correspond to the following information " +#~ "extracted from the business document:\n" +#~ "UNECE Tax Type code: %s\n" +#~ "UNECE Tax Category code: %s\n" +#~ "UNECE Due Date code: %s\n" +#~ "Tax amount: %s %s" +#~ msgstr "" +#~ "Odoo n'a pas trouvé de taxe avec 'Tax Application' = '%s' et 'Tax " +#~ "Included in Price' = '%s' qui correspondent aux informations suivantes " +#~ "extraites du document commercial :\n" +#~ "Code de type de taxe CEE-ONU : %s\n" +#~ "Code de catégorie de taxe CEE-ONU : %s\n" +#~ "Code de la date d'échéance CEE-ONU : %s\n" +#~ "Montant de la taxe : %s %s" + +#, python-format +#~ msgid "" +#~ "The %s has been identified by the domain name '%s' so please check " +#~ "carefully that the %s is correct." +#~ msgstr "" +#~ "Le %s a été identifié par le nom de domaine '%s'. Veuillez vérifier " +#~ "soigneusement que le %s est correct." + +#, python-format +#~ msgid "" +#~ "The VAT number of the customer written in the business document (%s) " +#~ "doesn't match the VAT number of the company '%s' (%s) in which you are " +#~ "trying to import this document." +#~ msgstr "" +#~ "Le numéro de TVA du client indiqué dans le document commercial (%s) ne " +#~ "correspond pas au numéro de TVA de la société '%s' (%s) dans laquelle " +#~ "vous essayez d'importer ce document." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the country code " +#~ "to find the related currency. But the country '%s' doesn't have any " +#~ "related currency configured in Odoo." +#~ msgstr "" +#~ "L'analyse du document commercial a retourné '%s' comme code de pays pour " +#~ "trouver la devise associée. Mais le pays '%s' n'a pas de devise associée " +#~ "configurée dans Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the currency " +#~ "symbol or ISO code. But there are none or several currencies with the " +#~ "symbol/ISO code in Odoo." +#~ msgstr "" +#~ "L'analyse du document commercial a donné '%s' comme symbole monétaire ou " +#~ "code ISO. Mais il n'y a pas ou plusieurs devises avec ce symbole/code ISO " +#~ "dans Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the unit of " +#~ "measure UNECE code, but there is no unit of measure with that UNECE code " +#~ "in Odoo. Please check the configuration of the units of measures in Odoo." +#~ msgstr "" +#~ "L'analyse du document commercial a donné '%s' comme code d'unité de " +#~ "mesure UNECE, mais il n'y a pas d'unité de mesure avec ce code UNECE dans " +#~ "Odoo. Veuillez vérifier la configuration des unités de mesure dans Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned IBAN %s as bank " +#~ "account, but there is no such bank account in Odoo linked to partner %s and the option to " +#~ "automatically create bank accounts upon import is disabled." +#~ msgstr "" +#~ "L'analyse du document commercial a renvoyé IBAN %s comme compte " +#~ "bancaire, mais il n'y a pas de tel compte bancaire dans Odoo lié au " +#~ "partenaire %s et " +#~ "l'option de création automatique de comptes bancaires à l'importation est " +#~ "désactivée." + +#, python-format +#~ msgid "" +#~ "The bank account IBAN %s has been automatically added on the " +#~ "supplier %s" +#~ msgstr "" +#~ "Le compte bancaire IBAN %s a été automatiquement ajouté sur le " +#~ "fournisseur %s" diff --git a/base_business_document_import/i18n/fr_FR.po b/base_business_document_import/i18n/fr_FR.po new file mode 100644 index 0000000000..9f10c2c1c6 --- /dev/null +++ b/base_business_document_import/i18n/fr_FR.po @@ -0,0 +1,598 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_business_document_import +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-15 17:46+0000\n" +"Last-Translator: Yves Le Doeuff \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" +"X-Generator: Weblate 4.3.2\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "(fixed)" +msgstr "(fixe)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in file %s:" +msgstr "Notes dans le fichier %s:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in imported document:" +msgstr "Notes dans le document importé:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"

    Odoo couldn't find any unit of measure corresponding to the following " +"information extracted from the business document:

    • UNECE code: " +"%(code)s
    • Name of the unit of measure: %(name)s

    So the " +"unit of measure 'Unit(s)' has been used. You may have to change it " +"manually.

    " +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Approximate match: account %(account)s has been matched with account " +"%(matched_account)s" +msgstr "" + +#. module: base_business_document_import +#: model:ir.model,name:base_business_document_import.model_business_document_import +msgid "Common methods to import business documents" +msgstr "Méthodes courantes d'importation de documents commerciaux" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Could not find any Incoterm in Odoo corresponding to '%s'" +msgstr "Impossible de trouver un Incoterm dans Odoo correspondant à '%s'" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"For product '%(product)s', the unit of measure is %(uom_product)s on the " +"existing line, but it is %(uom_imported)s on the imported line.We don't " +"support this scenario for the moment, so the lines haven't been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "IBAN %s is not valid, so it has been ignored." +msgstr "L'IBAN %s n'est pas valide, il a donc été ignoré." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "ID {id} of '{model}' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Missing VAT number on company '%s'" +msgstr "Numéro de TVA manquant pour la société '%s'" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "No currency specified, so Odoo used the company currency (%s)" +msgstr "" +"Pas de devise précisée, donc Odoo a utilisé la devise (%s) de la société" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any %(label)s corresponding to the following information " +"extracted from the business document:\n" +"Name: %(name)s \n" +"VAT number: %(vat)s \n" +"Reference: %(ref)s \n" +"E-mail: %(email)s \n" +"Website: %(website)s \n" +"State code: %(state)s \n" +"Country code: %(country)s \n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any account corresponding to the following information " +"extracted from the business document:\n" +"Account code: %s" +msgstr "" +"Odoo n'a pas trouvé de compte correspondant aux informations suivantes " +"extraites du document commercial :\n" +"Code du compte : %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any analytic account corresponding to the following " +"information extracted from the business document:\n" +"Analytic account code: %s" +msgstr "" +"Odoo n'a pas trouvé de compte analytique correspondant aux informations " +"suivantes extraites du document commercial :\n" +"Code du compte analytique : %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any journal corresponding to the following information " +"extracted from the business document:\n" +"Journal code: %s" +msgstr "" +"Odoo n'a pas trouvé de journal correspondant aux informations suivantes " +"extraites du document commercial :\n" +"Code journal : %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any product corresponding to the following information " +"extracted from the business document:\n" +"Barcode: %(barcode)s\n" +"Product code: %(product_code)s\n" +"Supplier: %(supplier)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any shipping partner corresponding to the following " +"information extracted from the business document:\n" +"Name: %(name)s\n" +"VAT number: %(vat)s\n" +"Reference: %(ref)s\n" +"E-mail: %(email)s\n" +"Website: %(website)s\n" +"Street: %(street)s\n" +"Street2: %(street2)s\n" +"City: %(city)s\n" +"ZIP: %(zip)s\n" +"State code: %(state)s\n" +"Country code: %(country)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax " +"Included in Price' = '%(price)s' which correspond to the following " +"information extracted from the business document:\n" +"UNECE Tax Type code: %(tax_type)s\n" +"UNECE Tax Category code: %(tax_cat)s\n" +"UNECE Due Date code: %(tax_due_date)s\n" +"Tax amount: %(amount)s %(amount_type)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"One of the imported lines doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"Une des lignes importées n'a pas de produit, donc les lignes n'ont pas " +"été mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The %(label)s has been identified by the domain name '%(domain)s' so please " +"check carefully that the %(label)s is correct." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The VAT number of the customer written in the business document " +"(%(parsed_vat)s) doesn't match the VAT number of the company " +"'%(company)s' (%(vat)s) in which you are trying to import this document." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "The XMLID '%s' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the country " +"code to find the related currency. But the country '%(name)s' doesn't have " +"any related currency configured in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the currency " +"symbol or ISO code. But there are none or several currencies with the symbol/" +"ISO code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the unit of " +"measure UNECE code, but there is no unit of measure with that UNECE code in " +"Odoo. Please check the configuration of the units of measures in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as country code. But " +"there are no country with that code in Odoo." +msgstr "" +"L'analyse du document commercial a retourné '%s' comme code de pays. Mais il " +"n'y a pas de pays avec ce code dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the country code to " +"find the related currency. But there is no country with that code in Odoo." +msgstr "" +"L'analyse du document commercial a renvoyé '%s' comme code de pays pour " +"trouver la devise correspondante. Mais il n'y a pas de pays avec ce code " +"dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency ISO " +"code. But there are no currency with that code in Odoo." +msgstr "" +"L'analyse du document commercial a donné '%s' comme code ISO de la devise. " +"Mais il n'y a pas de devise avec ce code dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency symbol. " +"But there are none or several currencies with that symbol in Odoo." +msgstr "" +"L'analyse du document commercial a donné '%s' comme symbole de devise. Mais " +"il n'y a pas ou plusieurs devises avec ce symbole dans Odoo." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned IBAN %(iban)s as bank " +"account, but there is no such bank account in Odoo linked to partner %(partner)s " +"and the option to automatically create bank accounts upon import is disabled." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The bank account IBAN %(iban)s has been automatically added on the " +"supplier " +"%(partner)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The existing line '%s' doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"La ligne existante '%s' n'a pas de produit, donc les lignes n'ont pas été " +"mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several existing lines, so the lines haven't " +"been updated." +msgstr "" +"Le produit '%s' est utilisé sur plusieurs lignes existantes, donc les " +"lignes n'ont pas été mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several imported lines, so the lines haven't " +"been updated." +msgstr "" +"Le produit '%s' est utilisé sur plusieurs lignes importées, donc les " +"lignes n'ont pas été mises à jour." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The record '{record}' is an instance of '{record_model}', not of " +"'{target_model}'." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "customer" +msgstr "client" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "partner" +msgstr "partenaire" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "supplier" +msgstr "fournisseur" + +#, python-format +#~ msgid "" +#~ "

    Odoo couldn't find any unit of measure corresponding to the following " +#~ "information extracted from the business document:

    • UNECE code: " +#~ "%s
    • Name of the unit of measure: %s

    So the unit of " +#~ "measure 'Unit(s)' has been used. You may have to change it manually.

    " +#~ msgstr "" +#~ "

    Odoo n'a pas trouvé d'unité de mesure correspondant aux informations " +#~ "suivantes extraites du document métier :

    • Code UNECE : %s
    • Nom de l'unité de mesure : %s

    L'unité de mesure " +#~ "'Unité(s)' a donc été utilisée. Vous devrez peut-être la modifier " +#~ "manuellement.

    " + +#, python-format +#~ msgid "Approximate match: account %s has been matched with account %s" +#~ msgstr "" +#~ "Correspondance approximative : le compte %s a été mis en correspondance " +#~ "avec le compte %s" + +#~ msgid "Display Name" +#~ msgstr "Nom affiché" + +#, python-format +#~ msgid "" +#~ "For product '%s', the unit of measure is %s on the existing line, but it " +#~ "is %s on the imported line. We don't support this scenario for the " +#~ "moment, so the lines haven't been updated." +#~ msgstr "" +#~ "Pour le produit '%s', l'unité de mesure est %s sur la ligne existante, " +#~ "mais elle est %s sur la ligne importée. Nous ne supportons pas ce " +#~ "scénario pour le moment, donc les lignes n'ont pas été mises à jour." + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any %s corresponding to the following information " +#~ "extracted from the business document:\n" +#~ "Name: %s\n" +#~ "VAT number: %s\n" +#~ "Reference: %s\n" +#~ "E-mail: %s\n" +#~ "Website: %s\n" +#~ "State code: %s\n" +#~ "Country code: %s\n" +#~ msgstr "" +#~ "Odoo n'a pas trouvé de %s correspondant aux informations suivantes " +#~ "extraites du document commercial :\n" +#~ "Nom : %s\n" +#~ "Numéro de TVA : %s\n" +#~ "Référence : %s\n" +#~ "E-mail : %s\n" +#~ "Site web : %s\n" +#~ "Code de l'État : %s\n" +#~ "Code du pays : %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any product corresponding to the following information " +#~ "extracted from the business document:\n" +#~ "Barcode: %s\n" +#~ "Product code: %s\n" +#~ "Supplier: %s\n" +#~ msgstr "" +#~ "Odoo n'a pas pu trouver de produit correspondant aux informations " +#~ "suivantes extraites du document commercial :\n" +#~ "Code barres : %s\n" +#~ "Code produit : %s\n" +#~ "Fournisseur : %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any shipping partner corresponding to the following " +#~ "information extracted from the business document:\n" +#~ "Name: %s\n" +#~ "VAT number: %s\n" +#~ "Reference: %s\n" +#~ "E-mail: %s\n" +#~ "Website: %s\n" +#~ "Street: %s\n" +#~ "Street2: %s\n" +#~ "City: %s\n" +#~ "ZIP: %s\n" +#~ "State code: %s\n" +#~ "Country code: %s\n" +#~ msgstr "" +#~ "Odoo n'a pas pu trouver de partenaire d'expédition correspondant aux " +#~ "informations suivantes extraites du document commercial :\n" +#~ "Nom : %s\n" +#~ "Numéro de TVA : %s\n" +#~ "Référence : %s\n" +#~ "E-mail : %s\n" +#~ "Site web : %s\n" +#~ "Rue : %s\n" +#~ "Rue2 : %s\n" +#~ "Ville : %s\n" +#~ "Code postal : %s\n" +#~ "Code d'état : %s\n" +#~ "Code du pays : %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any tax with 'Tax Application' = '%s' and 'Tax " +#~ "Included in Price' = '%s' which correspond to the following information " +#~ "extracted from the business document:\n" +#~ "UNECE Tax Type code: %s\n" +#~ "UNECE Tax Category code: %s\n" +#~ "UNECE Due Date code: %s\n" +#~ "Tax amount: %s %s" +#~ msgstr "" +#~ "Odoo n'a pas trouvé de taxe avec 'Application de taxe' = '%s' et 'Taxe " +#~ "Incluse dans le prix' = '%s' qui correspondent aux informations suivantes " +#~ "extraites du document commercial :\n" +#~ "Code de type de taxe CEE-ONU : %s\n" +#~ "Code de catégorie de taxe CEE-ONU : %s\n" +#~ "Code de la date d'échéance CEE-ONU : %s\n" +#~ "Montant de la taxe : %s %s" + +#, python-format +#~ msgid "" +#~ "The %s has been identified by the domain name '%s' so please check " +#~ "carefully that the %s is correct." +#~ msgstr "" +#~ "Le %s a été identifié par le nom de domaine '%s'. Veuillez vérifier " +#~ "soigneusement que le %s est correct." + +#, python-format +#~ msgid "" +#~ "The VAT number of the customer written in the business document (%s) " +#~ "doesn't match the VAT number of the company '%s' (%s) in which you are " +#~ "trying to import this document." +#~ msgstr "" +#~ "Le numéro de TVA du client indiqué dans le document commercial (%s) ne " +#~ "correspond pas au numéro de TVA de la société '%s' (%s) dans laquelle " +#~ "vous essayez d'importer ce document." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the country code " +#~ "to find the related currency. But the country '%s' doesn't have any " +#~ "related currency configured in Odoo." +#~ msgstr "" +#~ "L'analyse du document commercial a retourné '%s' comme code de pays pour " +#~ "trouver la devise associée. Mais le pays '%s' n'a pas de devise associée " +#~ "configurée dans Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the currency " +#~ "symbol or ISO code. But there are none or several currencies with the " +#~ "symbol/ISO code in Odoo." +#~ msgstr "" +#~ "L'analyse du document commercial a donné '%s' comme symbole monétaire ou " +#~ "code ISO. Mais il n'y a pas ou plusieurs devises avec ce symbole/code ISO " +#~ "dans Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the unit of " +#~ "measure UNECE code, but there is no unit of measure with that UNECE code " +#~ "in Odoo. Please check the configuration of the units of measures in Odoo." +#~ msgstr "" +#~ "L'analyse du document commercial a donné '%s' comme code d'unité de " +#~ "mesure UNECE, mais il n'y a pas d'unité de mesure avec ce code UNECE dans " +#~ "Odoo. Veuillez vérifier la configuration des unités de mesure dans Odoo." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned IBAN %s as bank " +#~ "account, but there is no such bank account in Odoo linked to partner %s and the option to " +#~ "automatically create bank accounts upon import is disabled." +#~ msgstr "" +#~ "L'analyse du document commercial a retourné IBAN %s comme compte " +#~ "bancaire, mais il n'y a pas de tel compte bancaire dans Odoo lié au " +#~ "partenaire %s et " +#~ "l'option de création automatique de comptes bancaires lors de " +#~ "l'importation est désactivée." + +#, python-format +#~ msgid "" +#~ "The bank account IBAN %s has been automatically added on the " +#~ "supplier %s" +#~ msgstr "" +#~ "Le compte bancaire IBAN %s a été automatiquement ajouté sur le " +#~ "fournisseur %s" diff --git a/base_business_document_import/i18n/nl.po b/base_business_document_import/i18n/nl.po new file mode 100644 index 0000000000..15d0d8aa2f --- /dev/null +++ b/base_business_document_import/i18n/nl.po @@ -0,0 +1,598 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_business_document_import +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-02-07 12:22+0000\n" +"Last-Translator: Bosd \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.14.1\n" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, fuzzy, python-format +msgid "(fixed)" +msgstr "(fixed)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in file %s:" +msgstr "Notities in bestand %s:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Notes in imported document:" +msgstr "Notities in geimporteerd document:" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"

    Odoo couldn't find any unit of measure corresponding to the following " +"information extracted from the business document:

    • UNECE code: " +"%(code)s
    • Name of the unit of measure: %(name)s

    So the " +"unit of measure 'Unit(s)' has been used. You may have to change it " +"manually.

    " +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Approximate match: account %(account)s has been matched with account " +"%(matched_account)s" +msgstr "" + +#. module: base_business_document_import +#: model:ir.model,name:base_business_document_import.model_business_document_import +msgid "Common methods to import business documents" +msgstr "Algemene procedures voor het importeren van bedrijfsdocumenten" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Could not find any Incoterm in Odoo corresponding to '%s'" +msgstr "Er kong geen Incoterm gevonden worden overeenkomstig met '%s'" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"For product '%(product)s', the unit of measure is %(uom_product)s on the " +"existing line, but it is %(uom_imported)s on the imported line.We don't " +"support this scenario for the moment, so the lines haven't been updated." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "IBAN %s is not valid, so it has been ignored." +msgstr "IBAN %s is ongeldig, dus genegeerd." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "ID {id} of '{model}' doesn't exist in Odoo." +msgstr "ID {id} van '{model}' bestaat niet." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "Missing VAT number on company '%s'" +msgstr "Ontbrekent BTW nummer voor bedrijf '%s'" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "No currency specified, so Odoo used the company currency (%s)" +msgstr "" +"Er is geen valuta gespicificeerd, dus de bedrijfsvaluta wordt gebruikt (%s)" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any %(label)s corresponding to the following information " +"extracted from the business document:\n" +"Name: %(name)s \n" +"VAT number: %(vat)s \n" +"Reference: %(ref)s \n" +"E-mail: %(email)s \n" +"Website: %(website)s \n" +"State code: %(state)s \n" +"Country code: %(country)s \n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any account corresponding to the following information " +"extracted from the business document:\n" +"Account code: %s" +msgstr "" +"kon geen rekening vinden welke overeenkomt met de verkregen informatie uit " +"dit bedrijfsdocument:\n" +"Rekening code: %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any analytic account corresponding to the following " +"information extracted from the business document:\n" +"Analytic account code: %s" +msgstr "" +"kon geen analytisch account vinden welke overeenkomt met de verkregen " +"informatie uit dit bedrijfsdocument:\n" +"Analytisch account code: %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any journal corresponding to the following information " +"extracted from the business document:\n" +"Journal code: %s" +msgstr "" +"kon geen dagboek vinden welke overeenkomt met de verkregen informatie uit " +"dit bedrijfsdocument:\n" +"Dagboek code: %s" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any product corresponding to the following information " +"extracted from the business document:\n" +"Barcode: %(barcode)s\n" +"Product code: %(product_code)s\n" +"Supplier: %(supplier)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any shipping partner corresponding to the following " +"information extracted from the business document:\n" +"Name: %(name)s\n" +"VAT number: %(vat)s\n" +"Reference: %(ref)s\n" +"E-mail: %(email)s\n" +"Website: %(website)s\n" +"Street: %(street)s\n" +"Street2: %(street2)s\n" +"City: %(city)s\n" +"ZIP: %(zip)s\n" +"State code: %(state)s\n" +"Country code: %(country)s\n" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' and 'Tax " +"Included in Price' = '%(price)s' which correspond to the following " +"information extracted from the business document:\n" +"UNECE Tax Type code: %(tax_type)s\n" +"UNECE Tax Category code: %(tax_cat)s\n" +"UNECE Due Date code: %(tax_due_date)s\n" +"Tax amount: %(amount)s %(amount_type)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"One of the imported lines doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"Een van de geimporteede regels bevat geen product, dus de regels zijn " +"niet bijgewerkt." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The %(label)s has been identified by the domain name '%(domain)s' so please " +"check carefully that the %(label)s is correct." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The VAT number of the customer written in the business document " +"(%(parsed_vat)s) doesn't match the VAT number of the company " +"'%(company)s' (%(vat)s) in which you are trying to import this document." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "The XMLID '%s' doesn't exist in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the country " +"code to find the related currency. But the country '%(name)s' doesn't have " +"any related currency configured in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the currency " +"symbol or ISO code. But there are none or several currencies with the symbol/" +"ISO code in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%(code)s' as the unit of " +"measure UNECE code, but there is no unit of measure with that UNECE code in " +"Odoo. Please check the configuration of the units of measures in Odoo." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as country code. But " +"there are no country with that code in Odoo." +msgstr "" +"De analyse van het bedrijfsdocument leverde landcode '%s' op. Deze landcode " +"is niet bekend in het systeem." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the country code to " +"find the related currency. But there is no country with that code in Odoo." +msgstr "" +"De analyse van het bedrijfsdocument leverde '%s' op als de landcode om de " +"bijbehorende valuta te vinden. Maar deze landcode is niet bekend in het " +"systeem." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency ISO " +"code. But there are no currency with that code in Odoo." +msgstr "" +"De analyse van het bedrijfsdocument leverde '%s' op als de valuta ISO code. " +"Er is geen valuta met deze code bekend in het systeem." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned '%s' as the currency symbol. " +"But there are none or several currencies with that symbol in Odoo." +msgstr "" +"De analyse van het bedrijfsdocument leverde '%s' op als de valutateken. Er " +"zijn geen of meerdre valutas met dat valutateken in het systeem." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The analysis of the business document returned IBAN %(iban)s as bank " +"account, but there is no such bank account in Odoo linked to partner %(partner)s " +"and the option to automatically create bank accounts upon import is disabled." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The bank account IBAN %(iban)s has been automatically added on the " +"supplier " +"%(partner)s" +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The existing line '%s' doesn't have any product, so the lines haven't " +"been updated." +msgstr "" +"De bestaande regel '%s' heeft geen product, dus de regel is niet " +"bijgewerkt." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several existing lines, so the lines haven't " +"been updated." +msgstr "" +"Het product '%s' is gebruikt op meerdere bestaande regels, dus de regels " +"zijn niet bijgewerkt." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The product '%s' is used on several imported lines, so the lines haven't " +"been updated." +msgstr "" +"Het product '%s' is gebruikt op meerdere geimporteerde regels, dus de " +"regels zijn niet bijgewerkt." + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "" +"The record '{record}' is an instance of '{record_model}', not of " +"'{target_model}'." +msgstr "" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "customer" +msgstr "klant" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "partner" +msgstr "relatie" + +#. module: base_business_document_import +#. odoo-python +#: code:addons/base_business_document_import/models/business_document_import.py:0 +#, python-format +msgid "supplier" +msgstr "leverancier" + +#, python-format +#~ msgid "" +#~ "

    Odoo couldn't find any unit of measure corresponding to the following " +#~ "information extracted from the business document:

    • UNECE code: " +#~ "%s
    • Name of the unit of measure: %s

    So the unit of " +#~ "measure 'Unit(s)' has been used. You may have to change it manually.

    " +#~ msgstr "" +#~ "

    Er kon geen eenheid gevonden worden welke overeenkomt met de volgende " +#~ "informatie verkregen uit het bedrijfsdocument:

    • UNECE code: %s
    • Eenheidsnaam: %s

    dus de 'Unit(s)' eenheid is gebruikt. " +#~ "Wellicht wilt u dit handmatig wijzigen.

    " + +#, python-format +#~ msgid "Approximate match: account %s has been matched with account %s" +#~ msgstr "Geschatte overeenkomst: rekening %s is gematched met rekening %s" + +#~ msgid "Display Name" +#~ msgstr "Weergavenaam" + +#, python-format +#~ msgid "" +#~ "For product '%s', the unit of measure is %s on the existing line, but it " +#~ "is %s on the imported line. We don't support this scenario for the " +#~ "moment, so the lines haven't been updated." +#~ msgstr "" +#~ "voor product '%s', is de eenheid %s op de bestaande regel, maar is %s op " +#~ "de geimporteerde regel. Dit wordt op dit moment niet ondersteund, de " +#~ "regels zijnnietbijgewerkt." + +#, fuzzy +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Laatst bijgewerkt op" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any %s corresponding to the following information " +#~ "extracted from the business document:\n" +#~ "Name: %s\n" +#~ "VAT number: %s\n" +#~ "Reference: %s\n" +#~ "E-mail: %s\n" +#~ "Website: %s\n" +#~ "State code: %s\n" +#~ "Country code: %s\n" +#~ msgstr "" +#~ "Er kon geen %s gevonden worden welke overeenkomt met de informatie " +#~ "verkregen uit het document:\n" +#~ "Naam: %s\n" +#~ "BTW nummer: %s\n" +#~ "Referentie: %s\n" +#~ "E-mail: %s\n" +#~ "Website: %s\n" +#~ "State code: %s\n" +#~ "Land code: %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any product corresponding to the following information " +#~ "extracted from the business document:\n" +#~ "Barcode: %s\n" +#~ "Product code: %s\n" +#~ "Supplier: %s\n" +#~ msgstr "" +#~ "Er kon geen product gevonden worden welke overeenkomt met de verkregen " +#~ "informatie uit het document:\n" +#~ "Barcode: %s\n" +#~ "Product code: %s\n" +#~ "Leverancier: %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any shipping partner corresponding to the following " +#~ "information extracted from the business document:\n" +#~ "Name: %s\n" +#~ "VAT number: %s\n" +#~ "Reference: %s\n" +#~ "E-mail: %s\n" +#~ "Website: %s\n" +#~ "Street: %s\n" +#~ "Street2: %s\n" +#~ "City: %s\n" +#~ "ZIP: %s\n" +#~ "State code: %s\n" +#~ "Country code: %s\n" +#~ msgstr "" +#~ "Er kon geen geadresseerde relatie gevonden worden welke overeenkomt met " +#~ "de verkregen informatie uit dit bedrijfsdocument:\n" +#~ "Naam: %s\n" +#~ "BTW nummer: %s\n" +#~ "Referentie: %s\n" +#~ "E-mail: %s\n" +#~ "Website: %s\n" +#~ "Straat: %s\n" +#~ "Straat2: %s\n" +#~ "Woonplaats: %s\n" +#~ "Postcode: %s\n" +#~ "State code: %s\n" +#~ "Land code: %s\n" + +#, python-format +#~ msgid "" +#~ "Odoo couldn't find any tax with 'Tax Application' = '%s' and 'Tax " +#~ "Included in Price' = '%s' which correspond to the following information " +#~ "extracted from the business document:\n" +#~ "UNECE Tax Type code: %s\n" +#~ "UNECE Tax Category code: %s\n" +#~ "UNECE Due Date code: %s\n" +#~ "Tax amount: %s %s" +#~ msgstr "" +#~ "Er kon geen belastingsregel gevonden worden 'Tax Application' = '%s' en " +#~ "'prijs inclusief btw' = '%s' welke overeenkomt met de volgende informatie " +#~ "verkregen uit dit bedrijfsdocument:\n" +#~ "UNECE Tax Type code: %s\n" +#~ "UNECE Tax Category code: %s\n" +#~ "UNECE Due Date code: %s\n" +#~ "Belast bedrag: %s %s" + +#, python-format +#~ msgid "" +#~ "The %s has been identified by the domain name '%s' so please check " +#~ "carefully that the %s is correct." +#~ msgstr "" +#~ "Het %s is geidentificeerd op de domeinnaam '%s' controleer zorgvuldig " +#~ "daat de %s juist is." + +#, python-format +#~ msgid "" +#~ "The VAT number of the customer written in the business document (%s) " +#~ "doesn't match the VAT number of the company '%s' (%s) in which you are " +#~ "trying to import this document." +#~ msgstr "" +#~ "Het BTW nummer van de klant in het bedrijfsdocument (%s) komt niet " +#~ "overeen met het BTW nummer van het bedrijf '%s' (%s) waarvoor je een " +#~ "document probeert te importeren." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the country code " +#~ "to find the related currency. But the country '%s' doesn't have any " +#~ "related currency configured in Odoo." +#~ msgstr "" +#~ "De analyse van het bedrijfsdocument leverde '%s' op als de landcode om de " +#~ "bijbehorende valuta te vinden. Maar voor het land '%s' zijn geen " +#~ "bijbehorende valuta's geconfigureerd." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the currency " +#~ "symbol or ISO code. But there are none or several currencies with the " +#~ "symbol/ISO code in Odoo." +#~ msgstr "" +#~ "De analyse van het bedrijfsdocument leverde '%s' op als het valuta " +#~ "symbool of ISO code. Er zijn geen of meerdere valuta met dit symbool/code " +#~ "bekend in het systeem." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned '%s' as the unit of " +#~ "measure UNECE code, but there is no unit of measure with that UNECE code " +#~ "in Odoo. Please check the configuration of the units of measures in Odoo." +#~ msgstr "" +#~ "De analyse van het bedrijfsdocument leverde '%s' als eenheids UNECE code, " +#~ "maar er is geen eenheid met die UNECE code in het systeem. Controleer de " +#~ "eenheidsinstellingen." + +#, python-format +#~ msgid "" +#~ "The analysis of the business document returned IBAN %s as bank " +#~ "account, but there is no such bank account in Odoo linked to partner %s and the option to " +#~ "automatically create bank accounts upon import is disabled." +#~ msgstr "" +#~ "De analyse van het bedrijfsdocument leverde IBAN %s op als " +#~ "bankrekening, maar het bankrekeningnummer is niet toegewezen aan relatie " +#~ "%s en de " +#~ "mogelijkheid om automatisch bankrekeningen aan te maken tijdens de import " +#~ "van bedrijfsdocumenten is uitgeschakeld." + +#, python-format +#~ msgid "" +#~ "The bank account IBAN %s has been automatically added on the " +#~ "supplier %s" +#~ msgstr "" +#~ "Het bankrekeningnummerIBAN %s is automatisch toegevoegd aan de " +#~ "leverancier %s" diff --git a/base_business_document_import/models/__init__.py b/base_business_document_import/models/__init__.py new file mode 100644 index 0000000000..d695bc5f59 --- /dev/null +++ b/base_business_document_import/models/__init__.py @@ -0,0 +1 @@ +from . import business_document_import diff --git a/base_business_document_import/models/business_document_import.py b/base_business_document_import/models/business_document_import.py new file mode 100644 index 0000000000..75932a0d48 --- /dev/null +++ b/base_business_document_import/models/business_document_import.py @@ -0,0 +1,1398 @@ +# Copyright 2015-2021 Akretion France +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from urllib.parse import urlparse + +from odoo import _, api, models +from odoo.exceptions import UserError +from odoo.osv import expression +from odoo.tools import float_compare + +from odoo.addons.base_iban.models.res_partner_bank import validate_iban + +logger = logging.getLogger(__name__) + + +class BusinessDocumentImport(models.AbstractModel): + _name = "business.document.import" + _description = "Common methods to import business documents" + + @api.model + def user_error_wrap(self, method, data_dict, error_msg): + """The method and data_dict arguments are useful when you want to + inherit this method to update the error messag_match_currencye""" + assert error_msg + raise UserError(error_msg) + + def _direct_match(self, data_dict, model, raise_exception=True): + if data_dict.get("recordset"): + record = data_dict["recordset"] + if isinstance(record, type(model)): + return record + elif raise_exception: + raise UserError( + _( + "The record '{record}' is an instance of '{record_model}', " + "not of '{target_model}'." + ).format( + record=record.display_name, + record_model=record._name, + target_model=model._name, + ) + ) + if data_dict.get("id"): + record = model.browse(data_dict["id"]).exists() + if not record and raise_exception: + raise UserError( + _("ID {id} of '{model}' doesn't exist in Odoo.").format( + id=data_dict["id"], model=model._name + ) + ) + if record: + return record + if data_dict.get("xmlid"): + xmlid = data_dict["xmlid"] + record = False + try: + record = self.env.ref(xmlid, raise_if_not_found=True) + except Exception as e: + if raise_exception: + raise UserError( + _("The XMLID '%s' doesn't exist in Odoo.") % xmlid + ) from e + if record: + if isinstance(record, type(model)): + return record + elif raise_exception: + raise UserError( + _( + "The record '{record}' is an instance of '{record_model}', " + "not of '{target_model}'." + ).format( + record=record.display_name, + record_model=record._name, + target_model=model._name, + ) + ) + return None + + @api.model + def _strip_cleanup_dict(self, match_dict): + if not match_dict: + return + + for key, value in match_dict.items(): + if value and isinstance(value, str): + match_dict[key] = value.strip() + if match_dict.get("country_code"): + match_dict["country_code"] = match_dict["country_code"].upper() + if match_dict.get("state_code"): + match_dict["state_code"] = match_dict["state_code"].upper() + + @api.model + def _get_match_partner_order(self, partner_type): + if partner_type == "supplier": + return "supplier_rank desc" + if partner_type == "customer": + return "customer_rank desc" + return "" + + @api.model + def _get_match_partner_type_label(self, partner_type): + if partner_type == "supplier": + return _("supplier") + if partner_type == "customer": + return _("customer") + return _("partner") + + @api.model + def _get_country_filter(self, partner_dict, chatter_msg): + """Generate filter by country""" + if partner_dict.get("country_code"): + country = self.env["res.country"].search( + [("code", "=", partner_dict["country_code"])], limit=1 + ) + if country: + return [ + "|", + ("country_id", "=", False), + ("country_id", "=", country.id), + ] + chatter_msg.append( + _( + "The analysis of the business document returned '%s' as " + "country code. But there are no country with that code " + "in Odoo." + ) + % partner_dict["country_code"] + ) + return False + + @api.model + def _get_country_state_filter(self, partner_dict, chatter_msg): + if partner_dict.get("state_code"): + country = self.env["res.country"].search( + [("code", "=", partner_dict["country_code"])], limit=1 + ) + if state := self.env["res.country.state"].search( + [ + ("code", "=", partner_dict["state_code"]), + ("country_id", "=", country.id), + ], + limit=1, + ): + return ["|", ("state_id", "=", False), ("state_id", "=", state.id)] + return False + + @api.model + def _match_partner_ref(self, partner_dict, chatter_msg, domain, order): + """If a ref is explicitly given, we just want to match that partner""" + if partner_dict.get("ref"): + domain = expression.AND( + [ + domain, + [("ref", "=", partner_dict["ref"])], + ] + ) + return self.env["res.partner"].search(domain, limit=1, order=order) + return False + + @api.model + def _match_partner_contact(self, partner_dict, chatter_msg, domain, order): + rpo = self.env["res.partner"] + if partner_dict.get("email") and "@" in partner_dict["email"]: + if partner := rpo.search( + expression.AND( + [ + domain, + [("email", "=ilike", partner_dict["email"])], + ] + ), + limit=1, + order=order, + ): + return partner + if partner_dict.get("contact"): + if partner := rpo.search( + expression.AND( + [ + domain, + [("name", "=ilike", partner_dict["contact"])], + ] + ), + limit=1, + order=order, + ): + return partner + if partner_dict.get("phone"): + if partner := rpo.search( + expression.AND( + [ + domain, + [ + "|", + ("mobile", "=", partner_dict["phone"]), + ("phone", "=", partner_dict["phone"]), + ], + ] + ), + limit=1, + order=order, + ): + return partner + return False + + @api.model + def _match_partner_name(self, partner_dict, chatter_msg, domain, order): + if partner_dict.get("name"): + domain = expression.AND( + [ + domain, + [ + ("name", "=ilike", partner_dict["name"]), + ], + ] + ) + return self.env["res.partner"].search(domain, limit=1, order=order) + return False + + @api.model + def _get_partner_website_domain(self, partner_dict): + if not partner_dict.get("website"): + return False + + urlp = urlparse(partner_dict["website"]) + netloc = urlp.netloc + if not urlp.scheme and not netloc: + netloc = urlp.path + if netloc and len(netloc.split(".")) >= 2: + return ".".join(netloc.split(".")[-2:]) + + @api.model + def _match_partner_website(self, partner_dict, chatter_msg, domain, order): + if website_domain := self._get_partner_website_domain(partner_dict): + domain = expression.AND( + [ + domain, + [ + ("website", "=ilike", "%" + website_domain + "%"), + ], + ] + ) + return self.env["res.partner"].search(domain, limit=1, order=order) + return False + + @api.model + def _get_partner_email_domain(self, partner_dict): + return ( + partner_dict.get("email") + and "@" in partner_dict["email"] + and partner_dict["email"].split("@")[1] + ) + + @api.model + def _match_partner_email(self, partner_dict, chatter_msg, domain, order): + email_domain = self._get_partner_email_domain(partner_dict) + # I can't search on email addresses with + # email_domain because of the emails such as + # @gmail.com, @yahoo.com that may match random partners + if email_domain: + partner = self.env["res.partner"].search( + expression.AND( + [domain, [("website", "=ilike", "%" + email_domain + "%")]] + ), + limit=1, + order=order, + ) + if not partner: + partner = self.env["res.partner"].search( + expression.AND( + [domain, [("email", "=ilike", "%@" + email_domain)]] + ), + limit=1, + order=order, + ) + if partner: + partner_type_label = partner_dict["type_label"] + chatter_msg.append( + _( + "The %(label)s has been identified by the domain name " + "'%(domain)s' so please check carefully that the " + "%(label)s is correct.", + label=partner_type_label, + domain=domain, + ) + ) + return partner + + @api.model + def _match_partner( # noqa: C901 + self, + partner_dict, + chatter_msg, + partner_type="supplier", + domain=None, + raise_exception=True, + ): + """Example: + partner_dict = { + 'country_code': 'FR', + 'state_code': False, + 'vat': 'FR12448890432', + 'email': 'roger.lemaire@akretion.com', + 'website': 'www.akretion.com', + 'name': 'Akretion France', + 'ref': 'C1242', + 'phone': '01.41.98.12.42', + } + """ + rpo = self.env["res.partner"] + partner_dict = partner_dict.copy() + self._strip_cleanup_dict(partner_dict) + partner = self._direct_match(partner_dict, rpo, raise_exception=raise_exception) + if partner: + return partner + company_id = self._context.get("force_company") or self.env.company.id + domain = domain or [] + domain = expression.AND( + [ + domain, + [ + "|", + ("company_id", "=", False), + ("company_id", "=", company_id), + ], + ] + ) + order = self._get_match_partner_order(partner_type) + partner_type_label = self._get_match_partner_type_label(partner_type) + partner_dict["type"] = partner_type + partner_dict["type_label"] = partner_type_label + + partner = self._match_partner_ref(partner_dict, chatter_msg, domain, order) + if partner: + return partner + + if country_domain := self._get_country_filter(partner_dict, chatter_msg): + domain = expression.AND([domain, country_domain]) + + if state_domain := self._get_country_state_filter( + partner_dict, chatter_msg + ): + domain = expression.AND([domain, state_domain]) + + # Search on VAT + if partner_dict.get("vat"): + vat = partner_dict["vat"].replace(" ", "").upper() + partner = rpo.search( + expression.AND([domain, [("vat", "=", vat)]]), + limit=1, + order=order, + ) + if partner: + return partner + + # Hook to plug alternative matching methods + partner = self._hook_match_partner(partner_dict, chatter_msg, domain, order) + if partner: + return partner + + # Search for partner contact + partner = self._match_partner_contact(partner_dict, chatter_msg, domain, order) + if partner: + return partner + + # Search for partner name + partner = self._match_partner_name(partner_dict, chatter_msg, domain, order) + if partner: + return partner + + # Search for partner website + partner = self._match_partner_website(partner_dict, chatter_msg, domain, order) + if partner: + return partner + + # Search for partner website + partner = self._match_partner_email(partner_dict, chatter_msg, domain, order) + if partner: + return partner + + if not raise_exception: + return None + raise self.user_error_wrap( + "_match_partner", + partner_dict, + _( + "Odoo couldn't find any %(label)s corresponding to the following " + "information extracted from the business document:\n" + "Name: %(name)s \n" + "VAT number: %(vat)s \n" + "Reference: %(ref)s \n" + "E-mail: %(email)s \n" + "Website: %(website)s \n" + "State code: %(state)s \n" + "Country code: %(country)s \n", + label=partner_type_label, + name=partner_dict.get("name") or "", + vat=partner_dict.get("vat") or "", + ref=partner_dict.get("ref") or "", + email=partner_dict.get("email") or "", + website=partner_dict.get("website") or "", + state=partner_dict.get("state_code") or "", + country=partner_dict.get("country_code") or "", + ), + ) + + @api.model + def _hook_match_partner(self, partner_dict, chatter_msg, domain, order): + return False + + @api.model + def _match_shipping_partner( + self, partner_dict, partner, chatter_msg, domain=None, raise_exception=True + ): + """Example: + shipping_dict = { + 'email': 'contact@akretion.com', + 'name': 'Akretion France', + 'street': 'Long Avenue', + 'street2': 'Building 2A', + 'city': 'Paris', + 'zip': '69100', + 'country_code': 'FR', + } + The shipping partner can be any partner, not especially related to the + customer/supplier (partner argument) + """ + domain = domain or [] + if partner_dict.get("street"): + if partner_dict.get("street_number"): + domain = expression.AND( + [ + domain, + [ + ( + "street", + "in", + [ + "{} {}".format( + partner_dict.get("street"), + partner_dict.get("street_number"), + ), + "{} {}".format( + partner_dict.get("street_number"), + partner_dict.get("street"), + ), + "{}, {}".format( + partner_dict.get("street"), + partner_dict.get("street_number"), + ), + "{}, {}".format( + partner_dict.get("street_number"), + partner_dict.get("street"), + ), + ], + ) + ], + ] + ) + else: + domain = expression.AND( + [ + domain, + [ + ("street", "=", partner_dict.get("street")), + ], + ] + ) + + if partner_dict.get("street2"): + domain = expression.AND( + [ + domain, + [ + ("street2", "=", partner_dict.get("street2")), + ], + ] + ) + if partner_dict.get("city"): + domain = expression.AND( + [ + domain, + [ + ("city", "=", partner_dict.get("city")), + ], + ] + ) + if partner_dict.get("zip"): + domain = expression.AND( + [ + domain, + [ + ("zip", "=", partner_dict.get("zip")), + ], + ] + ) + + domain_delivery = expression.AND([domain, [("type", "=", "delivery")]]) + partner = self._match_partner( + partner_dict, + chatter_msg, + partner_type=False, + domain=domain_delivery, + raise_exception=False, + ) + if partner: + return partner + if not partner_dict.get("vat") and not partner_dict.get("email"): + partner = self.env["res.partner"].search(domain_delivery, limit=1) + if partner: + return partner + partner = self._match_partner( + partner_dict, + chatter_msg, + partner_type=False, + domain=domain, + raise_exception=False, + ) + if partner: + return partner + if not partner_dict.get("vat"): + partner = self.env["res.partner"].search(domain, limit=1) + if partner: + return partner + + if not raise_exception: + return + raise self.user_error_wrap( + "_match_shipping_partner", + partner_dict, + _( + "Odoo couldn't find any shipping partner corresponding to the " + "following information extracted from the business document:\n" + "Name: %(name)s\n" + "VAT number: %(vat)s\n" + "Reference: %(ref)s\n" + "E-mail: %(email)s\n" + "Website: %(website)s\n" + "Street: %(street)s\n" + "Street2: %(street2)s\n" + "City: %(city)s\n" + "ZIP: %(zip)s\n" + "State code: %(state)s\n" + "Country code: %(country)s\n", + name=partner_dict.get("name") or "", + vat=partner_dict.get("vat") or "", + ref=partner_dict.get("ref") or "", + email=partner_dict.get("email") or "", + website=partner_dict.get("website") or "", + street=partner_dict.get("street") or "", + street2=partner_dict.get("street2") or "", + city=partner_dict.get("city") or "", + zip=partner_dict.get("zip") or "", + state=partner_dict.get("state_code") or "", + country=partner_dict.get("country_code") or "", + ), + ) + + @api.model + def _match_partner_bank( + self, partner, iban, bic, chatter_msg, create_if_not_found=False + ): + assert iban, "iban is a required arg" + assert partner, "partner is a required arg" + partner = partner.commercial_partner_id + iban = iban.replace(" ", "").upper() + rpbo = self.env["res.partner.bank"] + rbo = self.env["res.bank"] + try: + validate_iban(iban) + except Exception: + chatter_msg.append( + _("IBAN %s is not valid, so it has been ignored.") % iban + ) + return False + company_id = self._context.get("force_company") or self.env.company.id + bankaccount = rpbo.search( + [ + "|", + ("company_id", "=", False), + ("company_id", "=", company_id), + ("sanitized_acc_number", "=", iban), + ("partner_id", "=", partner.id), + ], + limit=1, + ) + if bankaccount: + return bankaccount + elif create_if_not_found: + bank_id = False + if bic: + bic = bic.replace(" ", "").upper() + bank = rbo.search([("bic", "=", bic)], limit=1) + if bank: + bank_id = bank.id + else: + bank = rbo.create( + {"bic": bic, "name": bic} # TODO: see if we could do better + ) + bank_id = bank.id + partner_bank = rpbo.create( + {"partner_id": partner.id, "acc_number": iban, "bank_id": bank_id} + ) + chatter_msg.append( + _( + "The bank account IBAN %(iban)s has been automatically " + "added on the supplier " + "%(partner)s", + iban=iban, + partner_id=partner.id, + partner=partner.display_name, + ) + ) + return partner_bank + else: + chatter_msg.append( + _( + "The analysis of the business document returned " + "IBAN %(iban)s as bank account, but there is no such " + "bank account in Odoo linked to partner " + "%(partner)s and " + "the option to automatically create bank " + "accounts upon import is disabled.", + iban=iban, + partner_id=partner.id, + partner=partner.display_name, + ) + ) + + @api.model + def _match_product(self, product_dict, chatter_msg, seller=False): + """Retrieve product. + + Matching sequence: + + 1. ID + 2. barcode + 3. packaging barcode + 4. default_code + 5. seller code + + :param product_dict: dictionary w/ product info. + + Example: {'barcode': '5449000054227', 'code': 'COCA1L'} + + :param chatter_msg: list of msgs to append to chatter (if any) + :param seller: optional product.supplierinfo record + """ + ppo = self.env["product.product"] + self._strip_cleanup_dict(product_dict) + product = self._direct_match(product_dict, ppo) + if product: + return product + product = self._match_product_search(product_dict) + if product: + return product + elif seller: + # WARNING: Won't work for multi-variant products + # because product.supplierinfo is attached to product template + sinfo = self.env["product.supplierinfo"].search( + self._match_company_domain() + + [ + ("partner_id", "=", seller.id), + ("product_code", "=", product_dict["code"]), + ], + limit=1, + ) + if ( + sinfo + and sinfo.product_tmpl_id.product_variant_ids + and len(sinfo.product_tmpl_id.product_variant_ids) == 1 + ): + return sinfo.product_tmpl_id.product_variant_ids[0] + raise self.user_error_wrap( + "_match_product", + product_dict, + _( + "Odoo couldn't find any product corresponding to the " + "following information extracted from the business document:\n" + "Barcode: %(barcode)s\n" + "Product code: %(product_code)s\n" + "Supplier: %(supplier)s\n", + barcode=product_dict.get("barcode") or "", + product_code=product_dict.get("code") or "", + supplier=seller and seller.name or "", + ), + ) + + @api.model + def _match_product_search(self, product_dict): + product = self.env["product.product"].browse() + cdomain = self._match_company_domain() + if product_dict.get("barcode"): + domain = expression.AND( + [ + cdomain, + [ + "|", + ("barcode", "=", product_dict["barcode"]), + ("packaging_ids.barcode", "=", product_dict["barcode"]), + ], + ] + ) + product = product.search(domain, limit=1) + if not product and product_dict.get("code"): + # TODO: this domain could be probably included in the former one + domain = expression.AND( + [ + cdomain, + [ + "|", + ("barcode", "=", product_dict["code"]), + ("default_code", "=", product_dict["code"]), + ], + ] + ) + product = product.search(domain, limit=1) + return product + + @api.model + def _match_company_domain(self): + company_id = self._context.get("force_company") or self.env.user.company_id.id + return ["|", ("company_id", "=", False), ("company_id", "=", company_id)] + + @api.model + def _match_currency(self, currency_dict, chatter_msg): + """Example: + currency_dict = { + 'iso': 'USD', # If we have ISO, no need to have more keys + 'symbol': '$', + 'country_code': 'US', + 'iso_or_symbol': '$', + } + """ + if not currency_dict: + currency_dict = {} + rco = self.env["res.currency"] + self._strip_cleanup_dict(currency_dict) + currency = self._direct_match(currency_dict, rco) + if currency: + return currency + if currency_dict.get("iso"): + currency_iso = currency_dict["iso"].upper() + currency = rco.search([("name", "=", currency_iso)], limit=1) + if currency: + return currency + else: + raise self.user_error_wrap( + "_match_currency", + currency_dict, + _( + "The analysis of the business document returned '%s' as " + "the currency ISO code. But there are no currency " + "with that code in Odoo." + ) + % currency_iso, + ) + if currency_dict.get("symbol"): + currencies = rco.search([("symbol", "=", currency_dict["symbol"])]) + if len(currencies) == 1: + return currencies + else: + chatter_msg.append( + _( + "The analysis of the business document returned '%s' as " + "the currency symbol. But there are none or several " + "currencies with that symbol in Odoo." + ) + % currency_dict["symbol"] + ) + if currency_dict.get("iso_or_symbol"): + currencies = rco.search( + [ + "|", + ("name", "=", currency_dict["iso_or_symbol"].upper()), + ("symbol", "=", currency_dict["iso_or_symbol"]), + ] + ) + if len(currencies) == 1: + return currencies[0] + else: + raise self.user_error_wrap( + "_match_currency", + currency_dict, + _( + "The analysis of the business document returned '%(code)s' as " + "the currency symbol or ISO code. But there are none or " + "several currencies with the symbol/ISO code in Odoo.", + code=currency_dict["iso_or_symbol"], + ), + ) + if currency_dict.get("country_code"): + country_code = currency_dict["country_code"] + country = self.env["res.country"].search( + [("code", "=", country_code)], limit=1 + ) + if country: + if country.currency_id: + return country.currency_id + else: + raise self.user_error_wrap( + "_match_currency", + currency_dict, + _( + "The analysis of the business document returned '%(code)s' " + "as the country code to find the related currency. " + "But the country '%(name)s' doesn't have any related " + "currency configured in Odoo.", + code=country_code, + name=country.name, + ), + ) + else: + raise self.user_error_wrap( + "_match_currency", + currency_dict, + _( + "The analysis of the business document returned '%s' " + "as the country code to find the related currency. " + "But there is no country with that code in Odoo." + ) + % country_code, + ) + if self._context.get("force_company"): + company = self.env["res.company"].browse(self._context["force_company"]) + else: + company = self.env.company + company_cur = company.currency_id + chatter_msg.append( + _("No currency specified, so Odoo used the company currency (%s)") + % company_cur.name + ) + return company_cur + + @api.model + def _match_uom(self, uom_dict, chatter_msg, product=False): + """Example: + uom_dict = { + 'unece_code': 'LTR', + 'name': 'Liter', + } + """ + uuo = self.env["uom.uom"] + if not uom_dict: + uom_dict = {} + self._strip_cleanup_dict(uom_dict) + uom = self._direct_match(uom_dict, uuo) + if uom: + return uom + if uom_dict.get("unece_code"): + # Map NIU to Unit + if uom_dict["unece_code"] == "NIU": + uom_dict["unece_code"] = "C62" + uom = uuo.search([("unece_code", "=", uom_dict["unece_code"])], limit=1) + if uom: + return uom + else: + chatter_msg.append( + _( + "The analysis of the business document returned '%(code)s' " + "as the unit of measure UNECE code, but there is no " + "unit of measure with that UNECE code in Odoo. Please " + "check the configuration of the units of measures in " + "Odoo.", + code=uom_dict["unece_code"], + ) + ) + if uom_dict.get("name"): + uom = uuo.search([("name", "=ilike", uom_dict["name"] + "%")], limit=1) + if uom: + return uom + if product: + return product.uom_id + chatter_msg.append( + _( + "

    Odoo couldn't find any unit of measure corresponding to the " + "following information extracted from the business document:

    " + "
    • UNECE code: %(code)s
    • " + "
    • Name of the unit of measure: %(name)s
    " + "

    So the unit of measure 'Unit(s)' has been used. You may " + "have to change it manually.

    ", + code=uom_dict.get("unece_code"), + name=uom_dict.get("name"), + ) + ) + return self.env.ref("uom.product_uom_unit") + + @api.model + def _match_taxes( + self, taxes_list, chatter_msg, type_tax_use="purchase", price_include=False + ): + """taxes_list must be a list of tax_dict""" + taxes_recordset = self.env["account.tax"].browse(False) + for tax_dict in taxes_list: + taxes_recordset += self._match_tax( + tax_dict, + chatter_msg, + type_tax_use=type_tax_use, + price_include=price_include, + ) + return taxes_recordset + + @api.model + def _prepare_match_tax_domain( + self, tax_dict, type_tax_use="purchase", price_include=False + ): + ato = self.env["account.tax"] + company_id = self._context.get("force_company") or self.env.company.id + domain = [("company_id", "=", company_id)] + if type_tax_use == "purchase": + domain.append(("type_tax_use", "=", "purchase")) + elif type_tax_use == "sale": + domain.append(("type_tax_use", "=", "sale")) + if price_include is False: + domain.append(("price_include", "=", False)) + elif price_include is True: + domain.append(("price_include", "=", True)) + # with the code above, if you set price_include=None, it will + # won't depend on the value of the price_include parameter + assert tax_dict.get("amount_type") in [ + "fixed", + "percent", + ], "bad tax type, has to be fixed or percent" + assert "amount" in tax_dict, "Missing amount key in tax_dict" + domain.append(("amount_type", "=", tax_dict["amount_type"])) + if tax_dict.get("unece_type_code"): + domain.append(("unece_type_code", "=", tax_dict["unece_type_code"])) + if tax_dict.get("unece_categ_code"): + domain.append(("unece_categ_code", "=", tax_dict["unece_categ_code"])) + if tax_dict.get("unece_due_date_code"): + tax_exigibility = ato._get_tax_exigibility_from_unece_code( + tax_dict["unece_due_date_code"] + ) + if tax_exigibility: + domain = expression.AND( + [domain, [("tax_exigibility", "=", tax_exigibility)]] + ) + return domain + + @api.model + def _match_tax( + self, + tax_dict, + chatter_msg, + type_tax_use="purchase", + price_include=False, + ): + """Example: + tax_dict = { + 'amount_type': 'percent', # required param, 'fixed' or 'percent' + 'amount': 20.0, # required + 'unece_type_code': 'VAT', + 'unece_categ_code': 'S', + 'unece_due_date_code': '72', + } + """ + ato = self.env["account.tax"] + self._strip_cleanup_dict(tax_dict) + tax = self._direct_match(tax_dict, ato) + if tax: + return tax + domain = self._prepare_match_tax_domain( + tax_dict, type_tax_use=type_tax_use, price_include=price_include + ) + taxes = ato.search(domain) + for tax in taxes: + tax_amount = tax.amount # 'amount' field : digits=(16, 4) + if not float_compare(tax_dict["amount"], tax_amount, precision_digits=4): + return tax + raise self.user_error_wrap( + "_match_tax", + tax_dict, + _( + "Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' " + "and 'Tax Included in Price' = '%(price)s' which correspond to the " + "following information extracted from the business document:\n" + "UNECE Tax Type code: %(tax_type)s\n" + "UNECE Tax Category code: %(tax_cat)s\n" + "UNECE Due Date code: %(tax_due_date)s\n" + "Tax amount: %(amount)s %(amount_type)s", + tax=type_tax_use, + price=price_include, + tax_type=tax_dict.get("unece_type_code") or "", + tax_cat=tax_dict.get("unece_categ_code") or "", + tax_due_date=tax_dict.get("unece_due_date_code") or "", + amount=tax_dict["amount"], + amount_type=tax_dict["amount_type"] == "percent" + and "%" + or _("(fixed)"), + ), + ) + + def compare_lines( + self, + existing_lines, + import_lines, + chatter_msg, + qty_precision=None, + price_precision=None, + seller=False, + ): + """Example: + existing_lines = [{ + 'product': odoo_recordset, + 'name': 'USB Adapter', + 'qty': 1.5, + 'price_unit': 23.43, # without taxes + 'uom': uom, + 'line': recordset, + # Add taxes + }] + import_lines = [{ + 'product': { + 'barcode': '2100002000003', + 'code': 'EAZY1', + }, + 'quantity': 2, + 'price_unit': 12.42, # without taxes + 'uom': {'unece_code': 'C62'}, + }] + + Result of the method: + { + 'to_remove': line_multirecordset, + 'to_add': [ + { + 'product': recordset1, + 'uom', recordset, + 'import_line': {import dict}, + # We provide product and uom as recordset to avoid the + # need to compute a second match + ] + 'to_update': { + 'line1_recordset': {'qty': [1, 2], 'price_unit': [4.5, 4.6]}, + # qty must be updated from 1 to 2 + # price must be updated from 4.5 to 4.6 + 'line2_recordset': {'qty': [12, 13]}, + # only qty must be updated + } + } + + The check existing_currency == import_currency must be done before + the call to compare_lines() + """ + dpo = self.env["decimal.precision"] + if qty_precision is None: + qty_precision = dpo.precision_get("Product Unit of Measure") + if price_precision is None: + price_precision = dpo.precision_get("Product Price") + existing_lines_dict = {} + for eline in existing_lines: + if not eline.get("product"): + chatter_msg.append( + _( + "The existing line '%s' doesn't have any product, " + "so the lines haven't been updated." + ) + % eline.get("name") + ) + return False + if eline["product"] in existing_lines_dict: + chatter_msg.append( + _( + "The product '%s' is used on several existing " + "lines, so the lines haven't been updated." + ) + % eline["product"].display_name + ) + return False + existing_lines_dict[eline["product"]] = eline + unique_import_products = [] + res = { + "to_remove": False, + "to_add": [], + "to_update": {}, + } + for iline in import_lines: + if not iline.get("product"): + chatter_msg.append( + _( + "One of the imported lines doesn't have any product, " + "so the lines haven't been updated." + ) + ) + return False + product = self._match_product(iline["product"], chatter_msg, seller=seller) + uom = self._match_uom(iline.get("uom"), chatter_msg, product) + if product in unique_import_products: + chatter_msg.append( + _( + "The product '%s' is used on several imported lines, " + "so the lines haven't been updated." + ) + % product.display_name + ) + return False + unique_import_products.append(product) + if product in existing_lines_dict: + if uom != existing_lines_dict[product]["uom"]: + chatter_msg.append( + _( + "For product '%(product)s', the unit of measure is " + "%(uom_product)s on the existing line, but it is " + "%(uom_imported)s on the imported line." + "We don't support this scenario for the moment, so " + "the lines haven't been updated.", + product=product.display_name, + uom_product=existing_lines_dict[product]["uom"].name, + uom_imported=uom.name, + ) + ) + return False + # used for to_remove + existing_lines_dict[product]["import"] = True + oline = existing_lines_dict[product]["line"] + res["to_update"][oline] = self._prepare_order_line_update_values( + existing_lines_dict[product], iline, qty_precision, price_precision + ) + else: + res["to_add"].append( + {"product": product, "uom": uom, "import_line": iline} + ) + for exiting_dict in existing_lines_dict.values(): + if not exiting_dict.get("import"): + if res["to_remove"]: + res["to_remove"] += exiting_dict["line"] + else: + res["to_remove"] = exiting_dict["line"] + return res + + def _prepare_order_line_update_values( + self, existing_line, iline, qty_precision, price_precision + ): + values = {} + if float_compare( + iline["qty"], + existing_line["qty"], + precision_digits=qty_precision, + ): + values["qty"] = [existing_line["qty"], iline["qty"]] + if "price_unit" in iline and float_compare( + iline["price_unit"], + existing_line["price_unit"], + precision_digits=price_precision, + ): + values["price_unit"] = [ + existing_line["price_unit"], + iline["price_unit"], + ] + return values + + def _prepare_account_speed_dict(self): + company_id = self._context.get("force_company") or self.env.company.id + res = self.env["account.account"].search_read( + [("company_id", "=", company_id), ("deprecated", "=", False)], ["code"] + ) + speed_dict = {} + for line in res: + speed_dict[line["code"].upper()] = line["id"] + return speed_dict + + @api.model + def _match_account(self, account_dict, chatter_msg, speed_dict=None): + """Example: + account_dict = { + 'code': '411100', + } + speed_dict is usefull to gain performance when you have a lot of + accounts to match + """ + if not account_dict: + account_dict = {} + aao = self.env["account.account"] + if speed_dict is None: + speed_dict = self._prepare_account_speed_dict() + self._strip_cleanup_dict(account_dict) + account = self._direct_match(account_dict, aao) + if account: + return account + if account_dict.get("code"): + acc_code = account_dict["code"].upper() + if acc_code in speed_dict: + return aao.browse(speed_dict[acc_code]) + # Match when account_dict['code'] is longer than Odoo's account + # codes because of trailing '0' + # I don't think we need a warning for this kind of match + acc_code_tmp = acc_code + while acc_code_tmp and acc_code_tmp[-1] == "0": + acc_code_tmp = acc_code_tmp[:-1] + if acc_code_tmp and acc_code_tmp in speed_dict: + return aao.browse(speed_dict[acc_code_tmp]) + # Match when account_dict['code'] is shorter than Odoo's accounts + # -> warns the user about this + for code, account_id in speed_dict.items(): + if code.startswith(acc_code): + chatter_msg.append( + _( + "Approximate match: account %(account)s has been matched " + "with account %(matched_account)s", + account=account_dict["code"], + matched_account=code, + ) + ) + return aao.browse(account_id) + raise self.user_error_wrap( + "_match_account", + account_dict, + _( + "Odoo couldn't find any account corresponding to the " + "following information extracted from the business document:\n" + "Account code: %s" + ) + % (account_dict.get("code") or ""), + ) + + def _prepare_analytic_account_speed_dict(self): + company_id = self._context.get("force_company") or self.env.company.id + res = self.env["account.analytic.account"].search_read( + [("company_id", "=", company_id)], ["code"] + ) + speed_dict = {} + for line in res: + if line["code"]: + speed_dict[line["code"].upper()] = line["id"] + return speed_dict + + @api.model + def _match_analytic_account(self, aaccount_dict, chatter_msg, speed_dict=None): + """Example: + aaccount_dict = { + 'code': '627', + } + speed_dict is usefull to gain performance when you have a lot of + analytic accounts to match + """ + if not aaccount_dict: + aaccount_dict = {} + aaao = self.env["account.analytic.account"] + if speed_dict is None: + speed_dict = self._prepare_analytic_account_speed_dict() + self._strip_cleanup_dict(aaccount_dict) + aaccount = self._direct_match(aaccount_dict, aaao) + if aaccount: + return aaccount + if aaccount_dict.get("code"): + aacode = aaccount_dict["code"].upper() + if aacode in speed_dict: + return aaao.browse(speed_dict[aacode]) + raise self.user_error_wrap( + "_match_analytic_account", + aaccount_dict, + _( + "Odoo couldn't find any analytic account corresponding to the " + "following information extracted from the business document:\n" + "Analytic account code: %s" + ) + % (aaccount_dict.get("code") or ""), + ) + + def _prepare_journal_speed_dict(self): + company_id = self._context.get("force_company") or self.env.company.id + res = self.env["account.journal"].search_read( + [("company_id", "=", company_id)], ["code"] + ) + speed_dict = {} + for line in res: + speed_dict[line["code"].upper()] = line["id"] + return speed_dict + + @api.model + def _match_journal(self, journal_dict, chatter_msg, speed_dict=None): + """Example: + journal_dict = { + 'code': 'MISC', + } + speed_dict is usefull to gain performance when you have a lot of + journals to match + """ + if not journal_dict: + journal_dict = {} + ajo = self.env["account.journal"] + if speed_dict is None: + speed_dict = self._prepare_journal_speed_dict() + self._strip_cleanup_dict(journal_dict) + journal = self._direct_match(journal_dict, ajo) + if journal: + return journal + if journal_dict.get("code"): + jcode = journal_dict["code"].upper() + if jcode in speed_dict: + return ajo.browse(speed_dict[jcode]) + # case insensitive + raise self.user_error_wrap( + "_match_journal", + journal_dict, + _( + "Odoo couldn't find any journal corresponding to the " + "following information extracted from the business document:\n" + "Journal code: %s" + ) + % (journal_dict.get("code") or ""), + ) + + # Code moved from base_business_document_import_stock + # Now that the incoterm obj (account.incoterms) is defined in + # the 'account' module (since Odoo v12) instead of 'stock' + @api.model + def _match_incoterm(self, incoterm_dict, chatter_msg): + aio = self.env["account.incoterms"] + if not incoterm_dict: + incoterm_dict = {} + self._strip_cleanup_dict(incoterm_dict) + incoterm = self._direct_match(incoterm_dict, aio) + if incoterm: + return incoterm + if incoterm_dict.get("code"): + incoterm = aio.search( + [ + "|", + ("name", "=ilike", incoterm_dict["code"]), + ("code", "=ilike", incoterm_dict["code"]), + ], + limit=1, + ) + if incoterm: + return incoterm + else: + self.user_error_wrap( + "_match_incoterm", + incoterm_dict, + _("Could not find any Incoterm in Odoo corresponding " "to '%s'") + % incoterm_dict["code"], + ) + return False + + @api.model + def _check_company(self, company_dict, chatter_msg): + if not company_dict: + company_dict = {} + rco = self.env["res.company"] + if self._context.get("force_company"): + company = rco.browse(self._context["force_company"]) + else: + company = self.env.company + if company_dict.get("vat"): + parsed_company_vat = company_dict["vat"].replace(" ", "").upper() + if company.partner_id.vat: + if company.partner_id.vat != parsed_company_vat: + raise self.user_error_wrap( + "_check_company", + company_dict, + _( + "The VAT number of the customer written in the " + "business document (%(parsed_vat)s) doesn't match " + "the VAT number of the company '%(company)s' (%(vat)s) " + "in which you are trying to import this document.", + parsed_vat=parsed_company_vat, + company=company.display_name, + vat=company.partner_id.vat, + ), + ) + else: + chatter_msg.append( + _("Missing VAT number on company '%s'") % company.display_name + ) + + def get_xml_files_from_pdf(self, pdf_file): + """Returns a dict with key = filename, value = XML file obj""" + logger.warning( + "`get_xml_files_from_pdf` deprecated: use `pdf.helper.pdf_get_xml_files`" + ) + return self.env["pdf.helper"].pdf_get_xml_files(pdf_file) + + @api.model + def post_create_or_update(self, parsed_dict, record, doc_filename=None): + if parsed_dict.get("attachments"): + for filename, data_base64 in parsed_dict["attachments"].items(): + self.env["ir.attachment"].create( + { + "name": filename, + "res_id": record.id, + "res_model": str(record._name), + "datas": data_base64, + } + ) + for msg in parsed_dict["chatter_msg"]: + record.message_post(body=msg) + if parsed_dict.get("note"): + if doc_filename: + msg = _("Notes in file %s:") % doc_filename + else: + msg = _("Notes in imported document:") + record.message_post( # pylint: disable=translation-required + body="{} {}".format(msg, parsed_dict["note"]) + ) diff --git a/base_business_document_import/readme/CONTRIBUTORS.rst b/base_business_document_import/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..2aa685f8ae --- /dev/null +++ b/base_business_document_import/readme/CONTRIBUTORS.rst @@ -0,0 +1,5 @@ +* Alexis de Lattre +* Nicolas JEUDY +* Jacques-Etienne Baudoux +* Phuc (Tran Thanh) +* Simone Orsi diff --git a/base_business_document_import/readme/DESCRIPTION.rst b/base_business_document_import/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..a5b1f2cc73 --- /dev/null +++ b/base_business_document_import/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +This is a technical module ; it doesn't bring any useful feature by itself. This module is the base modules for 2 other modules : + +* *account_invoice_import* which imports supplier invoices as PDF or XML files (this module also requires some additional modules such as *account_invoice_import_invoice2data*, *account_invoice_import_ubl*, etc... to support specific invoice formats), + +* *sale_invoice_import* which imports sale orders as CSV, XML or PDF files (this module also requires some additional modules such as *sale_invoice_import_csv* or *sale_invoice_import_ubl* to support specific order formats) diff --git a/base_business_document_import/static/description/icon.png b/base_business_document_import/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/base_business_document_import/static/description/index.html b/base_business_document_import/static/description/index.html new file mode 100644 index 0000000000..8cf028bdc3 --- /dev/null +++ b/base_business_document_import/static/description/index.html @@ -0,0 +1,432 @@ + + + + + + +Base Business Document Import + + + +
    +

    Base Business Document Import

    + + +

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

    +

    This is a technical module ; it doesn’t bring any useful feature by itself. This module is the base modules for 2 other modules :

    +
      +
    • account_invoice_import which imports supplier invoices as PDF or XML files (this module also requires some additional modules such as account_invoice_import_invoice2data, account_invoice_import_ubl, etc… to support specific invoice formats),
    • +
    • sale_invoice_import which imports sale orders as CSV, XML or PDF files (this module also requires some additional modules such as sale_invoice_import_csv or sale_invoice_import_ubl to support specific order formats)
    • +
    +

    Table of contents

    + +
    +

    Bug Tracker

    +

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

    +

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

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • Akretion
    • +
    • Nicolas JEUDY
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    +Odoo Community Association +

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

    +

    Current maintainer:

    +

    alexis-via

    +

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

    +

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

    +
    +
    +
    + + diff --git a/base_business_document_import/tests/__init__.py b/base_business_document_import/tests/__init__.py new file mode 100644 index 0000000000..12d28211d4 --- /dev/null +++ b/base_business_document_import/tests/__init__.py @@ -0,0 +1 @@ +from . import test_business_document_import diff --git a/base_business_document_import/tests/test_business_document_import.py b/base_business_document_import/tests/test_business_document_import.py new file mode 100644 index 0000000000..90ddbedcf6 --- /dev/null +++ b/base_business_document_import/tests/test_business_document_import.py @@ -0,0 +1,482 @@ +# Copyright 2016-2021 Akretion France (http://www.akretion.com/) +# Copyright 2020-2021 Jacques-Etienne Baudoux (BCIM) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo.exceptions import UserError +from odoo.tests import tagged +from odoo.tests.common import TransactionCase + +logger = logging.getLogger(__name__) + + +@tagged("post_install", "-at_install") +class TestBaseBusinessDocumentImport(TransactionCase): + def test_match_partner(self): + partner1 = self.env["res.partner"].create( + {"name": "COGIP", "ref": "COGIP", "website": "http://example.com/"} + ) + bdio = self.env["business.document.import"] + # match on domain extracted from email with warning + partner_dict = {"email": "alexis.delattre@example.com"} + warn = [] + res = bdio._match_partner(partner_dict, warn, partner_type=False) + self.assertEqual(res, partner1) + self.assertTrue(warn) + partner_dict = {"name": "ready mat "} + partner_ready_mat = self.env.ref("base.res_partner_4") + partner_ready_mat.supplier_rank = 1 # to be considered as a supplier + res = bdio._match_partner(partner_dict, [], partner_type="supplier") + self.assertEqual(res, partner_ready_mat) + partner_dict = {"ref": "COGIP"} + res = bdio._match_partner(partner_dict, [], partner_type=False) + self.assertEqual(res, partner1) + + def test_direct_match_recordset(self): + partner = self.env["res.partner"].create( + { + "name": "Alexis Delattre", + "email": "alexis.delattre@example.com", + "ref": "C1242", + } + ) + partner_dict = { + "recordset": partner, + } + bdio = self.env["business.document.import"] + partner_match = bdio._direct_match(partner_dict, self.env["res.partner"], True) + self.assertEqual(partner, partner_match) + + with self.assertRaises(UserError): + bdio._direct_match(partner_dict, self.env["res.partner.bank"], True) + + partner_match = bdio._direct_match( + partner_dict, self.env["res.partner.bank"], False + ) + self.assertEqual(None, partner_match) + + def test_direct_match_id(self): + partner = self.env["res.partner"].create( + { + "name": "Alexis Delattre", + "email": "alexis.delattre@example.com", + "ref": "C1242", + } + ) + partner_dict = { + "id": partner.id, + } + bdio = self.env["business.document.import"] + partner_match = bdio._direct_match(partner_dict, self.env["res.partner"], True) + self.assertEqual(partner, partner_match) + + partner_dict = { + "id": 234234234234231, + } + with self.assertRaises(UserError): + bdio._direct_match(partner_dict, self.env["res.partner"], True) + + def test_direct_match_xmlid(self): + partner_dict = { + "xmlid": "i.dont.exist.odoo", + } + bdio = self.env["business.document.import"] + with self.assertRaises(UserError): + bdio._direct_match(partner_dict, self.env["res.partner"], True) + + partner_dict = { + "xmlid": "base.fr", + } + with self.assertRaises(UserError): + bdio._direct_match(partner_dict, self.env["res.partner"], True) + + partner_dict = { + "xmlid": "base.main_partner", + } + partner = bdio._direct_match(partner_dict, self.env["res.partner"], True) + self.assertEqual(partner.name, "YourCompany") + + def test_match_partner_ref(self): + partner1 = self.env["res.partner"].create( + { + "name": "Alexis Delattre", + "email": "alexis.delattre@example.com", + "ref": "C1242", + } + ) + bdio = self.env["business.document.import"] + partner_dict = { + "name": "Alexis Delattre", + "email": "alexis.delattre@example.com", + "ref": "C1242", + } + chatter_msg = [] + domain = [] + order = "" + partner = bdio._match_partner_ref(partner_dict, chatter_msg, domain, order) + self.assertEqual(partner, partner1) + + def test_match_partner_contact(self): + partner_email = self.env["res.partner"].create( + { + "email": "alexis.email@example.com", + "name": "Alexis email", + } + ) + partner_contact = self.env["res.partner"].create( + { + "email": "alexis.name@example.com", + "name": "Alexis name", + } + ) + partner_phone = self.env["res.partner"].create( + { + "email": "alexis.phone@example.com", + "phone": "01.41.98.12.42", + "name": "Alexis phone", + } + ) + bdio = self.env["business.document.import"] + chatter_msg = [] + domain = [] + order = "" + + partner_dict = { + "name": "Alexis email", + "email": "alexis.email@example.com", + } + partner = bdio._match_partner_contact(partner_dict, chatter_msg, domain, order) + self.assertEqual(partner, partner_email) + + partner_dict = { + "contact": "Alexis name", + "email": "alexis.name@example.com", + } + partner = bdio._match_partner_contact(partner_dict, chatter_msg, domain, order) + self.assertEqual(partner, partner_contact) + + partner_dict = { + "name": "Alexis phone", + "email": "alexis.phone@example.com", + "phone": "01.41.98.12.42", + } + partner = bdio._match_partner_contact(partner_dict, chatter_msg, domain, order) + self.assertEqual(partner, partner_phone) + + def test_match_partner_name(self): + partner_name = self.env["res.partner"].create( + { + "email": "alexis.name@example.com", + "name": "Alexis name", + } + ) + bdio = self.env["business.document.import"] + chatter_msg = [] + domain = [] + order = "" + + partner_dict = { + "name": "Alexis name", + "email": "alexis.name@example.com", + } + partner = bdio._match_partner_name(partner_dict, chatter_msg, domain, order) + self.assertEqual(partner, partner_name) + + def test_get_partner_website_domain(self): + bdio = self.env["business.document.import"] + + www_website = {"website": "www.example.com"} + website_domain = bdio._get_partner_website_domain(www_website) + self.assertEqual(website_domain, "example.com") + + no_website = bdio._get_partner_website_domain({}) + self.assertEqual(False, no_website) + + https_www_website = {"website": "https://www.example.com"} + website_domain = bdio._get_partner_website_domain(https_www_website) + self.assertEqual(website_domain, "example.com") + + https_website = {"website": "https://example.com"} + website_domain = bdio._get_partner_website_domain(https_website) + self.assertEqual(website_domain, "example.com") + + https_path_website = {"website": "https://subdomain.example.com/bla/bla"} + website_domain = bdio._get_partner_website_domain(https_path_website) + self.assertEqual(website_domain, "example.com") + + https_big_subdomain_website = { + "website": "https://just.a.big.subdomain.example.com" + } + website_domain = bdio._get_partner_website_domain(https_big_subdomain_website) + self.assertEqual(website_domain, "example.com") + + def test_match_shipping_partner(self): + rpo = self.env["res.partner"] + bdio = self.env["business.document.import"] + partner1 = rpo.create( + { + "name": "Akretion France", + "street": "27 rue Henri Rolland", + "zip": "69100", + "country_id": self.env.ref("base.fr").id, + "email": "contact@akretion.com", + } + ) + rpo.create( + { + "parent_id": partner1.id, + "name": "Sébastien BEAU", + "email": "sebastien.beau@akretion.com", + "type": "contact", + } + ) + cpartner3 = rpo.create( + { + "parent_id": partner1.id, + "name": "Flo", + "email": "flo@akretion.com", + "street": "42 rue des lilas d'Espagne", + "zip": "92400", + "city": "Courbevoie", + "country_id": self.env.ref("base.fr").id, + "type": "invoice", + } + ) + shipping_dict = { + "email": "contact@akretion.com", + } + res = bdio._match_shipping_partner(shipping_dict, None, []) + self.assertEqual(res, partner1) + shipping_dict = { + "street": "42 rue des lilas d'Espagne", + "zip": "92400", + "country_code": "fr", + } + res = bdio._match_shipping_partner(shipping_dict, None, []) + self.assertEqual(res, cpartner3) + shipping_dict["zip"] = "92500" + with self.assertRaises(UserError): + bdio._match_shipping_partner(shipping_dict, None, []) + + no_error = bdio._match_shipping_partner( + shipping_dict, None, [], raise_exception=False + ) + self.assertEqual(no_error, None) + + partner2 = rpo.create( + { + "name": "Alex Corp", + "zip": "69009", + "country_id": self.env.ref("base.fr").id, + "email": "contact@alex.com", + } + ) + shipping_dict = { + "email": "contact@alex.com", + "zip": "69009", + "country_code": "FR", + } + res = bdio._match_shipping_partner(shipping_dict, None, []) + self.assertEqual(res, partner2) + + def test_match_currency(self): + bdio = self.env["business.document.import"] + currency_dict = {"xmlid": "base.USD"} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, self.env.ref("base.USD")) + first_cur = self.env["res.currency"].search([], limit=1) + currency_dict = {"id": first_cur.id} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, first_cur) + currency_dict = {"recordset": first_cur} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, first_cur) + currency_dict = {"iso": "EUR"} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, self.env.ref("base.EUR")) + currency_dict = {"symbol": "€"} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, self.env.ref("base.EUR")) + currency_dict = {"country_code": "fr "} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, self.env.ref("base.EUR")) + currency_dict = {"iso_or_symbol": "€"} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, self.env.ref("base.EUR")) + currency_id = self.env.ref("base.KRW").id + self.cr.execute( + "UPDATE res_company SET currency_id = %s WHERE id = 1", (currency_id,) + ) + currency_dict = {} + res = bdio._match_currency(currency_dict, []) + self.assertEqual(res, self.env.ref("base.KRW")) + + def test_match_product(self): + bdio = self.env["business.document.import"] + ppo = self.env["product.product"] + product1 = ppo.create( + { + "name": "Test Product", + "barcode": "9782203121102", + "seller_ids": [ + ( + 0, + 0, + { + "partner_id": self.env.ref("base.res_partner_2").id, + "product_code": "TEST1242", + }, + ), + ], + "packaging_ids": [(0, 0, {"name": "Big Pack", "barcode": "BIG-PACK"})], + } + ) + # Match by code + product_dict = {"code": "FURN_7777 "} + res = bdio._match_product(product_dict, []) + self.assertEqual(res, self.env.ref("product.product_delivery_01")) + # Match by barcode + product_dict = {"barcode": "9782203121102"} + res = bdio._match_product(product_dict, []) + self.assertEqual(res, product1) + # Match by packaging barcode + product_dict = {"barcode": "BIG-PACK"} + res = bdio._match_product(product_dict, []) + self.assertEqual(res, product1) + # Match by seller + product_dict = {"code": "TEST1242"} + res = bdio._match_product( + product_dict, [], seller=self.env.ref("base.res_partner_2") + ) + self.assertEqual(res, product1) + raise_test = True + try: + bdio._match_product(product_dict, [], seller=False) + raise_test = False + except Exception: + logger.info("Exception catched.") + + self.assertTrue(raise_test) + + def test_match_uom(self): + bdio = self.env["business.document.import"] + uom_dict = {"unece_code": "KGM"} + res = bdio._match_uom(uom_dict, []) + self.assertEqual(res, self.env.ref("uom.product_uom_kgm")) + uom_dict = {"unece_code": "NIU"} + res = bdio._match_uom(uom_dict, []) + self.assertEqual(res, self.env.ref("uom.product_uom_unit")) + uom_dict = {"name": "day"} + res = bdio._match_uom(uom_dict, []) + self.assertEqual(res, self.env.ref("uom.product_uom_day")) + uom_dict = {"name": "lb"} + res = bdio._match_uom(uom_dict, []) + self.assertEqual(res, self.env.ref("uom.product_uom_lb")) + uom_dict = {} + product = self.env.ref("product.product_product_1") + res = bdio._match_uom(uom_dict, [], product=product) + self.assertEqual(res, product.uom_id) + + def test_match_tax(self): + # on purpose, I use a rate that doesn't exist + # so that this test works even if the l10n_de is installed + de_tax_21 = self.env["account.tax"].create( + { + "name": "German VAT purchase 18.0%", + "description": "DE-VAT-buy-18.0", + "type_tax_use": "purchase", + "price_include": False, + "amount": 18, + "amount_type": "percent", + "tax_exigibility": "on_invoice", + "unece_type_id": self.env.ref("account_tax_unece.tax_type_vat").id, + "unece_categ_id": self.env.ref("account_tax_unece.tax_categ_s").id, + } + ) + de_tax_21_onpayment = self.env["account.tax"].create( + { + "name": "German VAT purchase 18.0%", + "description": "DE-VAT-buy-18.0", + "type_tax_use": "purchase", + "price_include": False, + "amount": 18, + "amount_type": "percent", + "tax_exigibility": "on_payment", + "unece_type_id": self.env.ref("account_tax_unece.tax_type_vat").id, + "unece_categ_id": self.env.ref("account_tax_unece.tax_categ_s").id, + } + ) + de_tax_21_ttc = self.env["account.tax"].create( + { + "name": "German VAT purchase 18.0% TTC", + "description": "DE-VAT-buy-18.0-TTC", + "type_tax_use": "purchase", + "price_include": True, + "amount": 18, + "amount_type": "percent", + "tax_exigibility": "on_invoice", + "unece_type_id": self.env.ref("account_tax_unece.tax_type_vat").id, + "unece_categ_id": self.env.ref("account_tax_unece.tax_categ_s").id, + } + ) + bdio = self.env["business.document.import"] + tax_dict = { + "amount_type": "percent", + "amount": 18, + "unece_type_code": "VAT", + "unece_categ_code": "S", + "unece_due_date_code": "5", + } + res = bdio._match_tax(tax_dict, [], type_tax_use="purchase") + self.assertEqual(res, de_tax_21) + tax_dict.pop("unece_categ_code") + res = bdio._match_tax(tax_dict, [], type_tax_use="purchase") + self.assertEqual(res, de_tax_21) + res = bdio._match_tax(tax_dict, [], type_tax_use="purchase", price_include=True) + self.assertEqual(res, de_tax_21_ttc) + res = bdio._match_taxes([tax_dict], [], type_tax_use="purchase") + self.assertEqual(res, de_tax_21) + res = bdio._match_taxes( + [dict(tax_dict, unece_due_date_code=72)], [], type_tax_use="purchase" + ) + self.assertEqual(res, de_tax_21_onpayment) + + def test_match_account_exact(self): + bdio = self.env["business.document.import"] + acc = self.env["account.account"].create( + { + "name": "Test 898999", + "code": "898999", + "account_type": "expense", + } + ) + res = bdio._match_account({"code": "898999"}, []) + self.assertEqual(acc, res) + + def test_match_account_bigger_in(self): + bdio = self.env["business.document.import"] + acc = self.env["account.account"].create( + { + "name": "Test 898999", + "code": "898999", + "account_type": "expense", + } + ) + res = bdio._match_account({"code": "89899900"}, []) + self.assertEqual(acc, res) + + def test_match_account_smaller_in(self): + bdio = self.env["business.document.import"] + acc = self.env["account.account"].create( + { + "name": "Test 89899910", + "code": "89899910", + "account_type": "expense", + } + ) + chatter = [] + res = bdio._match_account({"code": "898999"}, chatter) + self.assertEqual(acc, res) + self.assertEqual(len(chatter), 1) From bef47f5a0e2b84fab82c01826378b155e566bb40 Mon Sep 17 00:00:00 2001 From: pcastelovigo Date: Mon, 27 Nov 2023 11:34:24 +0100 Subject: [PATCH 5/5] fixes --- .../models/business_document_import.py | 625 ++++++++---------- 1 file changed, 266 insertions(+), 359 deletions(-) diff --git a/base_business_document_import/models/business_document_import.py b/base_business_document_import/models/business_document_import.py index 75932a0d48..af38486340 100644 --- a/base_business_document_import/models/business_document_import.py +++ b/base_business_document_import/models/business_document_import.py @@ -7,7 +7,6 @@ from odoo import _, api, models from odoo.exceptions import UserError -from odoo.osv import expression from odoo.tools import float_compare from odoo.addons.base_iban.models.res_partner_bank import validate_iban @@ -22,7 +21,7 @@ class BusinessDocumentImport(models.AbstractModel): @api.model def user_error_wrap(self, method, data_dict, error_msg): """The method and data_dict arguments are useful when you want to - inherit this method to update the error messag_match_currencye""" + inherit this method to update the error message""" assert error_msg raise UserError(error_msg) @@ -43,13 +42,19 @@ def _direct_match(self, data_dict, model, raise_exception=True): ) ) if data_dict.get("id"): - record = model.browse(data_dict["id"]).exists() - if not record and raise_exception: - raise UserError( - _("ID {id} of '{model}' doesn't exist in Odoo.").format( - id=data_dict["id"], model=model._name - ) - ) + record = False + try: + record = model.browse(data_dict["id"]) + # Browsing an unexisting ID doesn't make Odoo crash + # So I read create_date to make it crash + record.create_date # pylint: disable=pointless-statement + except Exception: + if raise_exception: + raise UserError( + _("ID {id} of '{model}' doesn't exist in Odoo.").format( + id=data_dict["id"], model=model._name + ) + ) from None if record: return record if data_dict.get("xmlid"): @@ -57,11 +62,12 @@ def _direct_match(self, data_dict, model, raise_exception=True): record = False try: record = self.env.ref(xmlid, raise_if_not_found=True) - except Exception as e: + except Exception: if raise_exception: raise UserError( - _("The XMLID '%s' doesn't exist in Odoo.") % xmlid - ) from e + _("The XMLID '%(xmlid)s' doesn't exist in Odoo.") + % {"xmlid": xmlid} + ) from None if record: if isinstance(record, type(model)): return record @@ -80,16 +86,14 @@ def _direct_match(self, data_dict, model, raise_exception=True): @api.model def _strip_cleanup_dict(self, match_dict): - if not match_dict: - return - - for key, value in match_dict.items(): - if value and isinstance(value, str): - match_dict[key] = value.strip() - if match_dict.get("country_code"): - match_dict["country_code"] = match_dict["country_code"].upper() - if match_dict.get("state_code"): - match_dict["state_code"] = match_dict["state_code"].upper() + if match_dict: + for key, value in match_dict.items(): + if value and isinstance(value, str): + match_dict[key] = value.strip() + if match_dict.get("country_code"): + match_dict["country_code"] = match_dict["country_code"].upper() + if match_dict.get("state_code"): + match_dict["state_code"] = match_dict["state_code"].upper() @api.model def _get_match_partner_order(self, partner_type): @@ -110,6 +114,7 @@ def _get_match_partner_type_label(self, partner_type): @api.model def _get_country_filter(self, partner_dict, chatter_msg): """Generate filter by country""" + country = False if partner_dict.get("country_code"): country = self.env["res.country"].search( [("code", "=", partner_dict["country_code"])], limit=1 @@ -122,11 +127,11 @@ def _get_country_filter(self, partner_dict, chatter_msg): ] chatter_msg.append( _( - "The analysis of the business document returned '%s' as " + "The analysis of the business document returned '%(cc)s' as " "country code. But there are no country with that code " "in Odoo." ) - % partner_dict["country_code"] + % {"cc": partner_dict["country_code"]} ) return False @@ -136,13 +141,14 @@ def _get_country_state_filter(self, partner_dict, chatter_msg): country = self.env["res.country"].search( [("code", "=", partner_dict["country_code"])], limit=1 ) - if state := self.env["res.country.state"].search( + state = self.env["res.country.state"].search( [ ("code", "=", partner_dict["state_code"]), ("country_id", "=", country.id), ], limit=1, - ): + ) + if state: return ["|", ("state_id", "=", False), ("state_id", "=", state.id)] return False @@ -150,98 +156,75 @@ def _get_country_state_filter(self, partner_dict, chatter_msg): def _match_partner_ref(self, partner_dict, chatter_msg, domain, order): """If a ref is explicitly given, we just want to match that partner""" if partner_dict.get("ref"): - domain = expression.AND( - [ - domain, - [("ref", "=", partner_dict["ref"])], - ] + return self.env["res.partner"].search( + domain + [("ref", "=", partner_dict["ref"])], limit=1, order=order ) - return self.env["res.partner"].search(domain, limit=1, order=order) return False @api.model def _match_partner_contact(self, partner_dict, chatter_msg, domain, order): rpo = self.env["res.partner"] if partner_dict.get("email") and "@" in partner_dict["email"]: - if partner := rpo.search( - expression.AND( - [ - domain, - [("email", "=ilike", partner_dict["email"])], - ] - ), + partner = rpo.search( + domain + [("email", "=ilike", partner_dict["email"])], limit=1, order=order, - ): + ) + if partner: return partner if partner_dict.get("contact"): - if partner := rpo.search( - expression.AND( - [ - domain, - [("name", "=ilike", partner_dict["contact"])], - ] - ), + partner = rpo.search( + domain + [("name", "=ilike", partner_dict["contact"])], limit=1, order=order, - ): + ) + if partner: return partner if partner_dict.get("phone"): - if partner := rpo.search( - expression.AND( - [ - domain, - [ - "|", - ("mobile", "=", partner_dict["phone"]), - ("phone", "=", partner_dict["phone"]), - ], - ] - ), + partner = rpo.search( + domain + + [ + "|", + ("mobile", "=", partner_dict["phone"]), + ("phone", "=", partner_dict["phone"]), + ], limit=1, order=order, - ): + ) + if partner: return partner return False @api.model def _match_partner_name(self, partner_dict, chatter_msg, domain, order): if partner_dict.get("name"): - domain = expression.AND( - [ - domain, - [ - ("name", "=ilike", partner_dict["name"]), - ], - ] + return self.env["res.partner"].search( + domain + [("name", "=ilike", partner_dict["name"])], + limit=1, + order=order, ) - return self.env["res.partner"].search(domain, limit=1, order=order) return False @api.model def _get_partner_website_domain(self, partner_dict): - if not partner_dict.get("website"): - return False - - urlp = urlparse(partner_dict["website"]) - netloc = urlp.netloc - if not urlp.scheme and not netloc: - netloc = urlp.path - if netloc and len(netloc.split(".")) >= 2: - return ".".join(netloc.split(".")[-2:]) + if partner_dict.get("website"): + urlp = urlparse(partner_dict["website"]) + netloc = urlp.netloc + if not urlp.scheme and not netloc: + netloc = urlp.path + if netloc and len(netloc.split(".")) >= 2: + return ".".join(netloc.split(".")[-2:]) + return False @api.model def _match_partner_website(self, partner_dict, chatter_msg, domain, order): - if website_domain := self._get_partner_website_domain(partner_dict): - domain = expression.AND( - [ - domain, - [ - ("website", "=ilike", "%" + website_domain + "%"), - ], - ] + website_domain = self._get_partner_website_domain(partner_dict) + if website_domain: + return self.env["res.partner"].search( + domain + [("website", "=ilike", "%" + website_domain + "%")], + limit=1, + order=order, ) - return self.env["res.partner"].search(domain, limit=1, order=order) return False @api.model @@ -260,17 +243,13 @@ def _match_partner_email(self, partner_dict, chatter_msg, domain, order): # @gmail.com, @yahoo.com that may match random partners if email_domain: partner = self.env["res.partner"].search( - expression.AND( - [domain, [("website", "=ilike", "%" + email_domain + "%")]] - ), + domain + [("website", "=ilike", "%" + email_domain + "%")], limit=1, order=order, ) if not partner: partner = self.env["res.partner"].search( - expression.AND( - [domain, [("email", "=ilike", "%@" + email_domain)]] - ), + domain + [("email", "=ilike", "%@" + email_domain)], limit=1, order=order, ) @@ -278,12 +257,11 @@ def _match_partner_email(self, partner_dict, chatter_msg, domain, order): partner_type_label = partner_dict["type_label"] chatter_msg.append( _( - "The %(label)s has been identified by the domain name " - "'%(domain)s' so please check carefully that the " - "%(label)s is correct.", - label=partner_type_label, - domain=domain, + "The %(p_type_label)s has been identified " + "by the domain name '%(domain)s' so please check carefully " + "that the %(p_type_label)s is correct." ) + % {"p_type_label": partner_type_label, "domain": domain} ) return partner @@ -314,18 +292,8 @@ def _match_partner( # noqa: C901 partner = self._direct_match(partner_dict, rpo, raise_exception=raise_exception) if partner: return partner - company_id = self._context.get("force_company") or self.env.company.id domain = domain or [] - domain = expression.AND( - [ - domain, - [ - "|", - ("company_id", "=", False), - ("company_id", "=", company_id), - ], - ] - ) + domain += self._match_company_domain() order = self._get_match_partner_order(partner_type) partner_type_label = self._get_match_partner_type_label(partner_type) partner_dict["type"] = partner_type @@ -335,22 +303,19 @@ def _match_partner( # noqa: C901 if partner: return partner - if country_domain := self._get_country_filter(partner_dict, chatter_msg): - domain = expression.AND([domain, country_domain]) + country_domain = self._get_country_filter(partner_dict, chatter_msg) - if state_domain := self._get_country_state_filter( - partner_dict, chatter_msg - ): - domain = expression.AND([domain, state_domain]) + if country_domain: + domain += country_domain + + state_domain = self._get_country_state_filter(partner_dict, chatter_msg) + if state_domain: + domain += state_domain # Search on VAT if partner_dict.get("vat"): vat = partner_dict["vat"].replace(" ", "").upper() - partner = rpo.search( - expression.AND([domain, [("vat", "=", vat)]]), - limit=1, - order=order, - ) + partner = rpo.search(domain + [("vat", "=", vat)], limit=1, order=order) if partner: return partner @@ -387,22 +352,24 @@ def _match_partner( # noqa: C901 _( "Odoo couldn't find any %(label)s corresponding to the following " "information extracted from the business document:\n" - "Name: %(name)s \n" - "VAT number: %(vat)s \n" - "Reference: %(ref)s \n" - "E-mail: %(email)s \n" - "Website: %(website)s \n" - "State code: %(state)s \n" - "Country code: %(country)s \n", - label=partner_type_label, - name=partner_dict.get("name") or "", - vat=partner_dict.get("vat") or "", - ref=partner_dict.get("ref") or "", - email=partner_dict.get("email") or "", - website=partner_dict.get("website") or "", - state=partner_dict.get("state_code") or "", - country=partner_dict.get("country_code") or "", - ), + "Name: %(name)s\n" + "VAT number: %(vat)s\n" + "Reference: %(ref)s\n" + "E-mail: %(mail)s\n" + "Website: %(web)s\n" + "State code: %(state)s\n" + "Country code: %(country)s\n" + ) + % { + "label": partner_type_label, + "name": partner_dict.get("name") or "", + "vat": partner_dict.get("vat") or "", + "ref": partner_dict.get("ref") or "", + "mail": partner_dict.get("email") or "", + "web": partner_dict.get("website") or "", + "state": partner_dict.get("state_code") or "", + "country": partner_dict.get("country_code") or "", + }, ) @api.model @@ -429,74 +396,40 @@ def _match_shipping_partner( domain = domain or [] if partner_dict.get("street"): if partner_dict.get("street_number"): - domain = expression.AND( - [ - domain, + domain += [ + ( + "street", + "in", [ - ( - "street", - "in", - [ - "{} {}".format( - partner_dict.get("street"), - partner_dict.get("street_number"), - ), - "{} {}".format( - partner_dict.get("street_number"), - partner_dict.get("street"), - ), - "{}, {}".format( - partner_dict.get("street"), - partner_dict.get("street_number"), - ), - "{}, {}".format( - partner_dict.get("street_number"), - partner_dict.get("street"), - ), - ], - ) + "{} {}".format( + partner_dict.get("street"), + partner_dict.get("street_number"), + ), + "{} {}".format( + partner_dict.get("street_number"), + partner_dict.get("street"), + ), + "{}, {}".format( + partner_dict.get("street"), + partner_dict.get("street_number"), + ), + "{}, {}".format( + partner_dict.get("street_number"), + partner_dict.get("street"), + ), ], - ] - ) + ) + ] else: - domain = expression.AND( - [ - domain, - [ - ("street", "=", partner_dict.get("street")), - ], - ] - ) - + domain += [("street", "=", partner_dict.get("street"))] if partner_dict.get("street2"): - domain = expression.AND( - [ - domain, - [ - ("street2", "=", partner_dict.get("street2")), - ], - ] - ) + domain += [("street2", "=", partner_dict.get("street2"))] if partner_dict.get("city"): - domain = expression.AND( - [ - domain, - [ - ("city", "=", partner_dict.get("city")), - ], - ] - ) + domain += [("city", "=", partner_dict.get("city"))] if partner_dict.get("zip"): - domain = expression.AND( - [ - domain, - [ - ("zip", "=", partner_dict.get("zip")), - ], - ] - ) + domain += [("zip", "=", partner_dict.get("zip"))] - domain_delivery = expression.AND([domain, [("type", "=", "delivery")]]) + domain_delivery = domain + [("type", "=", "delivery")] partner = self._match_partner( partner_dict, chatter_msg, @@ -535,26 +468,28 @@ def _match_shipping_partner( "Name: %(name)s\n" "VAT number: %(vat)s\n" "Reference: %(ref)s\n" - "E-mail: %(email)s\n" - "Website: %(website)s\n" - "Street: %(street)s\n" - "Street2: %(street2)s\n" + "E-mail: %(mail)s\n" + "Website: %(web)s\n" + "Street: %(str)s\n" + "Street2: %(str2)s\n" "City: %(city)s\n" "ZIP: %(zip)s\n" "State code: %(state)s\n" - "Country code: %(country)s\n", - name=partner_dict.get("name") or "", - vat=partner_dict.get("vat") or "", - ref=partner_dict.get("ref") or "", - email=partner_dict.get("email") or "", - website=partner_dict.get("website") or "", - street=partner_dict.get("street") or "", - street2=partner_dict.get("street2") or "", - city=partner_dict.get("city") or "", - zip=partner_dict.get("zip") or "", - state=partner_dict.get("state_code") or "", - country=partner_dict.get("country_code") or "", - ), + "Country code: %(country)s\n" + ) + % { + "name": partner_dict.get("name") or "", + "vat": partner_dict.get("vat") or "", + "ref": partner_dict.get("ref") or "", + "mail": partner_dict.get("email") or "", + "web": partner_dict.get("website") or "", + "str": partner_dict.get("street") or "", + "str2": partner_dict.get("street2") or "", + "city": partner_dict.get("city") or "", + "zip": partner_dict.get("zip") or "", + "state": partner_dict.get("state_code") or "", + "country": partner_dict.get("country_code") or "", + }, ) @api.model @@ -571,18 +506,13 @@ def _match_partner_bank( validate_iban(iban) except Exception: chatter_msg.append( - _("IBAN %s is not valid, so it has been ignored.") % iban + _("IBAN %(iban)s is not valid, so it has been ignored.") + % {"iban": iban} ) return False - company_id = self._context.get("force_company") or self.env.company.id bankaccount = rpbo.search( - [ - "|", - ("company_id", "=", False), - ("company_id", "=", company_id), - ("sanitized_acc_number", "=", iban), - ("partner_id", "=", partner.id), - ], + self._match_company_domain() + + [("sanitized_acc_number", "=", iban), ("partner_id", "=", partner.id)], limit=1, ) if bankaccount: @@ -606,12 +536,9 @@ def _match_partner_bank( _( "The bank account IBAN %(iban)s has been automatically " "added on the supplier " - "%(partner)s", - iban=iban, - partner_id=partner.id, - partner=partner.display_name, + "%(n)s" ) + % {"iban": iban, "i": partner.id, "n": partner.display_name} ) return partner_bank else: @@ -620,14 +547,11 @@ def _match_partner_bank( "The analysis of the business document returned " "IBAN %(iban)s as bank account, but there is no such " "bank account in Odoo linked to partner " - "%(partner)s and " - "the option to automatically create bank " - "accounts upon import is disabled.", - iban=iban, - partner_id=partner.id, - partner=partner.display_name, + "%(n)s " + "and the option to automatically create bank " + "accounts upon import is disabled." ) + % {"iban": iban, "p": partner.id, "n": partner.display_name} ) @api.model @@ -663,7 +587,7 @@ def _match_product(self, product_dict, chatter_msg, seller=False): sinfo = self.env["product.supplierinfo"].search( self._match_company_domain() + [ - ("partner_id", "=", seller.id), + ("name", "=", seller.id), ("product_code", "=", product_dict["code"]), ], limit=1, @@ -681,12 +605,14 @@ def _match_product(self, product_dict, chatter_msg, seller=False): "Odoo couldn't find any product corresponding to the " "following information extracted from the business document:\n" "Barcode: %(barcode)s\n" - "Product code: %(product_code)s\n" - "Supplier: %(supplier)s\n", - barcode=product_dict.get("barcode") or "", - product_code=product_dict.get("code") or "", - supplier=seller and seller.name or "", - ), + "Product code: %(product)s\n" + "Supplier: %(supplier)s\n" + ) + % { + "barcode": product_dict.get("barcode") or "", + "product": product_dict.get("code") or "", + "supplier": seller and seller.name or "", + }, ) @api.model @@ -694,35 +620,25 @@ def _match_product_search(self, product_dict): product = self.env["product.product"].browse() cdomain = self._match_company_domain() if product_dict.get("barcode"): - domain = expression.AND( - [ - cdomain, - [ - "|", - ("barcode", "=", product_dict["barcode"]), - ("packaging_ids.barcode", "=", product_dict["barcode"]), - ], - ] - ) + domain = cdomain + [ + "|", + ("barcode", "=", product_dict["barcode"]), + ("packaging_ids.barcode", "=", product_dict["barcode"]), + ] product = product.search(domain, limit=1) if not product and product_dict.get("code"): # TODO: this domain could be probably included in the former one - domain = expression.AND( - [ - cdomain, - [ - "|", - ("barcode", "=", product_dict["code"]), - ("default_code", "=", product_dict["code"]), - ], - ] - ) + domain = cdomain + [ + "|", + ("barcode", "=", product_dict["code"]), + ("default_code", "=", product_dict["code"]), + ] product = product.search(domain, limit=1) return product @api.model def _match_company_domain(self): - company_id = self._context.get("force_company") or self.env.user.company_id.id + company_id = self._context.get("force_company") or self.env.company.id return ["|", ("company_id", "=", False), ("company_id", "=", company_id)] @api.model @@ -752,24 +668,24 @@ def _match_currency(self, currency_dict, chatter_msg): "_match_currency", currency_dict, _( - "The analysis of the business document returned '%s' as " + "The analysis of the business document returned '%(currency)s' as " "the currency ISO code. But there are no currency " "with that code in Odoo." ) - % currency_iso, + % {"currency": currency_iso}, ) if currency_dict.get("symbol"): currencies = rco.search([("symbol", "=", currency_dict["symbol"])]) if len(currencies) == 1: - return currencies + return currencies[0] else: chatter_msg.append( _( - "The analysis of the business document returned '%s' as " + "The analysis of the business document returned '%(symbol)s' as " "the currency symbol. But there are none or several " "currencies with that symbol in Odoo." ) - % currency_dict["symbol"] + % {"symbol": currency_dict["symbol"]} ) if currency_dict.get("iso_or_symbol"): currencies = rco.search( @@ -786,11 +702,11 @@ def _match_currency(self, currency_dict, chatter_msg): "_match_currency", currency_dict, _( - "The analysis of the business document returned '%(code)s' as " + "The analysis of the business document returned '%(isoorsymbol)s' as " "the currency symbol or ISO code. But there are none or " - "several currencies with the symbol/ISO code in Odoo.", - code=currency_dict["iso_or_symbol"], - ), + "several currencies with the symbol/ISO code in Odoo." + ) + % {"isoorsymbol": currency_dict["iso_or_symbol"]}, ) if currency_dict.get("country_code"): country_code = currency_dict["country_code"] @@ -805,24 +721,23 @@ def _match_currency(self, currency_dict, chatter_msg): "_match_currency", currency_dict, _( - "The analysis of the business document returned '%(code)s' " + "The analysis of the business document returned '%(cc)s' " "as the country code to find the related currency. " - "But the country '%(name)s' doesn't have any related " - "currency configured in Odoo.", - code=country_code, - name=country.name, - ), + "But the country '%(cn)s' doesn't have any related " + "currency configured in Odoo." + ) + % {"cc": country_code, "cn": country.name}, ) else: raise self.user_error_wrap( "_match_currency", currency_dict, _( - "The analysis of the business document returned '%s' " + "The analysis of the business document returned '%(cc)s' " "as the country code to find the related currency. " "But there is no country with that code in Odoo." ) - % country_code, + % {"cc": country_code}, ) if self._context.get("force_company"): company = self.env["res.company"].browse(self._context["force_company"]) @@ -830,8 +745,8 @@ def _match_currency(self, currency_dict, chatter_msg): company = self.env.company company_cur = company.currency_id chatter_msg.append( - _("No currency specified, so Odoo used the company currency (%s)") - % company_cur.name + _("No currency specified, so Odoo used the company currency (%(company)s)") + % {"company": company_cur.name} ) return company_cur @@ -860,16 +775,16 @@ def _match_uom(self, uom_dict, chatter_msg, product=False): else: chatter_msg.append( _( - "The analysis of the business document returned '%(code)s' " + "The analysis of the business document returned '%(unece)s' " "as the unit of measure UNECE code, but there is no " "unit of measure with that UNECE code in Odoo. Please " "check the configuration of the units of measures in " - "Odoo.", - code=uom_dict["unece_code"], + "Odoo." ) + % {"unece": uom_dict["unece_code"]} ) if uom_dict.get("name"): - uom = uuo.search([("name", "=ilike", uom_dict["name"] + "%")], limit=1) + uom = uuo.search([("name", "=", uom_dict["name"])], limit=1) if uom: return uom if product: @@ -878,13 +793,12 @@ def _match_uom(self, uom_dict, chatter_msg, product=False): _( "

    Odoo couldn't find any unit of measure corresponding to the " "following information extracted from the business document:

    " - "
    • UNECE code: %(code)s
    • " - "
    • Name of the unit of measure: %(name)s
    " + "
    • UNECE code: %(unece)s
    • " + "
    • Name of the unit of measure: %(dict)s
    " "

    So the unit of measure 'Unit(s)' has been used. You may " - "have to change it manually.

    ", - code=uom_dict.get("unece_code"), - name=uom_dict.get("name"), + "have to change it manually.

    " ) + % {"unece": uom_dict.get("unece_code"), "dict": uom_dict.get("name")} ) return self.env.ref("uom.product_uom_unit") @@ -899,7 +813,7 @@ def _match_taxes( tax_dict, chatter_msg, type_tax_use=type_tax_use, - price_include=price_include, + price_include=tax_dict.get("price_include", price_include), ) return taxes_recordset @@ -935,18 +849,12 @@ def _prepare_match_tax_domain( tax_dict["unece_due_date_code"] ) if tax_exigibility: - domain = expression.AND( - [domain, [("tax_exigibility", "=", tax_exigibility)]] - ) + domain += [("tax_exigibility", "=", tax_exigibility)] return domain @api.model def _match_tax( - self, - tax_dict, - chatter_msg, - type_tax_use="purchase", - price_include=False, + self, tax_dict, chatter_msg, type_tax_use="purchase", price_include=False ): """Example: tax_dict = { @@ -977,20 +885,20 @@ def _match_tax( "Odoo couldn't find any tax with 'Tax Application' = '%(tax)s' " "and 'Tax Included in Price' = '%(price)s' which correspond to the " "following information extracted from the business document:\n" - "UNECE Tax Type code: %(tax_type)s\n" - "UNECE Tax Category code: %(tax_cat)s\n" - "UNECE Due Date code: %(tax_due_date)s\n" - "Tax amount: %(amount)s %(amount_type)s", - tax=type_tax_use, - price=price_include, - tax_type=tax_dict.get("unece_type_code") or "", - tax_cat=tax_dict.get("unece_categ_code") or "", - tax_due_date=tax_dict.get("unece_due_date_code") or "", - amount=tax_dict["amount"], - amount_type=tax_dict["amount_type"] == "percent" - and "%" - or _("(fixed)"), - ), + "UNECE Tax Type code: %(tc)s\n" + "UNECE Tax Category code: %(tcc)s\n" + "UNECE Due Date code: %(ddc)s\n" + "Tax amount: %(amt)s %(amtt)s" + ) + % { + "tax": type_tax_use, + "price": price_include, + "tc": tax_dict.get("unece_type_code") or "", + "tcc": tax_dict.get("unece_categ_code") or "", + "ddc": tax_dict.get("unece_due_date_code") or "", + "amt": tax_dict["amount"], + "amtt": tax_dict["amount_type"] == "percent" and "%" or _("(fixed)"), + }, ) def compare_lines( @@ -1055,28 +963,24 @@ def compare_lines( if not eline.get("product"): chatter_msg.append( _( - "The existing line '%s' doesn't have any product, " + "The existing line '%(eline)s' doesn't have any product, " "so the lines haven't been updated." ) - % eline.get("name") + % {"eline": eline.get("name")} ) return False if eline["product"] in existing_lines_dict: chatter_msg.append( _( - "The product '%s' is used on several existing " + "The product '%(eline)s' is used on several existing " "lines, so the lines haven't been updated." ) - % eline["product"].display_name + % {"eline": eline["product"].display_name} ) return False existing_lines_dict[eline["product"]] = eline unique_import_products = [] - res = { - "to_remove": False, - "to_add": [], - "to_update": {}, - } + res = {"to_remove": False, "to_add": [], "to_update": {}} for iline in import_lines: if not iline.get("product"): chatter_msg.append( @@ -1091,10 +995,10 @@ def compare_lines( if product in unique_import_products: chatter_msg.append( _( - "The product '%s' is used on several imported lines, " + "The product '%(product)s' is used on several imported lines, " "so the lines haven't been updated." ) - % product.display_name + % {"product": product.display_name} ) return False unique_import_products.append(product) @@ -1102,15 +1006,16 @@ def compare_lines( if uom != existing_lines_dict[product]["uom"]: chatter_msg.append( _( - "For product '%(product)s', the unit of measure is " - "%(uom_product)s on the existing line, but it is " - "%(uom_imported)s on the imported line." + "For product '%(p)s', the unit of measure is %(el)s on the" + " existing line, but it is %(name)s on the imported line. " "We don't support this scenario for the moment, so " - "the lines haven't been updated.", - product=product.display_name, - uom_product=existing_lines_dict[product]["uom"].name, - uom_imported=uom.name, + "the lines haven't been updated." ) + % { + "p": product.display_name, + "el": existing_lines_dict[product]["uom"].name, + "name": uom.name, + } ) return False # used for to_remove @@ -1136,9 +1041,7 @@ def _prepare_order_line_update_values( ): values = {} if float_compare( - iline["qty"], - existing_line["qty"], - precision_digits=qty_precision, + iline["qty"], existing_line["qty"], precision_digits=qty_precision ): values["qty"] = [existing_line["qty"], iline["qty"]] if "price_unit" in iline and float_compare( @@ -1146,10 +1049,7 @@ def _prepare_order_line_update_values( existing_line["price_unit"], precision_digits=price_precision, ): - values["price_unit"] = [ - existing_line["price_unit"], - iline["price_unit"], - ] + values["price_unit"] = [existing_line["price_unit"], iline["price_unit"]] return values def _prepare_account_speed_dict(self): @@ -1198,11 +1098,10 @@ def _match_account(self, account_dict, chatter_msg, speed_dict=None): if code.startswith(acc_code): chatter_msg.append( _( - "Approximate match: account %(account)s has been matched " - "with account %(matched_account)s", - account=account_dict["code"], - matched_account=code, + "Approximate match: account %(account_dict)s has been matched " + "with account %(code)s" ) + % {"account_dict": account_dict["code"], "code": code} ) return aao.browse(account_id) raise self.user_error_wrap( @@ -1211,9 +1110,9 @@ def _match_account(self, account_dict, chatter_msg, speed_dict=None): _( "Odoo couldn't find any account corresponding to the " "following information extracted from the business document:\n" - "Account code: %s" + "Account code: %(code)s" ) - % (account_dict.get("code") or ""), + % {"code": (account_dict.get("code") or "")}, ) def _prepare_analytic_account_speed_dict(self): @@ -1255,9 +1154,9 @@ def _match_analytic_account(self, aaccount_dict, chatter_msg, speed_dict=None): _( "Odoo couldn't find any analytic account corresponding to the " "following information extracted from the business document:\n" - "Analytic account code: %s" + "Analytic account code: %(aaccount)s" ) - % (aaccount_dict.get("code") or ""), + % {"aaccount": (aaccount_dict.get("code") or "")}, ) def _prepare_journal_speed_dict(self): @@ -1299,9 +1198,9 @@ def _match_journal(self, journal_dict, chatter_msg, speed_dict=None): _( "Odoo couldn't find any journal corresponding to the " "following information extracted from the business document:\n" - "Journal code: %s" + "Journal code: %(journal)s" ) - % (journal_dict.get("code") or ""), + % {"journal": (journal_dict.get("code") or "")}, ) # Code moved from base_business_document_import_stock @@ -1331,8 +1230,11 @@ def _match_incoterm(self, incoterm_dict, chatter_msg): self.user_error_wrap( "_match_incoterm", incoterm_dict, - _("Could not find any Incoterm in Odoo corresponding " "to '%s'") - % incoterm_dict["code"], + _( + "Could not find any Incoterm in Odoo corresponding " + "to '%(incoterm)s'" + ) + % {"incoterm": incoterm_dict["code"]}, ) return False @@ -1354,17 +1256,20 @@ def _check_company(self, company_dict, chatter_msg): company_dict, _( "The VAT number of the customer written in the " - "business document (%(parsed_vat)s) doesn't match " - "the VAT number of the company '%(company)s' (%(vat)s) " - "in which you are trying to import this document.", - parsed_vat=parsed_company_vat, - company=company.display_name, - vat=company.partner_id.vat, - ), + "business document (%(vat)s) doesn't match the VAT number " + "of the company '%(display_name)s' (%(partner_vat)s) in " + " which you are trying to import this document." + ) + % { + "vat": parsed_company_vat, + "display_name": company.display_name, + "partner_vat": company.partner_id.vat, + }, ) else: chatter_msg.append( - _("Missing VAT number on company '%s'") % company.display_name + _("Missing VAT number on company '%(company_name)s'") + % {"company_name": company.display_name} ) def get_xml_files_from_pdf(self, pdf_file): @@ -1390,7 +1295,9 @@ def post_create_or_update(self, parsed_dict, record, doc_filename=None): record.message_post(body=msg) if parsed_dict.get("note"): if doc_filename: - msg = _("Notes in file %s:") % doc_filename + msg = _("Notes in file %(filename)s:") % { + "filename": doc_filename + } else: msg = _("Notes in imported document:") record.message_post( # pylint: disable=translation-required