mirror of
https://github.com/bringout/oca-edi.git
synced 2026-04-20 19:52:00 +02:00
Initial commit: OCA Edi packages (42 packages)
This commit is contained in:
commit
df976c03db
2184 changed files with 571602 additions and 0 deletions
47
odoo-bringout-oca-edi-framework-sale_order_import/README.md
Normal file
47
odoo-bringout-oca-edi-framework-sale_order_import/README.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Sale Order Import
|
||||
|
||||
Odoo addon: sale_order_import
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-edi-framework-sale_order_import
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- sale_commercial_partner
|
||||
- base_business_document_import
|
||||
- onchange_helper
|
||||
- pdf_helper
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Sale Order Import
|
||||
- **Version**: 16.0.1.3.1
|
||||
- **Category**: Sales Management
|
||||
- **License**: AGPL-3
|
||||
- **Installable**: True
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/edi-framework](https://github.com/OCA/edi-framework) branch 16.0, addon `sale_order_import`.
|
||||
|
||||
## License
|
||||
|
||||
This package maintains the original AGPL-3 license from the upstream Odoo project.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Overview: doc/OVERVIEW.md
|
||||
- Architecture: doc/ARCHITECTURE.md
|
||||
- Models: doc/MODELS.md
|
||||
- Controllers: doc/CONTROLLERS.md
|
||||
- Wizards: doc/WIZARDS.md
|
||||
- Install: doc/INSTALL.md
|
||||
- Usage: doc/USAGE.md
|
||||
- Configuration: doc/CONFIGURATION.md
|
||||
- Dependencies: doc/DEPENDENCIES.md
|
||||
- Troubleshooting: doc/TROUBLESHOOTING.md
|
||||
- FAQ: doc/FAQ.md
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
U[Users] -->|HTTP| V[Views and QWeb Templates]
|
||||
V --> C[Controllers]
|
||||
V --> W[Wizards – Transient Models]
|
||||
C --> M[Models and ORM]
|
||||
W --> M
|
||||
M --> R[Reports]
|
||||
DX[Data XML] --> M
|
||||
S[Security – ACLs and Groups] -. enforces .-> M
|
||||
|
||||
subgraph Sale_order_import Module - sale_order_import
|
||||
direction LR
|
||||
M:::layer
|
||||
W:::layer
|
||||
C:::layer
|
||||
V:::layer
|
||||
R:::layer
|
||||
S:::layer
|
||||
DX:::layer
|
||||
end
|
||||
|
||||
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
|
||||
```
|
||||
|
||||
Notes
|
||||
- Views include tree/form/kanban templates and report templates.
|
||||
- Controllers provide website/portal routes when present.
|
||||
- Wizards are UI flows implemented with `models.TransientModel`.
|
||||
- Data XML loads data/demo records; Security defines groups and access.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configuration
|
||||
|
||||
Refer to Odoo settings for sale_order_import. Configure related models, access rights, and options as needed.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Controllers
|
||||
|
||||
This module does not define custom HTTP controllers.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Dependencies
|
||||
|
||||
This addon depends on:
|
||||
|
||||
- [sale_commercial_partner](../../odoo-bringout-oca-sale-workflow-sale_commercial_partner)
|
||||
- [base_business_document_import](../../odoo-bringout-oca-edi-base_business_document_import)
|
||||
- [onchange_helper](../../odoo-bringout-oca-server-tools-onchange_helper)
|
||||
- [pdf_helper](../../odoo-bringout-oca-edi-framework-pdf_helper)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# FAQ
|
||||
|
||||
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
|
||||
- Q: How to enable? A: Start server with --addon sale_order_import or install in UI.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Install
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-edi-framework-sale_order_import"
|
||||
# or
|
||||
uv pip install odoo-bringout-oca-edi-framework-sale_order_import"
|
||||
```
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Models
|
||||
|
||||
Detected core models and extensions in sale_order_import.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class sale_order
|
||||
```
|
||||
|
||||
Notes
|
||||
- Classes show model technical names; fields omitted for brevity.
|
||||
- Items listed under _inherit are extensions of existing models.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Overview
|
||||
|
||||
Packaged Odoo addon: sale_order_import. Provides features documented in upstream Odoo 16 under this addon.
|
||||
|
||||
- Source: OCA/OCB 16.0, addon sale_order_import
|
||||
- License: LGPL-3
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Reports
|
||||
|
||||
This module does not define custom reports.
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Security
|
||||
|
||||
Access control and security definitions in sale_order_import.
|
||||
|
||||
## Access Control Lists (ACLs)
|
||||
|
||||
Model access permissions defined in:
|
||||
- **[ir.model.access.csv](../sale_order_import/security/ir.model.access.csv)**
|
||||
- 1 model access rules
|
||||
|
||||
## Record Rules
|
||||
|
||||
Row-level security rules defined in:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Security Layers"
|
||||
A[Users] --> B[Groups]
|
||||
B --> C[Access Control Lists]
|
||||
C --> D[Models]
|
||||
B --> E[Record Rules]
|
||||
E --> F[Individual Records]
|
||||
end
|
||||
```
|
||||
|
||||
Security files overview:
|
||||
- **[ir.model.access.csv](../sale_order_import/security/ir.model.access.csv)**
|
||||
- Model access permissions (CRUD rights)
|
||||
|
||||
Notes
|
||||
- Access Control Lists define which groups can access which models
|
||||
- Record Rules provide row-level security (filter records by user/group)
|
||||
- Security groups organize users and define permission sets
|
||||
- All security is enforced at the ORM level by Odoo
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Troubleshooting
|
||||
|
||||
- Ensure Python and Odoo environment matches repo guidance.
|
||||
- Check database connectivity and logs if startup fails.
|
||||
- Validate that dependent addons listed in DEPENDENCIES.md are installed.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Usage
|
||||
|
||||
Start Odoo including this addon (from repo root):
|
||||
|
||||
```bash
|
||||
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon sale_order_import
|
||||
```
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Wizards
|
||||
|
||||
Transient models exposed as UI wizards in sale_order_import.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SaleOrderImport
|
||||
```
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
[project]
|
||||
name = "odoo-bringout-oca-edi-framework-sale_order_import"
|
||||
version = "16.0.0"
|
||||
description = "Sale Order Import - Import RFQ or sale orders from files"
|
||||
authors = [
|
||||
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
|
||||
]
|
||||
dependencies = [
|
||||
"odoo-bringout-oca-edi-framework-sale_commercial_partner>=16.0.0",
|
||||
"odoo-bringout-oca-edi-framework-base_business_document_import>=16.0.0",
|
||||
"odoo-bringout-oca-edi-framework-onchange_helper>=16.0.0",
|
||||
"odoo-bringout-oca-edi-framework-pdf_helper>=16.0.0",
|
||||
"requests>=2.25.1"
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">= 3.11"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Office/Business",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
homepage = "https://github.com/bringout/0"
|
||||
repository = "https://github.com/bringout/0"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.metadata]
|
||||
allow-direct-references = true
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["sale_order_import"]
|
||||
|
||||
[tool.rye]
|
||||
managed = true
|
||||
dev-dependencies = [
|
||||
"pytest>=8.4.1",
|
||||
]
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
.. image:: https://odoo-community.org/readme-banner-image
|
||||
:target: https://odoo-community.org/get-involved?utm_source=readme
|
||||
:alt: Odoo Community Association
|
||||
|
||||
=================
|
||||
Sale Order Import
|
||||
=================
|
||||
|
||||
..
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:8e01d803e464dc07c4ec36557747613a5f3db4de2c5c712b493c596addb6ce35
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Beta
|
||||
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fedi-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/edi/tree/16.0/sale_order_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-sale_order_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 module adds support for the import of electronic RFQ or orders. This module provides the base methods to import electronic orders, and you can also plug additional formats by extending the wizard. It requires additional modules to support specific order formats:
|
||||
|
||||
|
||||
* module *sale_order_import_ubl*: adds support for `Universal Business Language (UBL) <http://ubl.xml.org/>`_ RFQs and orders as:
|
||||
|
||||
- XML file,
|
||||
- PDF file with an embedded XML file.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
This module adds a wizard in the sale menu named *Import RFQ or Order*. This wizard will propose you to select the order or RFQ file. Depending on the format of the file (XML or PDF) and the type of file (RFQ or order), it may propose you additional options.
|
||||
|
||||
When you import an order, if there is a quotation in Odoo for the same customer, the wizard will propose you to either update the existing quotation or create a new order (in fact, it will create a new quotation, so that you are free to make some modifications before you click on the *Confirm Sale* button to convert the quotation to a sale order).
|
||||
|
||||
Once the RFQ/order is imported, you should read the messages in the chatter of the quotation because it may contain important information about the import.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/edi/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 <https://github.com/OCA/edi/issues/new?body=module:%20sale_order_import%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Do not contact contributors directly about support or help with technical issues.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
* Akretion
|
||||
* Camptocamp
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
* Dennis Sluijk <d.sluijk@onestein.nl>
|
||||
* Andrea Stirpe <a.stirpe@onestein.nl>
|
||||
* Simone Orsi <simone.orsi@camptocamp.com>
|
||||
* Duong (Tran Quoc) <duongtq@trobz.com>
|
||||
|
||||
Other credits
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The migration of this module from 13.0 to 16.0 was financially supported by Camptocamp
|
||||
|
||||
Maintainers
|
||||
~~~~~~~~~~~
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
This module is part of the `OCA/edi <https://github.com/OCA/edi/tree/16.0/sale_order_import>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import wizard
|
||||
from . import models
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "Sale Order Import",
|
||||
"version": "16.0.1.3.1",
|
||||
"category": "Sales Management",
|
||||
"license": "AGPL-3",
|
||||
"summary": "Import RFQ or sale orders from files",
|
||||
"author": "Akretion, Camptocamp, Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/edi",
|
||||
"depends": [
|
||||
# OCA/sale-workflow
|
||||
"sale_commercial_partner",
|
||||
# OCA/edi
|
||||
"base_business_document_import",
|
||||
# OCA/server-tools
|
||||
"onchange_helper",
|
||||
# TODO: this dependency should be removed
|
||||
# and support for PDF import should be moved to a glue module
|
||||
"pdf_helper",
|
||||
],
|
||||
"data": ["security/ir.model.access.csv", "wizard/sale_order_import_view.xml"],
|
||||
"installable": True,
|
||||
}
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_order_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: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/models/sale.py:0
|
||||
#: code:addons/sale_order_import/tests/test_sale_order.py:0
|
||||
#, python-format
|
||||
msgid " Amount w/o tax: %(amount)s %(currency)s"
|
||||
msgstr " Iznos bez poreza: %(amount)s %(currency)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s new order line(s) created: %(label)s"
|
||||
msgstr "%(orders)s nova stavka(e) naloga kreirana(e): %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s order line(s) deleted: %(label)s"
|
||||
msgstr "%(orders)s stavka(e) naloga obrisana(e): %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An order of customer '%(partner)s' with reference '%(ref)s' already exists: "
|
||||
"%(name)s (state: %(state)s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__price_source
|
||||
msgid "Apply Prices From"
|
||||
msgstr "Primijeni cijene iz"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Cancel"
|
||||
msgstr "Otkaži"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__commercial_partner_id
|
||||
msgid "Commercial Entity"
|
||||
msgstr "Komercijalni entitet"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__confirm_order
|
||||
msgid "Confirm Order"
|
||||
msgstr "Potvrdi nalog"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Create New"
|
||||
msgstr "Kreiraj novi"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Created automatically via file import (%s)."
|
||||
msgstr "Kreiran automatski putem importa datoteke (%s)."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Kreirao"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Kreirano"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_id
|
||||
msgid "Customer"
|
||||
msgstr "Kupac"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__order
|
||||
msgid "Customer Order"
|
||||
msgstr "Nalog kupca"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Prikazani naziv"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__doc_type
|
||||
msgid "Document Type"
|
||||
msgstr "Tip dokumenta"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_filename
|
||||
msgid "Filename"
|
||||
msgstr "Naziv datoteke"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is a PDF file, Odoo will try to find an XML file in the attachments of"
|
||||
" the PDF file and then use this XML file to create the quotation."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is an XML file, Odoo will parse it if the module that adds support for"
|
||||
" this XML format is installed. For the"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import"
|
||||
msgstr "Uvoz"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.actions.act_window,name:sale_order_import.sale_order_import_action
|
||||
#: model:ir.ui.menu,name:sale_order_import.sale_order_import_menu
|
||||
msgid "Import RFQ or Order"
|
||||
msgstr "Uvoz zahtjeva za ponudu ili naloga"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import Sale Orders"
|
||||
msgstr "Uvoz prodajnih naloga"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Import Type"
|
||||
msgstr "Tip uvoza"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Zadnje mijenjano"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Zadnji ažurirao"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Zadnje ažurirano"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "No data provided"
|
||||
msgstr "Nema podataka"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No price is defined in the file. Please double check file or select "
|
||||
"Pricelist as the source for prices."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__pdf
|
||||
msgid "PDF"
|
||||
msgstr "PDF"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Please select a valid import type before importing!"
|
||||
msgstr "Molimo odaberite važeći tip uvoza prije uvoza!"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__pricelist
|
||||
msgid "Pricelist"
|
||||
msgstr "Cjenik"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__sale_id
|
||||
msgid "Quotation to Update"
|
||||
msgstr "Ponuda za ažuriranje"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__rfq
|
||||
msgid "Request For Quotation"
|
||||
msgstr "Zahtjev za ponudu"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_file
|
||||
msgid "Request for Quotation or Order"
|
||||
msgstr "Zahtjev za ponudu ili nalog"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__order
|
||||
msgid "Sale Order"
|
||||
msgstr "Prodajni nalog"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order_import
|
||||
msgid "Sale Order Import from Files"
|
||||
msgstr "Uvoz prodajnog naloga iz datoteka"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr "Prodajni nalog"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Select a type which you want to import"
|
||||
msgstr "Odaberite tip koji želite uvoziti"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_shipping_id
|
||||
msgid "Shipping Address"
|
||||
msgstr "Adresa isporuke"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Some quotations have been found for this customer ; one of them may "
|
||||
"correspond to the order or RFQ that you are importing. You can either select"
|
||||
" an existing quotation to update or create a new one."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__state
|
||||
msgid "State"
|
||||
msgstr "Status"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The currency of the imported order (%(old)s) is different from the currency "
|
||||
"of the existing order (%(new)s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The customer '%(name)s' has a pricelist '%(pricelist)s' but the currency of "
|
||||
"this order is '%(currency)s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The quantity has been updated on the order line with product '%(product)s' "
|
||||
"from %(qty0)s to %(qty1)s %(uom)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The unit price has been updated on the order line with product '%(product)s'"
|
||||
" from %(old)s to %(new)s %(currency)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "There are no embedded XML file in this PDF file."
|
||||
msgstr "Nema ugrađene XML datoteke u ovoj PDF datoteci."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Import Type is not supported. Did you install the module to support "
|
||||
"this type?"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This XML file is not XML-compliant"
|
||||
msgstr "Ova XML datoteka nije XML-kompatibilna"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%(filename)s' is not recognized as a %(type)s file. Please check "
|
||||
"the file and its extension."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%s' is not recognised as a XML nor PDF file. Please check the "
|
||||
"file and it's extension."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This order doesn't have any line !"
|
||||
msgstr "Ovaj nalog nema stavki!"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This quotation has been updated automatically via the import of file %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This type of XML RFQ/order is not supported. Did you install the module to "
|
||||
"support this XML format?"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Universal Business Language"
|
||||
msgstr "Universal Business Language"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Unsupported file format"
|
||||
msgstr "Nepodržan format datoteke"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__update
|
||||
msgid "Update"
|
||||
msgstr "Ažuriraj"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Update Existing"
|
||||
msgstr "Ažuriraj postojeći"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__order_file
|
||||
msgid ""
|
||||
"Upload a Request for Quotation or an Order file. Supported formats: XML and "
|
||||
"PDF (PDF with an embeded XML file)."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Upload below the customer order or request for quotation as XML or PDF file."
|
||||
" When you click on the Import button:"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__xml
|
||||
msgid "XML"
|
||||
msgstr "XML"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "You must select a quotation to update."
|
||||
msgstr "Morate odabrati ponudu za ažuriranje."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"format (UBL), you should install the module <em>sale_order_import_ubl</em>."
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,460 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_order_import
|
||||
#
|
||||
# Translators:
|
||||
# enjolras <yo@miguelrevilla.com>, 2018
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 10.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-03-12 01:43+0000\n"
|
||||
"PO-Revision-Date: 2023-11-26 20:35+0000\n"
|
||||
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\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: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/models/sale.py:0
|
||||
#: code:addons/sale_order_import/tests/test_sale_order.py:0
|
||||
#, python-format
|
||||
msgid " Amount w/o tax: %(amount)s %(currency)s"
|
||||
msgstr " Importe sin impuestos: %(amount)s %(currency)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s new order line(s) created: %(label)s"
|
||||
msgstr "%(orders)s nueva(s) línea(s) de pedido creada(s): %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s order line(s) deleted: %(label)s"
|
||||
msgstr "%(orders)s línea(s) de pedido suprimida(s): %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An order of customer '%(partner)s' with reference '%(ref)s' already exists: "
|
||||
"%(name)s (state: %(state)s)"
|
||||
msgstr ""
|
||||
"Ya existe un pedido del cliente '%(partner)s' con referencia '%(ref)s': "
|
||||
"%(name)s (state: %(state)s)"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__price_source
|
||||
msgid "Apply Prices From"
|
||||
msgstr "Aplicar Precios Desde"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__commercial_partner_id
|
||||
msgid "Commercial Entity"
|
||||
msgstr "Entidad Comercial"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__confirm_order
|
||||
msgid "Confirm Order"
|
||||
msgstr "Confirmar Pedido"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Create New"
|
||||
msgstr "Crear nuevo"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Created automatically via file import (%s)."
|
||||
msgstr "Creado automáticamente a través de la importación de archivos (%s)."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creado el"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_id
|
||||
msgid "Customer"
|
||||
msgstr "Cliente"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__order
|
||||
msgid "Customer Order"
|
||||
msgstr "Pedido del cliente"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nombre mostrado"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__doc_type
|
||||
msgid "Document Type"
|
||||
msgstr "Tipo de documento"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_filename
|
||||
msgid "Filename"
|
||||
msgstr "Archivo"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is a PDF file, Odoo will try to find an XML file in the attachments of "
|
||||
"the PDF file and then use this XML file to create the quotation."
|
||||
msgstr ""
|
||||
"Si es un archivo PDF, Odoo tratará de encontrar un archivo XML en los "
|
||||
"adjuntos del archivo PDF y luego usará este archivo XML para crear la "
|
||||
"cotización."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is an XML file, Odoo will parse it if the module that adds support for "
|
||||
"this XML format is installed. For the"
|
||||
msgstr ""
|
||||
"Si es un archivo XML, Odoo lo analizará si el módulo que añade soporte para "
|
||||
"este formato XML está instalado. Para los archivos"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import"
|
||||
msgstr "Importar"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.actions.act_window,name:sale_order_import.sale_order_import_action
|
||||
#: model:ir.ui.menu,name:sale_order_import.sale_order_import_menu
|
||||
msgid "Import RFQ or Order"
|
||||
msgstr "Importar solicitud de presupuesto o pedido"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import Sale Orders"
|
||||
msgstr "Importar pedidos de venta"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Import Type"
|
||||
msgstr "Tipo de Importación"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificación el"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualización por"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualización el"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "No data provided"
|
||||
msgstr "No se han facilitado datos"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No price is defined in the file. Please double check file or select "
|
||||
"Pricelist as the source for prices."
|
||||
msgstr ""
|
||||
"No se ha definido ningún precio en el archivo. Compruebe el archivo o "
|
||||
"seleccione Lista de precios como fuente de precios."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__pdf
|
||||
msgid "PDF"
|
||||
msgstr "PDF"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Please select a valid import type before importing!"
|
||||
msgstr ""
|
||||
"¡Por favor, seleccione un tipo de importación válido antes de importar!"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__pricelist
|
||||
msgid "Pricelist"
|
||||
msgstr "Tarifa"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__sale_id
|
||||
msgid "Quotation to Update"
|
||||
msgstr "Presupuesto para actualizar"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__rfq
|
||||
msgid "Request For Quotation"
|
||||
msgstr "Solicitud de presupuesto"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_file
|
||||
msgid "Request for Quotation or Order"
|
||||
msgstr "Solicitud de presupuesto o pedido"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__order
|
||||
msgid "Sale Order"
|
||||
msgstr "Pedido de venta"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order_import
|
||||
msgid "Sale Order Import from Files"
|
||||
msgstr "Importación de Orden de Venta desde Ficheros"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr "Pedido de venta"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Select a type which you want to import"
|
||||
msgstr "Seleccione el tipo que desea importar"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_shipping_id
|
||||
msgid "Shipping Address"
|
||||
msgstr "Dirección de envío"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Some quotations have been found for this customer ; one of them may "
|
||||
"correspond to the order or RFQ that you are importing. You can either select "
|
||||
"an existing quotation to update or create a new one."
|
||||
msgstr ""
|
||||
"Se han encontrado algunos presupuestos para este cliente; uno de ellos puede "
|
||||
"corresponder al pedido o petición de oferta que está importando. Puede "
|
||||
"seleccionar una oferta existente para actualizarla o crear una nueva."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__state
|
||||
msgid "State"
|
||||
msgstr "Estado"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The currency of the imported order (%(old)s) is different from the currency "
|
||||
"of the existing order (%(new)s)"
|
||||
msgstr ""
|
||||
"La divisa del pedido importado ( %(old)s) es diferente de la divisa del "
|
||||
"pedido existente (%(new)s)"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The customer '%(name)s' has a pricelist '%(pricelist)s' but the currency of "
|
||||
"this order is '%(currency)s'."
|
||||
msgstr ""
|
||||
"El cliente '%(name)s' tiene una lista de precios '%(pricelist)s' pero la "
|
||||
"divisa de este pedido es '%(currency)s'."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The quantity has been updated on the order line with product '%(product)s' "
|
||||
"from %(qty0)s to %(qty1)s %(uom)s"
|
||||
msgstr ""
|
||||
"Se ha actualizado la cantidad en la línea de pedido con el producto "
|
||||
"'%(product)s' de %(qty0)s a %(qty1)s %(uom)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The unit price has been updated on the order line with product '%(product)s' "
|
||||
"from %(old)s to %(new)s %(currency)s"
|
||||
msgstr ""
|
||||
"Se ha actualizado el precio unitario en la línea de pedido con el producto "
|
||||
"'%(product)s' de %(old)s a %(new)s %(currency)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "There are no embedded XML file in this PDF file."
|
||||
msgstr "No hay ningún archivo XML incorporado en este archivo PDF."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Import Type is not supported. Did you install the module to support "
|
||||
"this type?"
|
||||
msgstr ""
|
||||
"Este Tipo de Importación no está admitido. ¿Has instalado el módulo para "
|
||||
"admitir este tipo?"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This XML file is not XML-compliant"
|
||||
msgstr "Este archivo no es compatible con el formato XML"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%(filename)s' is not recognized as a %(type)s file. Please check "
|
||||
"the file and its extension."
|
||||
msgstr ""
|
||||
"Este archivo '%(filename)s' no se reconoce como un archivo %(type)s. "
|
||||
"Compruebe el archivo y su extensión."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%s' is not recognised as a XML nor PDF file. Please check the "
|
||||
"file and it's extension."
|
||||
msgstr ""
|
||||
"Este archivo '%s' no se reconoce como archivo XML ni PDF. Compruebe el "
|
||||
"archivo y su extensión."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This order doesn't have any line !"
|
||||
msgstr "¡Este pedido no tiene ninguna línea!"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This quotation has been updated automatically via the import of file %s"
|
||||
msgstr ""
|
||||
"Este presupuesto se ha actualizado automáticamente mediante la importación "
|
||||
"del fichero %s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This type of XML RFQ/order is not supported. Did you install the module to "
|
||||
"support this XML format?"
|
||||
msgstr ""
|
||||
"Este tipo de petición de oferta/pedido XML no es compatible. ¿Ha instalado "
|
||||
"el módulo para admitir este formato XML?"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Universal Business Language"
|
||||
msgstr "Lenguaje Comercial Universal"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Unsupported file format"
|
||||
msgstr "Formato de archivo no soportado"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__update
|
||||
msgid "Update"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Update Existing"
|
||||
msgstr "Actualizar existente"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__order_file
|
||||
msgid ""
|
||||
"Upload a Request for Quotation or an Order file. Supported formats: XML and "
|
||||
"PDF (PDF with an embeded XML file)."
|
||||
msgstr ""
|
||||
"Cargue una solicitud de presupuesto o un archivo de pedido. Formatos "
|
||||
"admitidos: XML y PDF (PDF con un archivo XML incorporado)."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Upload below the customer order or request for quotation as XML or PDF file. "
|
||||
"When you click on the Import button:"
|
||||
msgstr ""
|
||||
"Cargue a continuación el pedido del cliente o la solicitud de presupuesto "
|
||||
"como archivo XML o PDF. Al hacer clic en el botón Importar:"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__xml
|
||||
msgid "XML"
|
||||
msgstr "XML"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "You must select a quotation to update."
|
||||
msgstr "Debe seleccionar un presupuesto para actualizarlo."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"format (UBL), you should install the module <em>sale_order_import_ubl</em>."
|
||||
msgstr "(UBL), debe instalar el módulo <em>sale_order_import_ubl</em>."
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Csv Import"
|
||||
#~ msgstr "Importar CSV"
|
||||
|
||||
#~ msgid "Missing customer"
|
||||
#~ msgstr "Falta cliente"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Quotation"
|
||||
#~ msgstr "Presupuesto para actualizar"
|
||||
|
|
@ -0,0 +1,426 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_order_import
|
||||
#
|
||||
# Translators:
|
||||
# OCA Transbot <transbot@odoo-community.org>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-11-12 13:36+0000\n"
|
||||
"PO-Revision-Date: 2024-11-06 16:06+0000\n"
|
||||
"Last-Translator: samibc2c <sami.bouzidi@camptocamp.com>\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 5.6.2\n"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/models/sale.py:0
|
||||
#: code:addons/sale_order_import/tests/test_sale_order.py:0
|
||||
#, python-format
|
||||
msgid " Amount w/o tax: %(amount)s %(currency)s"
|
||||
msgstr " Montant hors taxe: %(amount)s %(currency)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s new order line(s) created: %(label)s"
|
||||
msgstr "%(orders)s nouvelle(s) ligne(s) de commande créée(s): %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s order line(s) deleted: %(label)s"
|
||||
msgstr "%(orders)s ligne(s) de commande supprimée(s): %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An order of customer '%(partner)s' with reference '%(ref)s' already exists: "
|
||||
"%(name)s (state: %(state)s)"
|
||||
msgstr ""
|
||||
"Une commande avec la référence '%(ref)s' existe déjà pour le client "
|
||||
"'%(partner)s': %(name)s (état: %(state)s)"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__price_source
|
||||
msgid "Apply Prices From"
|
||||
msgstr "Appliquer les prix à partir de"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__commercial_partner_id
|
||||
msgid "Commercial Entity"
|
||||
msgstr "Entité commerciale"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__confirm_order
|
||||
msgid "Confirm Order"
|
||||
msgstr "Confirmer la commande"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Create New"
|
||||
msgstr "Créer une nouvelle"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Created automatically via file import (%s)."
|
||||
msgstr "Créé automatiquement par importation de fichier (%s)."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Créé par"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Créé le"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_id
|
||||
msgid "Customer"
|
||||
msgstr "Client"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__order
|
||||
msgid "Customer Order"
|
||||
msgstr "Commande client"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nom affiché"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__doc_type
|
||||
msgid "Document Type"
|
||||
msgstr "Type de document"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_filename
|
||||
msgid "Filename"
|
||||
msgstr "Nom du fichier"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is a PDF file, Odoo will try to find an XML file in the attachments of "
|
||||
"the PDF file and then use this XML file to create the quotation."
|
||||
msgstr ""
|
||||
"S'il s'agit d'un document PDF, Odoo tentera de trouver un fichier XML en "
|
||||
"pièce-jointe et utilisera ensuite ce document XML pour créer le devis."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is an XML file, Odoo will parse it if the module that adds support for "
|
||||
"this XML format is installed. For the"
|
||||
msgstr ""
|
||||
"S'il s'agit d'un document XML, Odoo l'analysera si le module adéquat est "
|
||||
"installé. Pour le"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import"
|
||||
msgstr "Importer"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.actions.act_window,name:sale_order_import.sale_order_import_action
|
||||
#: model:ir.ui.menu,name:sale_order_import.sale_order_import_menu
|
||||
msgid "Import RFQ or Order"
|
||||
msgstr "Importer la demande ou la commande d'achat"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import Sale Orders"
|
||||
msgstr "Importer le bon de commande"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Import Type"
|
||||
msgstr "Type d'import"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Dernière modification le"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Dernière mise-à-jour par"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Dernière mise-à-jour le"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "No data provided"
|
||||
msgstr "Aucune donnée fournie"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No price is defined in the file. Please double check file or select "
|
||||
"Pricelist as the source for prices."
|
||||
msgstr ""
|
||||
"Aucun prix définit dans le fichier. Veuillez vérifier le fichier ou "
|
||||
"sélectionner une liste de prix source."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__pdf
|
||||
msgid "PDF"
|
||||
msgstr "PDF"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Please select a valid import type before importing!"
|
||||
msgstr "Veuillez sélectionner un type d'importation valide avant d'importer !"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__pricelist
|
||||
msgid "Pricelist"
|
||||
msgstr "Liste de prix"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__sale_id
|
||||
msgid "Quotation to Update"
|
||||
msgstr "Devis à mettre à jour"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__rfq
|
||||
msgid "Request For Quotation"
|
||||
msgstr "Demande de prix"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_file
|
||||
msgid "Request for Quotation or Order"
|
||||
msgstr "Demande de prix ou Bon de conmande"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__order
|
||||
msgid "Sale Order"
|
||||
msgstr "Bon de commande"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order_import
|
||||
msgid "Sale Order Import from Files"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Select a type which you want to import"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_shipping_id
|
||||
msgid "Shipping Address"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Some quotations have been found for this customer ; one of them may "
|
||||
"correspond to the order or RFQ that you are importing. You can either select "
|
||||
"an existing quotation to update or create a new one."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__state
|
||||
msgid "State"
|
||||
msgstr "Etat"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The currency of the imported order (%(old)s) is different from the currency "
|
||||
"of the existing order (%(new)s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The customer '%(name)s' has a pricelist '%(pricelist)s' but the currency of "
|
||||
"this order is '%(currency)s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The quantity has been updated on the order line with product '%(product)s' "
|
||||
"from %(qty0)s to %(qty1)s %(uom)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The unit price has been updated on the order line with product '%(product)s' "
|
||||
"from %(old)s to %(new)s %(currency)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "There are no embedded XML file in this PDF file."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Import Type is not supported. Did you install the module to support "
|
||||
"this type?"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This XML file is not XML-compliant"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%(filename)s' is not recognized as a %(type)s file. Please check "
|
||||
"the file and its extension."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%s' is not recognised as a XML nor PDF file. Please check the "
|
||||
"file and it's extension."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This order doesn't have any line !"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This quotation has been updated automatically via the import of file %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This type of XML RFQ/order is not supported. Did you install the module to "
|
||||
"support this XML format?"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Universal Business Language"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Unsupported file format"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__update
|
||||
msgid "Update"
|
||||
msgstr "Mettre à jour"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Update Existing"
|
||||
msgstr "Mettre à jour une existante"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__order_file
|
||||
msgid ""
|
||||
"Upload a Request for Quotation or an Order file. Supported formats: XML and "
|
||||
"PDF (PDF with an embeded XML file)."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Upload below the customer order or request for quotation as XML or PDF file. "
|
||||
"When you click on the Import button:"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__xml
|
||||
msgid "XML"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "You must select a quotation to update."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"format (UBL), you should install the module <em>sale_order_import_ubl</em>."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Csv Import"
|
||||
#~ msgstr "Importer"
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_order_import
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-07-24 16:25+0000\n"
|
||||
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.10.4\n"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/models/sale.py:0
|
||||
#: code:addons/sale_order_import/tests/test_sale_order.py:0
|
||||
#, python-format
|
||||
msgid " Amount w/o tax: %(amount)s %(currency)s"
|
||||
msgstr " Valore senza imposte: %(amount)s %(currency)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s new order line(s) created: %(label)s"
|
||||
msgstr "%(orders)s nuova riga(e) ordine creata: %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s order line(s) deleted: %(label)s"
|
||||
msgstr "%(orders)s riga(e) ordine cancellata: %(label)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An order of customer '%(partner)s' with reference '%(ref)s' already exists: "
|
||||
"%(name)s (state: %(state)s)"
|
||||
msgstr ""
|
||||
"Un ordine del cliente '%(partner)s' con riferimento '%(ref)s' esiste già: "
|
||||
"%(name)s (stato: %(state)s)"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__price_source
|
||||
msgid "Apply Prices From"
|
||||
msgstr "Maschera applicazione prezzi"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Cancel"
|
||||
msgstr "Annulla"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__commercial_partner_id
|
||||
msgid "Commercial Entity"
|
||||
msgstr "Entità commerciale"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__confirm_order
|
||||
msgid "Confirm Order"
|
||||
msgstr "Conferma ordine"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Create New"
|
||||
msgstr "Crea nuovo"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Created automatically via file import (%s)."
|
||||
msgstr "Creati automaticamente con importazione file (%s)."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creato da"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creato il"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_id
|
||||
msgid "Customer"
|
||||
msgstr "Cliente"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__order
|
||||
msgid "Customer Order"
|
||||
msgstr "Ordine cliente"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nome visualizzato"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__doc_type
|
||||
msgid "Document Type"
|
||||
msgstr "Tipo documento"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_filename
|
||||
msgid "Filename"
|
||||
msgstr "Nome file"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is a PDF file, Odoo will try to find an XML file in the attachments of"
|
||||
" the PDF file and then use this XML file to create the quotation."
|
||||
msgstr ""
|
||||
"Se è un file PDF, Odoo cercherà di trovare un file XML allegato al file PDF "
|
||||
"e usarlo per creare il preventivo."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is an XML file, Odoo will parse it if the module that adds support for"
|
||||
" this XML format is installed. For the"
|
||||
msgstr ""
|
||||
"Se è un file XML, Odoo lo analizzerà se è installato il modulo che aggiunge "
|
||||
"il supporto per questo formato XML. Per il"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import"
|
||||
msgstr "Importa"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.actions.act_window,name:sale_order_import.sale_order_import_action
|
||||
#: model:ir.ui.menu,name:sale_order_import.sale_order_import_menu
|
||||
msgid "Import RFQ or Order"
|
||||
msgstr "Importa RdP o ordine"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import Sale Orders"
|
||||
msgstr "Importa gli ordini di vendita"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Import Type"
|
||||
msgstr "Tipo importazione"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Ultima modifica il"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Ultimo aggiornamento di"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Ultimo aggiornamento il"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "No data provided"
|
||||
msgstr "Nessun dato fornito"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No price is defined in the file. Please double check file or select "
|
||||
"Pricelist as the source for prices."
|
||||
msgstr ""
|
||||
"Nessun prezzo definito nel file. Ricontrollare il file o selezionare un "
|
||||
"listino per i prezzi."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__pdf
|
||||
msgid "PDF"
|
||||
msgstr "PDF"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Please select a valid import type before importing!"
|
||||
msgstr "Selezionare un tipo importazione valido prima di importare!"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__pricelist
|
||||
msgid "Pricelist"
|
||||
msgstr "Listino prezzi"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__sale_id
|
||||
msgid "Quotation to Update"
|
||||
msgstr "Preventivo da aggiornare"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__rfq
|
||||
msgid "Request For Quotation"
|
||||
msgstr "Richiesta di preventivo"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_file
|
||||
msgid "Request for Quotation or Order"
|
||||
msgstr "Richiesta di preventivo o ordine"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__order
|
||||
msgid "Sale Order"
|
||||
msgstr "Ordine di vendita"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order_import
|
||||
msgid "Sale Order Import from Files"
|
||||
msgstr "Importazione ordine di vendita da file"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr "Ordine di vendita"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Select a type which you want to import"
|
||||
msgstr "Selezionare un tipo che si vuole importare"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_shipping_id
|
||||
msgid "Shipping Address"
|
||||
msgstr "Indirizzo di spedizione"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Some quotations have been found for this customer ; one of them may "
|
||||
"correspond to the order or RFQ that you are importing. You can either select"
|
||||
" an existing quotation to update or create a new one."
|
||||
msgstr ""
|
||||
"Sono stati trovati alcuni preventivi per questo cliente; uno di essi può "
|
||||
"corrispondere all'ordine o alla RdP che si sta importando. Si può "
|
||||
"selezionare un preventivo esistente o crearne uno nuovo."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__state
|
||||
msgid "State"
|
||||
msgstr "Stato"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The currency of the imported order (%(old)s) is different from the currency "
|
||||
"of the existing order (%(new)s)"
|
||||
msgstr ""
|
||||
"La valuta dell'ordine importato (%(old)s) è diversa dalla valuta dell'ordine "
|
||||
"esistente (%(new)s)"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The customer '%(name)s' has a pricelist '%(pricelist)s' but the currency of "
|
||||
"this order is '%(currency)s'."
|
||||
msgstr ""
|
||||
"Il cliente '%(name)s' ha un listino '%(pricelist)s' ma la valuta dell'ordine "
|
||||
"è '%(currency)s'."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The quantity has been updated on the order line with product '%(product)s' "
|
||||
"from %(qty0)s to %(qty1)s %(uom)s"
|
||||
msgstr ""
|
||||
"La quantità è stata aggiornata nella riga ordine con prodotto '%(product)s' "
|
||||
"da %(qty0)s a %(qty1)s %(uom)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The unit price has been updated on the order line with product '%(product)s'"
|
||||
" from %(old)s to %(new)s %(currency)s"
|
||||
msgstr ""
|
||||
"Il prezzo unitario è stato aggiornato nella riga ordine con prodotto "
|
||||
"'%(product)s' da %(old)s a %(new)s %(currency)s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "There are no embedded XML file in this PDF file."
|
||||
msgstr "In questo PDF non c'è un file XML integrato."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Import Type is not supported. Did you install the module to support "
|
||||
"this type?"
|
||||
msgstr ""
|
||||
"Questo tipo di importazione non è supportato. Il modulo per supportarlo è "
|
||||
"stato installato?"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This XML file is not XML-compliant"
|
||||
msgstr "Il file XML non è compatibile al formato XML"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%(filename)s' is not recognized as a %(type)s file. Please check "
|
||||
"the file and its extension."
|
||||
msgstr ""
|
||||
"Questo file '%(filename)s' non è riconosciuto come file %(type)s. "
|
||||
"Controllare il file e la sua estensione."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%s' is not recognised as a XML nor PDF file. Please check the "
|
||||
"file and it's extension."
|
||||
msgstr ""
|
||||
"Il file '%s' non è riconosciuto come file XML o PDF. Controllare il file e "
|
||||
"la sua estensione."
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This order doesn't have any line !"
|
||||
msgstr "Questo ordine non ha righe!"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This quotation has been updated automatically via the import of file %s"
|
||||
msgstr ""
|
||||
"Il preventivo è stato aggiornato automaticamente con l'importazione del file "
|
||||
"%s"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This type of XML RFQ/order is not supported. Did you install the module to "
|
||||
"support this XML format?"
|
||||
msgstr ""
|
||||
"Questo tipo RdP/ordine XML non è supportato. Il modulo per supportare questo "
|
||||
"formato è stato installato?"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Universal Business Language"
|
||||
msgstr "Linguaggio commerciale universale"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Unsupported file format"
|
||||
msgstr "Formato file non supportato"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__update
|
||||
msgid "Update"
|
||||
msgstr "Aggiorna"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Update Existing"
|
||||
msgstr "Aggiorna esistente"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__order_file
|
||||
msgid ""
|
||||
"Upload a Request for Quotation or an Order file. Supported formats: XML and "
|
||||
"PDF (PDF with an embeded XML file)."
|
||||
msgstr ""
|
||||
"Caricare un file richiesta di preventivo o un ordine. Formati supportati: "
|
||||
"XML e PDF (PDF con file XML integrato)."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Upload below the customer order or request for quotation as XML or PDF file."
|
||||
" When you click on the Import button:"
|
||||
msgstr ""
|
||||
"Caricare in calce l'ordine cliente o la richiesta di preventivo come file "
|
||||
"XML o PDF. Quando si fa clic sul pulsante importazione:"
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__xml
|
||||
msgid "XML"
|
||||
msgstr "XML"
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "You must select a quotation to update."
|
||||
msgstr "Bisogna selezionare un preventivo da aggiornare."
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"format (UBL), you should install the module <em>sale_order_import_ubl</em>."
|
||||
msgstr ""
|
||||
"formato (UBL), bisogna installare il modulo <em>sale_order_import_ubl</em>."
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_order_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: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/models/sale.py:0
|
||||
#: code:addons/sale_order_import/tests/test_sale_order.py:0
|
||||
#, python-format
|
||||
msgid " Amount w/o tax: %(amount)s %(currency)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s new order line(s) created: %(label)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "%(orders)s order line(s) deleted: %(label)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"An order of customer '%(partner)s' with reference '%(ref)s' already exists: "
|
||||
"%(name)s (state: %(state)s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__price_source
|
||||
msgid "Apply Prices From"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__commercial_partner_id
|
||||
msgid "Commercial Entity"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__confirm_order
|
||||
msgid "Confirm Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Create New"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Created automatically via file import (%s)."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_id
|
||||
msgid "Customer"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__order
|
||||
msgid "Customer Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__doc_type
|
||||
msgid "Document Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_filename
|
||||
msgid "Filename"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is a PDF file, Odoo will try to find an XML file in the attachments of"
|
||||
" the PDF file and then use this XML file to create the quotation."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"If it is an XML file, Odoo will parse it if the module that adds support for"
|
||||
" this XML format is installed. For the"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.actions.act_window,name:sale_order_import.sale_order_import_action
|
||||
#: model:ir.ui.menu,name:sale_order_import.sale_order_import_menu
|
||||
msgid "Import RFQ or Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Import Sale Orders"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Import Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "No data provided"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No price is defined in the file. Please double check file or select "
|
||||
"Pricelist as the source for prices."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__pdf
|
||||
msgid "PDF"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Please select a valid import type before importing!"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__price_source__pricelist
|
||||
msgid "Pricelist"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__sale_id
|
||||
msgid "Quotation to Update"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__rfq
|
||||
msgid "Request For Quotation"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__order_file
|
||||
msgid "Request for Quotation or Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__doc_type__order
|
||||
msgid "Sale Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order_import
|
||||
msgid "Sale Order Import from Files"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model,name:sale_order_import.model_sale_order
|
||||
msgid "Sales Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__import_type
|
||||
msgid "Select a type which you want to import"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__partner_shipping_id
|
||||
msgid "Shipping Address"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Some quotations have been found for this customer ; one of them may "
|
||||
"correspond to the order or RFQ that you are importing. You can either select"
|
||||
" an existing quotation to update or create a new one."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,field_description:sale_order_import.field_sale_order_import__state
|
||||
msgid "State"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The currency of the imported order (%(old)s) is different from the currency "
|
||||
"of the existing order (%(new)s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The customer '%(name)s' has a pricelist '%(pricelist)s' but the currency of "
|
||||
"this order is '%(currency)s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The quantity has been updated on the order line with product '%(product)s' "
|
||||
"from %(qty0)s to %(qty1)s %(uom)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The unit price has been updated on the order line with product '%(product)s'"
|
||||
" from %(old)s to %(new)s %(currency)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "There are no embedded XML file in this PDF file."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Import Type is not supported. Did you install the module to support "
|
||||
"this type?"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This XML file is not XML-compliant"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%(filename)s' is not recognized as a %(type)s file. Please check "
|
||||
"the file and its extension."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This file '%s' is not recognised as a XML nor PDF file. Please check the "
|
||||
"file and it's extension."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "This order doesn't have any line !"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This quotation has been updated automatically via the import of file %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This type of XML RFQ/order is not supported. Did you install the module to "
|
||||
"support this XML format?"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Universal Business Language"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "Unsupported file format"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__state__update
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid "Update Existing"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields,help:sale_order_import.field_sale_order_import__order_file
|
||||
msgid ""
|
||||
"Upload a Request for Quotation or an Order file. Supported formats: XML and "
|
||||
"PDF (PDF with an embeded XML file)."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"Upload below the customer order or request for quotation as XML or PDF file."
|
||||
" When you click on the Import button:"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model:ir.model.fields.selection,name:sale_order_import.selection__sale_order_import__import_type__xml
|
||||
msgid "XML"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#. odoo-python
|
||||
#: code:addons/sale_order_import/wizard/sale_order_import.py:0
|
||||
#, python-format
|
||||
msgid "You must select a quotation to update."
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_order_import
|
||||
#: model_terms:ir.ui.view,arch_db:sale_order_import.sale_order_import_form
|
||||
msgid ""
|
||||
"format (UBL), you should install the module <em>sale_order_import_ubl</em>."
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import sale
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# © 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, models
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
def name_get(self):
|
||||
"""Add amount_untaxed in name_get of sale orders"""
|
||||
res = super().name_get()
|
||||
if self._context.get("sale_order_show_amount"):
|
||||
new_res = []
|
||||
for (sale_id, name) in res:
|
||||
sale = self.browse(sale_id)
|
||||
# TODO: find a python method to easily display a float + currency
|
||||
# symbol (before or after) depending on lang of context and currency
|
||||
name += _(
|
||||
" Amount w/o tax: %(amount)s %(currency)s",
|
||||
amount=sale.amount_untaxed,
|
||||
currency=sale.currency_id.name,
|
||||
)
|
||||
new_res.append((sale_id, name))
|
||||
return new_res
|
||||
else:
|
||||
return res
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
* Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
* Dennis Sluijk <d.sluijk@onestein.nl>
|
||||
* Andrea Stirpe <a.stirpe@onestein.nl>
|
||||
* Simone Orsi <simone.orsi@camptocamp.com>
|
||||
* Duong (Tran Quoc) <duongtq@trobz.com>
|
||||
|
|
@ -0,0 +1 @@
|
|||
The migration of this module from 13.0 to 16.0 was financially supported by Camptocamp
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
This module adds support for the import of electronic RFQ or orders. This module provides the base methods to import electronic orders, and you can also plug additional formats by extending the wizard. It requires additional modules to support specific order formats:
|
||||
|
||||
|
||||
* module *sale_order_import_ubl*: adds support for `Universal Business Language (UBL) <http://ubl.xml.org/>`_ RFQs and orders as:
|
||||
|
||||
- XML file,
|
||||
- PDF file with an embedded XML file.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
This module adds a wizard in the sale menu named *Import RFQ or Order*. This wizard will propose you to select the order or RFQ file. Depending on the format of the file (XML or PDF) and the type of file (RFQ or order), it may propose you additional options.
|
||||
|
||||
When you import an order, if there is a quotation in Odoo for the same customer, the wizard will propose you to either update the existing quotation or create a new order (in fact, it will create a new quotation, so that you are free to make some modifications before you click on the *Confirm Sale* button to convert the quotation to a sale order).
|
||||
|
||||
Once the RFQ/order is imported, you should read the messages in the chatter of the quotation because it may contain important information about the import.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_sale_order_import,access_sale_order_import,model_sale_order_import,sales_team.group_sale_salesman,1,1,1,1
|
||||
|
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
|
|
@ -0,0 +1,453 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||
<title>README.rst</title>
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
:Author: David Goodger (goodger@python.org)
|
||||
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
Despite the name, some widely supported CSS2 features are used.
|
||||
|
||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||
customize this style sheet.
|
||||
*/
|
||||
|
||||
/* used to remove borders from tables and images */
|
||||
.borderless, table.borderless td, table.borderless th {
|
||||
border: 0 }
|
||||
|
||||
table.borderless td, table.borderless th {
|
||||
/* Override padding for "table.docutils td" with "! important".
|
||||
The right padding separates the table cells. */
|
||||
padding: 0 0.5em 0 0 ! important }
|
||||
|
||||
.first {
|
||||
/* Override more specific margin styles with "! important". */
|
||||
margin-top: 0 ! important }
|
||||
|
||||
.last, .with-subtitle {
|
||||
margin-bottom: 0 ! important }
|
||||
|
||||
.hidden {
|
||||
display: none }
|
||||
|
||||
.subscript {
|
||||
vertical-align: sub;
|
||||
font-size: smaller }
|
||||
|
||||
.superscript {
|
||||
vertical-align: super;
|
||||
font-size: smaller }
|
||||
|
||||
a.toc-backref {
|
||||
text-decoration: none ;
|
||||
color: black }
|
||||
|
||||
blockquote.epigraph {
|
||||
margin: 2em 5em ; }
|
||||
|
||||
dl.docutils dd {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Uncomment (and remove this text!) to get bold-faced definition list terms
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
*/
|
||||
|
||||
div.abstract {
|
||||
margin: 2em 5em }
|
||||
|
||||
div.abstract p.topic-title {
|
||||
font-weight: bold ;
|
||||
text-align: center }
|
||||
|
||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
||||
div.hint, div.important, div.note, div.tip, div.warning {
|
||||
margin: 2em ;
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
||||
div.important p.admonition-title, div.note p.admonition-title,
|
||||
div.tip p.admonition-title {
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
||||
div.danger p.admonition-title, div.error p.admonition-title,
|
||||
div.warning p.admonition-title, .code .error {
|
||||
color: red ;
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
||||
compound paragraphs.
|
||||
div.compound .compound-first, div.compound .compound-middle {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.compound .compound-last, div.compound .compound-middle {
|
||||
margin-top: 0.5em }
|
||||
*/
|
||||
|
||||
div.dedication {
|
||||
margin: 2em 5em ;
|
||||
text-align: center ;
|
||||
font-style: italic }
|
||||
|
||||
div.dedication p.topic-title {
|
||||
font-weight: bold ;
|
||||
font-style: normal }
|
||||
|
||||
div.figure {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
div.footer, div.header {
|
||||
clear: both;
|
||||
font-size: smaller }
|
||||
|
||||
div.line-block {
|
||||
display: block ;
|
||||
margin-top: 1em ;
|
||||
margin-bottom: 1em }
|
||||
|
||||
div.line-block div.line-block {
|
||||
margin-top: 0 ;
|
||||
margin-bottom: 0 ;
|
||||
margin-left: 1.5em }
|
||||
|
||||
div.sidebar {
|
||||
margin: 0 0 0.5em 1em ;
|
||||
border: medium outset ;
|
||||
padding: 1em ;
|
||||
background-color: #ffffee ;
|
||||
width: 40% ;
|
||||
float: right ;
|
||||
clear: right }
|
||||
|
||||
div.sidebar p.rubric {
|
||||
font-family: sans-serif ;
|
||||
font-size: medium }
|
||||
|
||||
div.system-messages {
|
||||
margin: 5em }
|
||||
|
||||
div.system-messages h1 {
|
||||
color: red }
|
||||
|
||||
div.system-message {
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.system-message p.system-message-title {
|
||||
color: red ;
|
||||
font-weight: bold }
|
||||
|
||||
div.topic {
|
||||
margin: 2em }
|
||||
|
||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
||||
margin-top: 0.4em }
|
||||
|
||||
h1.title {
|
||||
text-align: center }
|
||||
|
||||
h2.subtitle {
|
||||
text-align: center }
|
||||
|
||||
hr.docutils {
|
||||
width: 75% }
|
||||
|
||||
img.align-left, .figure.align-left, object.align-left, table.align-left {
|
||||
clear: left ;
|
||||
float: left ;
|
||||
margin-right: 1em }
|
||||
|
||||
img.align-right, .figure.align-right, object.align-right, table.align-right {
|
||||
clear: right ;
|
||||
float: right ;
|
||||
margin-left: 1em }
|
||||
|
||||
img.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left }
|
||||
|
||||
.align-center {
|
||||
clear: both ;
|
||||
text-align: center }
|
||||
|
||||
.align-right {
|
||||
text-align: right }
|
||||
|
||||
/* reset inner alignment in figures */
|
||||
div.align-right {
|
||||
text-align: inherit }
|
||||
|
||||
/* div.align-center * { */
|
||||
/* text-align: left } */
|
||||
|
||||
.align-top {
|
||||
vertical-align: top }
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle }
|
||||
|
||||
.align-bottom {
|
||||
vertical-align: bottom }
|
||||
|
||||
ol.simple, ul.simple {
|
||||
margin-bottom: 1em }
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal }
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha }
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha }
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman }
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman }
|
||||
|
||||
p.attribution {
|
||||
text-align: right ;
|
||||
margin-left: 50% }
|
||||
|
||||
p.caption {
|
||||
font-style: italic }
|
||||
|
||||
p.credits {
|
||||
font-style: italic ;
|
||||
font-size: smaller }
|
||||
|
||||
p.label {
|
||||
white-space: nowrap }
|
||||
|
||||
p.rubric {
|
||||
font-weight: bold ;
|
||||
font-size: larger ;
|
||||
color: maroon ;
|
||||
text-align: center }
|
||||
|
||||
p.sidebar-title {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold ;
|
||||
font-size: larger }
|
||||
|
||||
p.sidebar-subtitle {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
p.topic-title {
|
||||
font-weight: bold }
|
||||
|
||||
pre.address {
|
||||
margin-bottom: 0 ;
|
||||
margin-top: 0 ;
|
||||
font: inherit }
|
||||
|
||||
pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
pre.code .ln { color: gray; } /* line numbers */
|
||||
pre.code, code { background-color: #eeeeee }
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
span.classifier {
|
||||
font-family: sans-serif ;
|
||||
font-style: oblique }
|
||||
|
||||
span.classifier-delimiter {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
span.interpreted {
|
||||
font-family: sans-serif }
|
||||
|
||||
span.option {
|
||||
white-space: nowrap }
|
||||
|
||||
span.pre {
|
||||
white-space: pre }
|
||||
|
||||
span.problematic, pre.problematic {
|
||||
color: red }
|
||||
|
||||
span.section-subtitle {
|
||||
/* font-size relative to parent (h1..h6 element) */
|
||||
font-size: 80% }
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docinfo {
|
||||
margin: 2em 4em }
|
||||
|
||||
table.docutils {
|
||||
margin-top: 0.5em ;
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
table.footnote {
|
||||
border-left: solid 1px black;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docutils td, table.docutils th,
|
||||
table.docinfo td, table.docinfo th {
|
||||
padding-left: 0.5em ;
|
||||
padding-right: 0.5em ;
|
||||
vertical-align: top }
|
||||
|
||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
||||
font-weight: bold ;
|
||||
text-align: left ;
|
||||
white-space: nowrap ;
|
||||
padding-left: 0 }
|
||||
|
||||
/* "booktabs" style (no vertical lines) */
|
||||
table.docutils.booktabs {
|
||||
border: 0px;
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.docutils.booktabs * {
|
||||
border: 0px;
|
||||
}
|
||||
table.docutils.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
|
||||
font-size: 100% }
|
||||
|
||||
ul.auto-toc {
|
||||
list-style-type: none }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
|
||||
|
||||
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
|
||||
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
|
||||
</a>
|
||||
<div class="section" id="sale-order-import">
|
||||
<h1>Sale Order Import</h1>
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:8e01d803e464dc07c4ec36557747613a5f3db4de2c5c712b493c596addb6ce35
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/edi/tree/16.0/sale_order_import"><img alt="OCA/edi" src="https://img.shields.io/badge/github-OCA%2Fedi-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/edi-16-0/edi-16-0-sale_order_import"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/edi&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||
<p>This module adds support for the import of electronic RFQ or orders. This module provides the base methods to import electronic orders, and you can also plug additional formats by extending the wizard. It requires additional modules to support specific order formats:</p>
|
||||
<ul class="simple">
|
||||
<li>module <em>sale_order_import_ubl</em>: adds support for <a class="reference external" href="http://ubl.xml.org/">Universal Business Language (UBL)</a> RFQs and orders as:<ul>
|
||||
<li>XML file,</li>
|
||||
<li>PDF file with an embedded XML file.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p><strong>Table of contents</strong></p>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#other-credits" id="toc-entry-6">Other credits</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
|
||||
<p>This module adds a wizard in the sale menu named <em>Import RFQ or Order</em>. This wizard will propose you to select the order or RFQ file. Depending on the format of the file (XML or PDF) and the type of file (RFQ or order), it may propose you additional options.</p>
|
||||
<p>When you import an order, if there is a quotation in Odoo for the same customer, the wizard will propose you to either update the existing quotation or create a new order (in fact, it will create a new quotation, so that you are free to make some modifications before you click on the <em>Confirm Sale</em> button to convert the quotation to a sale order).</p>
|
||||
<p>Once the RFQ/order is imported, you should read the messages in the chatter of the quotation because it may contain important information about the import.</p>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/edi/issues">GitHub Issues</a>.
|
||||
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
|
||||
<a class="reference external" href="https://github.com/OCA/edi/issues/new?body=module:%20sale_order_import%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
|
||||
<div class="section" id="authors">
|
||||
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
|
||||
<ul class="simple">
|
||||
<li>Akretion</li>
|
||||
<li>Camptocamp</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
|
||||
<ul class="simple">
|
||||
<li>Alexis de Lattre <<a class="reference external" href="mailto:alexis.delattre@akretion.com">alexis.delattre@akretion.com</a>></li>
|
||||
<li>Dennis Sluijk <<a class="reference external" href="mailto:d.sluijk@onestein.nl">d.sluijk@onestein.nl</a>></li>
|
||||
<li>Andrea Stirpe <<a class="reference external" href="mailto:a.stirpe@onestein.nl">a.stirpe@onestein.nl</a>></li>
|
||||
<li>Simone Orsi <<a class="reference external" href="mailto:simone.orsi@camptocamp.com">simone.orsi@camptocamp.com</a>></li>
|
||||
<li>Duong (Tran Quoc) <<a class="reference external" href="mailto:duongtq@trobz.com">duongtq@trobz.com</a>></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="other-credits">
|
||||
<h3><a class="toc-backref" href="#toc-entry-6">Other credits</a></h3>
|
||||
<p>The migration of this module from 13.0 to 16.0 was financially supported by Camptocamp</p>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
|
||||
<p>This module is maintained by the OCA.</p>
|
||||
<a class="reference external image-reference" href="https://odoo-community.org">
|
||||
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
||||
</a>
|
||||
<p>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.</p>
|
||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/edi/tree/16.0/sale_order_import">OCA/edi</a> project on GitHub.</p>
|
||||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import test_sale_order
|
||||
from . import test_order_import
|
||||
from . import test_parse_validate
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright 2022 Camptocamp SA
|
||||
# @author: Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
import base64
|
||||
import os
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestCommon(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
cls.wiz_model = cls.env["sale.order.import"]
|
||||
cls.partner = cls.env["res.partner"].create({"name": "SO Test"})
|
||||
|
||||
def read_test_file(self, filename, mode="r", as_b64=False):
|
||||
path = os.path.join(os.path.dirname(__file__), "fixtures", filename)
|
||||
with open(path, mode) as thefile:
|
||||
content = thefile.read()
|
||||
return content if not as_b64 else base64.b64encode(content)
|
||||
BIN
odoo-bringout-oca-edi-framework-sale_order_import/sale_order_import/tests/fixtures/test.pdf
vendored
Normal file
BIN
odoo-bringout-oca-edi-framework-sale_order_import/sale_order_import/tests/fixtures/test.pdf
vendored
Normal file
Binary file not shown.
|
|
@ -0,0 +1,182 @@
|
|||
# Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# Copyright 2022 Camptocamp SA
|
||||
# @author: Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
import base64
|
||||
from unittest import mock
|
||||
|
||||
from odoo import exceptions
|
||||
from odoo.tests.common import Form
|
||||
|
||||
from .common import TestCommon
|
||||
|
||||
|
||||
class TestOrderImport(TestCommon):
|
||||
"""Test order create/update."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.parsed_order = {
|
||||
"partner": {"email": "deco.addict82@example.com"},
|
||||
"date": "2018-08-14",
|
||||
"order_ref": "TEST1242",
|
||||
"lines": [
|
||||
{
|
||||
"product": {"code": "FURN_8888"},
|
||||
"qty": 2,
|
||||
"uom": {"unece_code": "C62"},
|
||||
"price_unit": 12.42,
|
||||
}
|
||||
],
|
||||
"chatter_msg": [],
|
||||
"doc_type": "rfq",
|
||||
}
|
||||
|
||||
def test_order_import(self):
|
||||
order = self.wiz_model.create_order(self.parsed_order, "pricelist")
|
||||
self.assertEqual(order.client_order_ref, self.parsed_order["order_ref"])
|
||||
self.assertEqual(
|
||||
order.order_line[0].product_id.default_code,
|
||||
self.parsed_order["lines"][0]["product"]["code"],
|
||||
)
|
||||
self.assertEqual(int(order.order_line[0].product_uom_qty), 2)
|
||||
# Now update the order
|
||||
parsed_order_up = dict(
|
||||
self.parsed_order,
|
||||
partner={"email": "agrolait@yourcompany.example.com"},
|
||||
lines=[
|
||||
{
|
||||
"product": {"code": "FURN_8888"},
|
||||
"qty": 3,
|
||||
"uom": {"unece_code": "C62"},
|
||||
"price_unit": 12.42,
|
||||
},
|
||||
{
|
||||
"product": {"code": "FURN_9999"},
|
||||
"qty": 1,
|
||||
"uom": {"unece_code": "C62"},
|
||||
"price_unit": 1.42,
|
||||
},
|
||||
],
|
||||
)
|
||||
self.wiz_model.update_order_lines(parsed_order_up, order, "pricelist")
|
||||
self.assertEqual(len(order.order_line), 2)
|
||||
self.assertEqual(int(order.order_line[0].product_uom_qty), 3)
|
||||
# test raise UserError if not price_unit
|
||||
parsed_order_up_no_price_unit = dict(
|
||||
self.parsed_order,
|
||||
partner={"email": "agrolait@yourcompany.example.com"},
|
||||
lines=[
|
||||
{
|
||||
"product": {"code": "FURN_7777"},
|
||||
"qty": 4,
|
||||
"uom": {"unece_code": "C62"},
|
||||
},
|
||||
],
|
||||
)
|
||||
parsed_order_up_no_price_unit["doc_type"] = "order"
|
||||
parsed_order_up_no_price_unit["price_source"] = "order"
|
||||
expected_msg = (
|
||||
"No price is defined in the file. Please double check "
|
||||
"file or select Pricelist as the source for prices."
|
||||
)
|
||||
with self.assertRaisesRegex(exceptions.UserError, expected_msg):
|
||||
self.wiz_model.update_order_lines(
|
||||
parsed_order_up_no_price_unit, order, "order"
|
||||
)
|
||||
|
||||
def test_order_import_action(self):
|
||||
wiz = self.wiz_model.create({"import_type": "xml"})
|
||||
action = wiz.create_order_return_action(self.parsed_order, "order.ref")
|
||||
order = self.env["sale.order"].browse(action["res_id"])
|
||||
self.assertEqual(order.state, "draft")
|
||||
|
||||
def test_order_import_confirm(self):
|
||||
wiz = self.wiz_model.create({"import_type": "xml", "confirm_order": True})
|
||||
action = wiz.create_order_return_action(self.parsed_order, "order.ref")
|
||||
order = self.env["sale.order"].browse(action["res_id"])
|
||||
self.assertEqual(order.state, "sale")
|
||||
|
||||
def test_order_import_default_so_vals(self):
|
||||
default = {"client_order_ref": "OVERRIDE"}
|
||||
order = self.wiz_model.with_context(
|
||||
sale_order_import__default_vals=dict(order=default)
|
||||
).create_order(self.parsed_order, "pricelist")
|
||||
self.assertEqual(order.client_order_ref, "OVERRIDE")
|
||||
|
||||
def test_with_order_buttons(self):
|
||||
# Prepare test data
|
||||
order_file_data = base64.b64encode(
|
||||
b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
)
|
||||
order_filename = "test_order.xml"
|
||||
mock_parse_order = mock.patch.object(type(self.wiz_model), "parse_xml_order")
|
||||
# Create a new form
|
||||
with Form(
|
||||
self.wiz_model.with_context(
|
||||
default_order_filename=order_filename,
|
||||
)
|
||||
) as form:
|
||||
with mock_parse_order as mocked:
|
||||
# Return 'rfq' for doc_type
|
||||
mocked.return_value = "rfq"
|
||||
# Set values for the required fields
|
||||
form.import_type = "xml"
|
||||
form.order_file = order_file_data
|
||||
mocked.assert_called()
|
||||
# Test the button with the simulated values
|
||||
mocked.return_value = self.parsed_order
|
||||
action = form.save().import_order_button()
|
||||
self.assertEqual(action["xml_id"], "sale.action_quotations")
|
||||
self.assertEqual(action["view_mode"], "form,tree,calendar,graph")
|
||||
self.assertEqual(action["view_id"], False)
|
||||
mocked.assert_called()
|
||||
so = self.env["sale.order"].browse(action["res_id"])
|
||||
self.assertEqual(so.partner_id.email, "deco.addict82@example.com")
|
||||
self.assertEqual(so.client_order_ref, "TEST1242")
|
||||
self.assertEqual(so.order_line.product_id.code, "FURN_8888")
|
||||
self.assertEqual(so.state, "draft")
|
||||
|
||||
# Create another form to update the above sale order
|
||||
with Form(
|
||||
self.wiz_model.with_context(
|
||||
default_order_filename=order_filename,
|
||||
)
|
||||
) as form:
|
||||
with mock_parse_order as mocked:
|
||||
# Return 'rfq' for doc_type
|
||||
mocked.return_value = "rfq"
|
||||
# Set the required fields
|
||||
form.import_type = "xml"
|
||||
form.order_file = order_file_data
|
||||
parsed_order_up = dict(
|
||||
self.parsed_order,
|
||||
lines=[
|
||||
{
|
||||
"product": {"code": "FURN_8888"},
|
||||
"qty": 3,
|
||||
"uom": {"unece_code": "C62"},
|
||||
"price_unit": 12.42,
|
||||
},
|
||||
{
|
||||
"product": {"code": "FURN_9999"},
|
||||
"qty": 1,
|
||||
"uom": {"unece_code": "C62"},
|
||||
"price_unit": 1.42,
|
||||
},
|
||||
],
|
||||
)
|
||||
mocked.return_value = parsed_order_up
|
||||
action = form.save().import_order_button()
|
||||
form = form.save()
|
||||
self.assertEqual(
|
||||
action["xml_id"], "sale_order_import.sale_order_import_action"
|
||||
)
|
||||
self.assertEqual(form.state, "update")
|
||||
self.assertEqual(form.sale_id, so)
|
||||
form.update_order_button()
|
||||
|
||||
self.assertEqual(len(so.order_line), 2)
|
||||
self.assertEqual(so.order_line[0].product_uom_qty, 3)
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
# Copyright 2022 Camptocamp SA
|
||||
# @author: Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
import base64
|
||||
from unittest import mock
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from odoo import exceptions
|
||||
from odoo.tests.common import Form
|
||||
|
||||
from .common import TestCommon
|
||||
|
||||
|
||||
class TestParsingValidation(TestCommon):
|
||||
"""Mostly unit tests on wizard parsing methods."""
|
||||
|
||||
def test_wrong_import_type(self):
|
||||
order_file_data = base64.b64encode(
|
||||
b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
)
|
||||
order_filename = "test_order.xml"
|
||||
expected_error_message = (
|
||||
"This file 'test_order.xml' is not recognized as"
|
||||
" a PDF file. Please check the file and its extension."
|
||||
)
|
||||
|
||||
with self.assertRaisesRegex(exceptions.UserError, expected_error_message):
|
||||
with Form(
|
||||
self.wiz_model.with_context(default_order_filename=order_filename)
|
||||
) as form:
|
||||
form.import_type = "pdf"
|
||||
form.order_file = order_file_data
|
||||
|
||||
def test_onchange_validation_xml(self):
|
||||
xml_data = base64.b64encode(
|
||||
b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
)
|
||||
|
||||
# Simulate bad file handling
|
||||
mock_parse_xml = mock.patch.object(type(self.wiz_model), "_parse_xml")
|
||||
|
||||
with Form(
|
||||
self.wiz_model.with_context(default_order_filename="test.xml")
|
||||
) as form:
|
||||
with mock_parse_xml as mocked:
|
||||
mocked.return_value = ("", "I don't like this file")
|
||||
with self.assertRaisesRegex(
|
||||
exceptions.UserError, "I don't like this file"
|
||||
):
|
||||
form.import_type = "xml"
|
||||
form.order_file = xml_data
|
||||
mocked.assert_called()
|
||||
|
||||
mock_parse_order = mock.patch.object(type(self.wiz_model), "parse_xml_order")
|
||||
|
||||
with Form(
|
||||
self.wiz_model.with_context(default_order_filename="test.xml")
|
||||
) as form:
|
||||
with mock_parse_order as mocked:
|
||||
mocked.return_value = "rfq"
|
||||
form.import_type = "xml"
|
||||
form.order_file = xml_data
|
||||
mocked.assert_called()
|
||||
self.assertEqual(form.doc_type, "rfq")
|
||||
|
||||
def test_onchange_validation_pdf(self):
|
||||
pdf_data = self.read_test_file("test.pdf", mode="rb", as_b64=True)
|
||||
mock_parse_order = mock.patch.object(type(self.wiz_model), "parse_pdf_order")
|
||||
|
||||
with Form(
|
||||
self.wiz_model.with_context(default_order_filename="test.pdf")
|
||||
) as form:
|
||||
with mock_parse_order as mocked:
|
||||
mocked.return_value = "rfq"
|
||||
form.import_type = "pdf"
|
||||
form.order_file = pdf_data
|
||||
mocked.assert_called()
|
||||
self.assertEqual(form.doc_type, "rfq")
|
||||
|
||||
def test_parse_xml_bad(self):
|
||||
xml_root, error_msg = self.wiz_model._parse_xml("")
|
||||
self.assertEqual(xml_root, None)
|
||||
self.assertEqual(error_msg, "No data provided")
|
||||
xml_root, error_msg = self.wiz_model._parse_xml("something_wrong")
|
||||
self.assertEqual(xml_root, None)
|
||||
self.assertEqual(error_msg, "This XML file is not XML-compliant")
|
||||
|
||||
def test_parse_xml_unsupported(self):
|
||||
xml_data = b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
xml_root, error_msg = self.wiz_model._parse_xml(xml_data)
|
||||
self.assertTrue(isinstance(xml_root, etree._Element))
|
||||
# Due to parse_xml_order NotImplementedError
|
||||
mock_parse_order = mock.patch.object(type(self.wiz_model), "parse_xml_order")
|
||||
with mock_parse_order as mocked:
|
||||
mocked.side_effect = exceptions.UserError("I don't like this file")
|
||||
self.assertTrue(isinstance(xml_root, etree._Element))
|
||||
|
||||
def test_parse_xml_good(self):
|
||||
xml_data = b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
mock_parse_order = mock.patch.object(type(self.wiz_model), "parse_xml_order")
|
||||
with mock_parse_order as mocked:
|
||||
mocked.return_value = "rfq"
|
||||
xml_root, error_msg = self.wiz_model._parse_xml(xml_data)
|
||||
self.assertTrue(isinstance(xml_root, etree._Element))
|
||||
self.assertTrue(error_msg is None)
|
||||
|
||||
def test_parse_pdf_bad(self):
|
||||
pdf_data = self.read_test_file("test.pdf", mode="rb", as_b64=True)
|
||||
mock_pdf_get_xml_files = mock.patch.object(
|
||||
type(self.env["pdf.helper"]), "pdf_get_xml_files"
|
||||
)
|
||||
with mock_pdf_get_xml_files as mocked:
|
||||
mocked.return_value = {}
|
||||
with self.assertRaisesRegex(
|
||||
exceptions.UserError, "There are no embedded XML file in this PDF file."
|
||||
):
|
||||
self.wiz_model.parse_pdf_order(pdf_data)
|
||||
mocked.assert_called()
|
||||
|
||||
def test_parse_pdf_good(self):
|
||||
pdf_data = self.read_test_file("test.pdf", mode="rb", as_b64=True)
|
||||
mock_pdf_get_xml_files = mock.patch.object(
|
||||
type(self.env["pdf.helper"]), "pdf_get_xml_files"
|
||||
)
|
||||
mock_parse_xml_order = mock.patch.object(
|
||||
type(self.wiz_model), "parse_xml_order"
|
||||
)
|
||||
with mock_pdf_get_xml_files as m1, mock_parse_xml_order as m2:
|
||||
m1.return_value = {
|
||||
"test.pdf": etree.fromstring(
|
||||
b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
)
|
||||
}
|
||||
fake_parsed_order = {"got": "a wonderful order"}
|
||||
m2.return_value = fake_parsed_order
|
||||
res = self.wiz_model.parse_pdf_order(pdf_data)
|
||||
m1.assert_called()
|
||||
m2.assert_called()
|
||||
self.assertEqual(res, fake_parsed_order)
|
||||
|
||||
def test_parse_pdf_good_but_no_file(self):
|
||||
pdf_data = self.read_test_file("test.pdf", mode="rb", as_b64=True)
|
||||
mock_pdf_get_xml_files = mock.patch.object(
|
||||
type(self.env["pdf.helper"]), "pdf_get_xml_files"
|
||||
)
|
||||
mock_parse_xml_order = mock.patch.object(
|
||||
type(self.wiz_model), "parse_xml_order"
|
||||
)
|
||||
with mock_pdf_get_xml_files as m1, mock_parse_xml_order as m2:
|
||||
m1.return_value = {
|
||||
"test.pdf": etree.fromstring(
|
||||
b"<?xml version='1.0' encoding='utf-8'?><root><foo>baz</foo></root>"
|
||||
)
|
||||
}
|
||||
m2.side_effect = etree.LxmlError("Bad XML sir!")
|
||||
expected_msg = (
|
||||
"This type of XML RFQ/order is not supported. Did you install "
|
||||
"the module to support this XML format?"
|
||||
)
|
||||
with self.assertRaisesRegex(exceptions.UserError, expected_msg):
|
||||
self.wiz_model.parse_pdf_order(pdf_data)
|
||||
m1.assert_called()
|
||||
m2.assert_called()
|
||||
# same w/ UserError catched somewhere else
|
||||
m2.side_effect = exceptions.UserError("Something is wrong w/ this file")
|
||||
with self.assertRaisesRegex(exceptions.UserError, expected_msg):
|
||||
self.wiz_model.parse_pdf_order(pdf_data)
|
||||
m1.assert_called()
|
||||
m2.assert_called()
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# Copyright 2022 Camptocamp SA
|
||||
# @author: Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestOrderImport(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
|
||||
def test_name_get(self):
|
||||
sale_order = self.env.ref("sale.sale_order_1")
|
||||
name = sale_order.name + _(
|
||||
" Amount w/o tax: %(amount)s %(currency)s",
|
||||
amount=sale_order.amount_untaxed,
|
||||
currency=sale_order.currency_id.name,
|
||||
)
|
||||
so = self.env["sale.order"].with_context(sale_order_show_amount=True)
|
||||
name_get_res = so.search([("id", "=", sale_order.id)]).name_get()
|
||||
self.assertEqual(name, name_get_res[0][1])
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import sale_order_import
|
||||
|
|
@ -0,0 +1,690 @@
|
|||
# Copyright 2016-2017 Akretion
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# Copyright 2022 Camptocamp
|
||||
# @author: Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
import mimetypes
|
||||
from base64 import b64decode, b64encode
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.osv.expression import AND
|
||||
from odoo.tools import config, float_compare, float_is_zero
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SaleOrderImport(models.TransientModel):
|
||||
_name = "sale.order.import"
|
||||
_description = "Sale Order Import from Files"
|
||||
|
||||
state = fields.Selection(
|
||||
[("import", "Import"), ("update", "Update")], default="import"
|
||||
)
|
||||
partner_id = fields.Many2one("res.partner", string="Customer")
|
||||
import_type = fields.Selection(
|
||||
[("xml", "XML"), ("pdf", "PDF")],
|
||||
required=True,
|
||||
default=None,
|
||||
help="Select a type which you want to import",
|
||||
)
|
||||
order_file = fields.Binary(
|
||||
string="Request for Quotation or Order",
|
||||
required=True,
|
||||
help="Upload a Request for Quotation or an Order file. Supported "
|
||||
"formats: XML and PDF (PDF with an embeded XML file).",
|
||||
)
|
||||
order_filename = fields.Char(string="Filename")
|
||||
doc_type = fields.Selection(
|
||||
[("rfq", "Request For Quotation"), ("order", "Sale Order")],
|
||||
string="Document Type",
|
||||
readonly=True,
|
||||
)
|
||||
price_source = fields.Selection(
|
||||
[("pricelist", "Pricelist"), ("order", "Customer Order")],
|
||||
string="Apply Prices From",
|
||||
)
|
||||
# for state = update
|
||||
commercial_partner_id = fields.Many2one(
|
||||
"res.partner", string="Commercial Entity", readonly=True
|
||||
)
|
||||
partner_shipping_id = fields.Many2one(
|
||||
"res.partner", string="Shipping Address", readonly=True
|
||||
)
|
||||
sale_id = fields.Many2one("sale.order", string="Quotation to Update")
|
||||
confirm_order = fields.Boolean(default=False)
|
||||
|
||||
@api.onchange("order_file")
|
||||
def order_file_change(self):
|
||||
if not self.order_filename or not self.order_file:
|
||||
self.doc_type = False
|
||||
return
|
||||
|
||||
doc_type = self._parse_file(
|
||||
self.order_filename, b64decode(self.order_file), detect_doc_type=True
|
||||
)
|
||||
if doc_type is None:
|
||||
return {"warning": self._unsupported_file_msg(self.order_filename)}
|
||||
self.doc_type = doc_type
|
||||
|
||||
def _get_supported_types(self):
|
||||
# Define the supported types dictionary
|
||||
supported_types = {
|
||||
"xml": ("application/xml", "text/xml"),
|
||||
"pdf": ("application/pdf"),
|
||||
}
|
||||
return supported_types
|
||||
|
||||
def _parse_file(self, filename, filecontent, detect_doc_type=False):
|
||||
assert filename, "Missing filename"
|
||||
assert filecontent, "Missing file content"
|
||||
filetype = mimetypes.guess_type(filename)
|
||||
logger.debug("Order file mimetype: %s", filetype)
|
||||
mimetype = filetype[0]
|
||||
supported_types = self._get_supported_types()
|
||||
# Check if the selected import type is supported
|
||||
if self.import_type not in supported_types:
|
||||
raise UserError(_("Please select a valid import type before importing!"))
|
||||
|
||||
# Check if the detected MIME type is supported for the selected import type
|
||||
if mimetype not in supported_types[self.import_type]:
|
||||
raise UserError(
|
||||
_(
|
||||
"This file '%(filename)s' is not recognized as a %(type)s file. "
|
||||
"Please check the file and its extension.",
|
||||
filename=filename,
|
||||
type=self.import_type.upper(),
|
||||
)
|
||||
)
|
||||
|
||||
if parser_method := getattr(self, f"parse_{self.import_type}_order", None):
|
||||
return parser_method(filecontent, detect_doc_type=detect_doc_type)
|
||||
else:
|
||||
logger.error(
|
||||
"%(meth)s not found %(itype)s not supported",
|
||||
meth=f"parse_{self.import_type}_order",
|
||||
itype=self.import_type,
|
||||
)
|
||||
raise UserError(
|
||||
_(
|
||||
"This Import Type is not supported. Did you install "
|
||||
"the module to support this type?"
|
||||
)
|
||||
)
|
||||
|
||||
def _unsupported_file_msg(self, filename):
|
||||
return {
|
||||
"title": _("Unsupported file format"),
|
||||
"message": _(
|
||||
"This file '%s' is not recognised as a XML nor "
|
||||
"PDF file. Please check the file and it's "
|
||||
"extension."
|
||||
)
|
||||
% filename,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _parse_xml(self, data):
|
||||
if not data:
|
||||
return None, _("No data provided")
|
||||
xml_root = None
|
||||
try:
|
||||
xml_root = etree.fromstring(data)
|
||||
error_msg = None
|
||||
except etree.XMLSyntaxError:
|
||||
error_msg = _("This XML file is not XML-compliant")
|
||||
return xml_root, error_msg
|
||||
return xml_root, error_msg
|
||||
|
||||
@api.model
|
||||
def parse_xml_order(self, data, detect_doc_type=False):
|
||||
if not self.env.context.get("xml_root", False):
|
||||
xml_root, error_msg = self._parse_xml(data)
|
||||
else:
|
||||
xml_root = data
|
||||
error_msg = None
|
||||
if (xml_root is None or not len(xml_root)) and error_msg:
|
||||
raise UserError(error_msg)
|
||||
raise NotImplementedError(
|
||||
_(
|
||||
"This type of XML RFQ/order is not supported. Did you install "
|
||||
"the module to support this XML format?"
|
||||
)
|
||||
)
|
||||
|
||||
@api.model
|
||||
def parse_pdf_order(self, order_file, detect_doc_type=False):
|
||||
"""
|
||||
Get PDF attachments, filter on XML files and call import_order_xml
|
||||
"""
|
||||
xml_files_dict = self.env["pdf.helper"].pdf_get_xml_files(order_file)
|
||||
if not xml_files_dict:
|
||||
raise UserError(_("There are no embedded XML file in this PDF file."))
|
||||
for xml_filename, xml_root in xml_files_dict.items():
|
||||
logger.info("Trying to parse XML file %s", xml_filename)
|
||||
try:
|
||||
parsed_order = self.with_context(xml_root=True).parse_xml_order(
|
||||
xml_root, detect_doc_type=detect_doc_type
|
||||
)
|
||||
return parsed_order
|
||||
except (etree.LxmlError, UserError):
|
||||
continue
|
||||
raise UserError(
|
||||
_(
|
||||
"This type of XML RFQ/order is not supported. Did you install "
|
||||
"the module to support this XML format?"
|
||||
)
|
||||
)
|
||||
|
||||
# Format of parsed_order
|
||||
# {
|
||||
# 'partner': {
|
||||
# 'vat': 'FR25499247138',
|
||||
# 'name': 'Camptocamp',
|
||||
# 'email': 'luc@camptocamp.com',
|
||||
# },
|
||||
# 'ship_to': {
|
||||
# 'partner': partner_dict,
|
||||
# 'address': {
|
||||
# 'country_code': 'FR',
|
||||
# 'state_code': False,
|
||||
# 'zip': False,
|
||||
# },
|
||||
# 'company': {'vat': 'FR12123456789'}, # Only used to check we are not
|
||||
# # importing the order in the
|
||||
# # wrong company by mistake
|
||||
# 'date': '2016-08-16', # order date
|
||||
# 'order_ref': 'PO1242', # Customer PO number
|
||||
# 'currency': {'iso': 'EUR', 'symbol': u'€'},
|
||||
# 'incoterm': 'EXW',
|
||||
# 'note': 'order notes of the customer',
|
||||
# 'chatter_msg': ['msg1', 'msg2']
|
||||
# 'lines': [{
|
||||
# 'product': {
|
||||
# 'code': 'EA7821',
|
||||
# 'ean13': '2100002000003',
|
||||
# },
|
||||
# 'qty': 2.5,
|
||||
# 'uom': {'unece_code': 'C62'},
|
||||
# 'price_unit': 12.42, # without taxes
|
||||
# 'doc_type': 'rfq' or 'order',
|
||||
# }]
|
||||
|
||||
@api.model
|
||||
def _search_existing_order_domain(
|
||||
self, parsed_order, commercial_partner, state_domain
|
||||
):
|
||||
return AND(
|
||||
[
|
||||
state_domain,
|
||||
[
|
||||
("client_order_ref", "=", parsed_order["order_ref"]),
|
||||
("commercial_partner_id", "=", commercial_partner.id),
|
||||
],
|
||||
]
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _prepare_order(self, parsed_order, price_source):
|
||||
soo = self.env["sale.order"]
|
||||
bdio = self.env["business.document.import"]
|
||||
partner = bdio._match_partner(
|
||||
parsed_order["partner"],
|
||||
parsed_order["chatter_msg"],
|
||||
partner_type="customer",
|
||||
)
|
||||
currency = bdio._match_currency(
|
||||
parsed_order.get("currency"), parsed_order["chatter_msg"]
|
||||
)
|
||||
# FIXME: this should work but it's not as it breaks core price compute
|
||||
# so_vals = soo.default_get(soo._fields.keys())
|
||||
so_vals = {
|
||||
"partner_id": partner.id,
|
||||
"client_order_ref": parsed_order.get("order_ref"),
|
||||
}
|
||||
self._validate_currency(partner, currency)
|
||||
self._validate_existing_orders(partner, parsed_order)
|
||||
so_vals = soo.play_onchanges(so_vals, ["partner_id"])
|
||||
so_vals["order_line"] = []
|
||||
if parsed_order.get("ship_to"):
|
||||
shipping_partner = bdio._match_shipping_partner(
|
||||
parsed_order["ship_to"], partner, parsed_order["chatter_msg"]
|
||||
)
|
||||
so_vals["partner_shipping_id"] = shipping_partner.id
|
||||
|
||||
if parsed_order.get("delivery_detail"):
|
||||
so_vals.update(parsed_order.get("delivery_detail"))
|
||||
|
||||
if parsed_order.get("invoice_to"):
|
||||
invoicing_partner = bdio._match_partner(
|
||||
parsed_order["invoice_to"], parsed_order["chatter_msg"], partner_type=""
|
||||
)
|
||||
so_vals["partner_invoice_id"] = invoicing_partner.id
|
||||
if parsed_order.get("date"):
|
||||
so_vals["date_order"] = parsed_order["date"]
|
||||
for line in parsed_order["lines"]:
|
||||
# partner=False because we don't want to use product.supplierinfo
|
||||
product = bdio._match_product(
|
||||
line["product"], parsed_order["chatter_msg"], seller=False
|
||||
)
|
||||
uom = bdio._match_uom(line.get("uom"), parsed_order["chatter_msg"], product)
|
||||
line_vals = self._prepare_create_order_line(
|
||||
product, uom, so_vals, line, price_source
|
||||
)
|
||||
so_vals["order_line"].append((0, 0, line_vals))
|
||||
|
||||
defaults = self.env.context.get("sale_order_import__default_vals", {}).get(
|
||||
"order", {}
|
||||
)
|
||||
so_vals.update(defaults)
|
||||
return so_vals
|
||||
|
||||
def _validate_currency(self, partner, currency):
|
||||
if partner.property_product_pricelist.currency_id != currency:
|
||||
raise UserError(
|
||||
_(
|
||||
"The customer '%(name)s' has a pricelist '%(pricelist)s' but the "
|
||||
"currency of this order is '%(currency)s'.",
|
||||
name=partner.display_name,
|
||||
pricelist=partner.property_product_pricelist.display_name,
|
||||
currency=currency.name,
|
||||
)
|
||||
)
|
||||
|
||||
def _validate_existing_orders(self, partner, parsed_order):
|
||||
if not parsed_order.get("order_ref"):
|
||||
return
|
||||
commercial_partner = partner.commercial_partner_id
|
||||
existing_orders = self.env["sale.order"].search(
|
||||
self._search_existing_order_domain(
|
||||
parsed_order, commercial_partner, [("state", "!=", "cancel")]
|
||||
),
|
||||
limit=1,
|
||||
)
|
||||
if existing_orders:
|
||||
raise UserError(
|
||||
_(
|
||||
"An order of customer '%(partner)s' with reference '%(ref)s' "
|
||||
"already exists: %(name)s (state: %(state)s)",
|
||||
partner=partner.display_name,
|
||||
ref=parsed_order["order_ref"],
|
||||
name=existing_orders[0].name,
|
||||
state=existing_orders[0].state,
|
||||
)
|
||||
)
|
||||
|
||||
# TODO: I wonder why these methods are model methods
|
||||
@api.model
|
||||
def create_order(
|
||||
self, parsed_order, price_source, order_filename=None, confirm_order=False
|
||||
):
|
||||
soo = self.env["sale.order"].with_context(mail_create_nosubscribe=True)
|
||||
bdio = self.env["business.document.import"]
|
||||
so_vals = self._prepare_order(parsed_order, price_source)
|
||||
order = soo.create(so_vals)
|
||||
if confirm_order:
|
||||
order.action_confirm()
|
||||
bdio.post_create_or_update(parsed_order, order, doc_filename=order_filename)
|
||||
logger.info("Sale Order ID %d created", order.id)
|
||||
return order
|
||||
|
||||
@api.model
|
||||
def create_order_ws(
|
||||
self, parsed_order, price_source, order_filename=None, confirm_order=False
|
||||
):
|
||||
"""Same method as create_order() but callable via JSON-RPC
|
||||
webservice. Returns an ID to avoid this error:
|
||||
TypeError: sale.order(15,) is not JSON serializable"""
|
||||
order = self.create_order(
|
||||
parsed_order,
|
||||
price_source,
|
||||
order_filename=order_filename,
|
||||
confirm_order=confirm_order,
|
||||
)
|
||||
return order.id
|
||||
|
||||
@api.model
|
||||
def parse_order(self, order_file, order_filename, partner=False):
|
||||
parsed_order = self._parse_file(order_filename, order_file)
|
||||
logger.debug("Result of order parsing: %s", parsed_order)
|
||||
defaults = (
|
||||
("attachments", {}),
|
||||
("chatter_msg", []),
|
||||
)
|
||||
for key, val in defaults:
|
||||
parsed_order.setdefault(key, val)
|
||||
|
||||
parsed_order["attachments"][order_filename] = b64encode(order_file)
|
||||
if (
|
||||
parsed_order.get("company")
|
||||
and not config["test_enable"]
|
||||
and not self._context.get("edi_skip_company_check")
|
||||
):
|
||||
self.env["business.document.import"]._check_company(
|
||||
parsed_order["company"], parsed_order["chatter_msg"]
|
||||
)
|
||||
return parsed_order
|
||||
|
||||
def import_order_button(self):
|
||||
self.ensure_one()
|
||||
bdio = self.env["business.document.import"]
|
||||
order_file_decoded = b64decode(self.order_file)
|
||||
parsed_order = self.parse_order(
|
||||
order_file_decoded, self.order_filename, self.partner_id
|
||||
)
|
||||
if not parsed_order.get("lines"):
|
||||
raise UserError(_("This order doesn't have any line !"))
|
||||
partner = bdio._match_partner(
|
||||
parsed_order["partner"], [], partner_type="customer"
|
||||
)
|
||||
commercial_partner = partner.commercial_partner_id
|
||||
partner_shipping_id = False
|
||||
if parsed_order.get("ship_to"):
|
||||
partner_shipping_id = bdio._match_shipping_partner(
|
||||
parsed_order["ship_to"], partner, []
|
||||
).id
|
||||
existing_quotations = self.env["sale.order"].search(
|
||||
self._search_existing_order_domain(
|
||||
parsed_order, commercial_partner, [("state", "in", ("draft", "sent"))]
|
||||
)
|
||||
)
|
||||
if existing_quotations:
|
||||
default_sale_id = False
|
||||
if len(existing_quotations) == 1:
|
||||
default_sale_id = existing_quotations[0].id
|
||||
self.write(
|
||||
{
|
||||
"commercial_partner_id": commercial_partner.id,
|
||||
"partner_shipping_id": partner_shipping_id,
|
||||
"state": "update",
|
||||
"sale_id": default_sale_id,
|
||||
"doc_type": parsed_order.get("doc_type"),
|
||||
}
|
||||
)
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"sale_order_import.sale_order_import_action"
|
||||
)
|
||||
action["res_id"] = self.id
|
||||
return action
|
||||
else:
|
||||
return self.create_order_return_action(parsed_order, self.order_filename)
|
||||
|
||||
def create_order_button(self):
|
||||
self.ensure_one()
|
||||
parsed_order = self.parse_order(
|
||||
b64decode(self.order_file), self.order_filename, self.partner_id
|
||||
)
|
||||
return self.create_order_return_action(parsed_order, self.order_filename)
|
||||
|
||||
def create_order_return_action(self, parsed_order, order_filename):
|
||||
self.ensure_one()
|
||||
order = self.create_order(
|
||||
parsed_order,
|
||||
self.price_source,
|
||||
order_filename,
|
||||
confirm_order=self._order_should_be_confirmed(),
|
||||
)
|
||||
order.message_post(
|
||||
body=_("Created automatically via file import (%s).") % self.order_filename
|
||||
)
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("sale.action_quotations")
|
||||
action.update(
|
||||
{
|
||||
"view_mode": "form,tree,calendar,graph",
|
||||
"views": False,
|
||||
"view_id": False,
|
||||
"res_id": order.id,
|
||||
}
|
||||
)
|
||||
return action
|
||||
|
||||
def _order_should_be_confirmed(self):
|
||||
# Hook to override behavior
|
||||
return self.confirm_order
|
||||
|
||||
# TODO: add tests
|
||||
@api.model
|
||||
def _prepare_update_order_vals(self, parsed_order, order, partner):
|
||||
bdio = self.env["business.document.import"]
|
||||
partner = bdio._match_partner(
|
||||
parsed_order["partner"],
|
||||
parsed_order["chatter_msg"],
|
||||
partner_type="customer",
|
||||
)
|
||||
vals = {"partner_id": partner.id}
|
||||
if parsed_order.get("ship_to"):
|
||||
shipping_partner = bdio._match_shipping_partner(
|
||||
parsed_order["ship_to"], partner, parsed_order["chatter_msg"]
|
||||
)
|
||||
vals["partner_shipping_id"] = shipping_partner.id
|
||||
if parsed_order.get("order_ref"):
|
||||
vals["client_order_ref"] = parsed_order["order_ref"]
|
||||
return vals
|
||||
|
||||
@api.model
|
||||
def _prepare_create_order_line(
|
||||
self, product, uom, order, import_line, price_source
|
||||
):
|
||||
"""the 'order' arg can be a recordset (in case of an update of a sale order)
|
||||
or a dict (in case of the creation of a new sale order)"""
|
||||
solo = self.env["sale.order.line"]
|
||||
vals = {}
|
||||
# Ensure the company is loaded before we play onchanges.
|
||||
# Yes, `company_id` is related to `order_id.company_id`
|
||||
# but when we call `play_onchanges` it will be empty
|
||||
# w/out this precaution.
|
||||
company_id = self._prepare_order_line_get_company_id(order)
|
||||
vals.update(
|
||||
{
|
||||
"product_id": product.id,
|
||||
"product_uom_qty": import_line["qty"],
|
||||
"product_uom": uom.id,
|
||||
"company_id": company_id,
|
||||
}
|
||||
)
|
||||
|
||||
if price_source == "order":
|
||||
if "price_unit" not in import_line:
|
||||
raise UserError(
|
||||
_(
|
||||
"No price is defined in the file. Please double check "
|
||||
"file or select Pricelist as the source for prices."
|
||||
)
|
||||
)
|
||||
vals["price_unit"] = import_line["price_unit"]
|
||||
elif price_source == "pricelist":
|
||||
# product_id_change is played in the inherit of create()
|
||||
# of sale.order.line cf odoo/addons/sale/models/sale.py
|
||||
# but it is not enough: we also need to play _onchange_discount()
|
||||
# to have the right discount for pricelist
|
||||
vals["order_id"] = order
|
||||
vals.pop("order_id")
|
||||
|
||||
# Handle additional fields dynamically if available.
|
||||
# If a field is added to a record and its value is injected by a parser
|
||||
# you won't have to override `_prepare_create_order_line`
|
||||
# to let it propagate.
|
||||
for k, v in import_line.items():
|
||||
if k not in vals and k in solo._fields:
|
||||
vals[k] = v
|
||||
|
||||
defaults = self.env.context.get("sale_order_import__default_vals", {}).get(
|
||||
"lines", {}
|
||||
)
|
||||
vals.update(defaults)
|
||||
return vals
|
||||
|
||||
def _prepare_order_line_get_company_id(self, order):
|
||||
company_id = self.env.company.id
|
||||
if isinstance(order, models.Model):
|
||||
company_id = order.company_id.id
|
||||
elif isinstance(order, dict):
|
||||
company_id = order.get("company_id") or company_id
|
||||
return company_id
|
||||
|
||||
# TODO: add tests
|
||||
@api.model
|
||||
def update_order_lines(self, parsed_order, order, price_source):
|
||||
chatter = parsed_order["chatter_msg"]
|
||||
solo = self.env["sale.order.line"]
|
||||
dpo = self.env["decimal.precision"]
|
||||
bdio = self.env["business.document.import"]
|
||||
qty_prec = dpo.precision_get("Product UoS")
|
||||
price_prec = dpo.precision_get("Product Price")
|
||||
existing_lines = []
|
||||
for oline in order.order_line:
|
||||
# compute price unit without tax
|
||||
price_unit = 0.0
|
||||
if not float_is_zero(oline.product_uom_qty, precision_digits=qty_prec):
|
||||
qty = float(oline.product_uom_qty)
|
||||
price_unit = oline.price_subtotal / qty
|
||||
existing_lines.append(
|
||||
{
|
||||
"product": oline.product_id or False,
|
||||
"name": oline.name,
|
||||
"qty": oline.product_uom_qty,
|
||||
"uom": oline.product_uom,
|
||||
"line": oline,
|
||||
"price_unit": price_unit,
|
||||
}
|
||||
)
|
||||
compare_res = bdio.compare_lines(
|
||||
existing_lines,
|
||||
parsed_order["lines"],
|
||||
chatter,
|
||||
qty_precision=qty_prec,
|
||||
seller=False,
|
||||
)
|
||||
# NOW, we start to write/delete/create the order lines
|
||||
for oline, cdict in compare_res["to_update"].items():
|
||||
write_vals = {}
|
||||
# TODO: add support for price_source == order
|
||||
if cdict.get("qty"):
|
||||
chatter.append(
|
||||
_(
|
||||
"The quantity has been updated on the order line "
|
||||
"with product '%(product)s' from %(qty0)s to %(qty1)s %(uom)s",
|
||||
product=oline.product_id.display_name,
|
||||
qty0=cdict["qty"][0],
|
||||
qty1=cdict["qty"][1],
|
||||
uom=oline.product_uom.name,
|
||||
)
|
||||
)
|
||||
write_vals["product_uom_qty"] = cdict["qty"][1]
|
||||
if price_source != "order":
|
||||
new_price_unit = order.pricelist_id.with_context(
|
||||
date=order.date_order, uom=oline.product_uom.id
|
||||
)._price_get(oline.product_id, write_vals["product_uom_qty"],)[
|
||||
order.pricelist_id.id
|
||||
]
|
||||
if float_compare(
|
||||
new_price_unit, oline.price_unit, precision_digits=price_prec
|
||||
):
|
||||
chatter.append(
|
||||
_(
|
||||
"The unit price has been updated on the order "
|
||||
"line with product '%(product)s' from %(old)s to "
|
||||
"%(new)s %(currency)s",
|
||||
product=oline.product_id.display_name,
|
||||
old=oline.price_unit,
|
||||
new=new_price_unit,
|
||||
currency=order.currency_id.name,
|
||||
)
|
||||
)
|
||||
write_vals["price_unit"] = new_price_unit
|
||||
write_vals.update(self._prepare_update_order_line_vals(cdict))
|
||||
if write_vals:
|
||||
oline.write(write_vals)
|
||||
if compare_res["to_remove"]:
|
||||
to_remove_label = [
|
||||
f"{line.product_uom_qty} {line.product_uom.name} "
|
||||
f"x {line.product_id.name}"
|
||||
for line in compare_res["to_remove"]
|
||||
]
|
||||
chatter.append(
|
||||
_(
|
||||
"%(orders)s order line(s) deleted: %(label)s",
|
||||
orders=len(compare_res["to_remove"]),
|
||||
label=", ".join(to_remove_label),
|
||||
)
|
||||
)
|
||||
compare_res["to_remove"].unlink()
|
||||
if compare_res["to_add"]:
|
||||
to_create_label = []
|
||||
for add in compare_res["to_add"]:
|
||||
line_vals = self._prepare_create_order_line(
|
||||
add["product"], add["uom"], order, add["import_line"], price_source
|
||||
)
|
||||
line_vals["order_id"] = order.id
|
||||
new_line = solo.create(line_vals)
|
||||
to_create_label.append(
|
||||
f"{new_line.product_uom_qty} {new_line.product_uom.name} "
|
||||
f"x {new_line.name}"
|
||||
)
|
||||
chatter.append(
|
||||
_(
|
||||
"%(orders)s new order line(s) created: %(label)s",
|
||||
orders=len(compare_res["to_add"]),
|
||||
label=", ".join(to_create_label),
|
||||
)
|
||||
)
|
||||
return True
|
||||
|
||||
def _prepare_update_order_line_vals(self, change_dict):
|
||||
# Allows other module to update some fields on the line
|
||||
return {}
|
||||
|
||||
def update_order_button(self):
|
||||
self.ensure_one()
|
||||
bdio = self.env["business.document.import"]
|
||||
order = self.sale_id
|
||||
if not order:
|
||||
raise UserError(_("You must select a quotation to update."))
|
||||
parsed_order = self.parse_order(
|
||||
b64decode(self.order_file), self.order_filename, self.partner_id
|
||||
)
|
||||
currency = bdio._match_currency(
|
||||
parsed_order.get("currency"), parsed_order["chatter_msg"]
|
||||
)
|
||||
if currency != order.currency_id:
|
||||
raise UserError(
|
||||
_(
|
||||
"The currency of the imported order (%(old)s) is different from "
|
||||
"the currency of the existing order (%(new)s)",
|
||||
old=currency.name,
|
||||
new=order.currency_id.name,
|
||||
)
|
||||
)
|
||||
vals = self._prepare_update_order_vals(
|
||||
parsed_order, order, self.commercial_partner_id
|
||||
)
|
||||
if vals:
|
||||
order.write(vals)
|
||||
self.update_order_lines(parsed_order, order, self.price_source)
|
||||
bdio.post_create_or_update(parsed_order, order)
|
||||
logger.info(
|
||||
"Quotation ID %d updated via import of file %s",
|
||||
order.id,
|
||||
self.order_filename,
|
||||
)
|
||||
order.message_post(
|
||||
body=_(
|
||||
"This quotation has been updated automatically via the import of "
|
||||
"file %s"
|
||||
)
|
||||
% self.order_filename
|
||||
)
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id("sale.action_quotations")
|
||||
action.update(
|
||||
{
|
||||
"view_mode": "form,tree,calendar,graph",
|
||||
"views": False,
|
||||
"view_id": False,
|
||||
"res_id": order.id,
|
||||
}
|
||||
)
|
||||
return action
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
© 2016-2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
<odoo>
|
||||
<record id="sale_order_import_form" model="ir.ui.view">
|
||||
<field name="name">sale.order.import.form</field>
|
||||
<field name="model">sale.order.import</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Import Sale Orders">
|
||||
<group name="technical" invisible="1">
|
||||
<field name="state" />
|
||||
</group>
|
||||
<group colspan="4" name="help-import" states="import">
|
||||
<div colspan="2">
|
||||
<p
|
||||
>Upload below the customer order or request for quotation as XML or PDF file. When you click on the Import button:</p>
|
||||
<ol>
|
||||
<li
|
||||
>If it is an XML file, Odoo will parse it if the module that adds support for this XML format is installed. For the <a
|
||||
href="http://ubl.xml.org/"
|
||||
target="_blank"
|
||||
>Universal Business Language</a> format (UBL), you should install the module <em
|
||||
>sale_order_import_ubl</em>.</li>
|
||||
<li
|
||||
>If it is a PDF file, Odoo will try to find an XML file in the attachments of the PDF file and then use this XML file to create the quotation.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</group>
|
||||
<group colspan="4" name="help-update" states="update">
|
||||
<div colspan="2">
|
||||
<p
|
||||
>Some quotations have been found for this customer ; one of them may correspond to the order or RFQ that you are importing. You can either select an existing quotation to update or create a new one.</p>
|
||||
</div>
|
||||
</group>
|
||||
<group name="import" states="import">
|
||||
<field name="import_type" />
|
||||
<field
|
||||
name="order_file"
|
||||
filename="order_filename"
|
||||
attrs="{'readonly': [('import_type', '=', False)]}"
|
||||
/>
|
||||
<field name="order_filename" invisible="1" />
|
||||
</group>
|
||||
<group name="update" states="update">
|
||||
<field name="commercial_partner_id" />
|
||||
<field
|
||||
name="partner_shipping_id"
|
||||
context="{'show_address': 1}"
|
||||
options="{'always_reload': 1}"
|
||||
/>
|
||||
<field
|
||||
name="sale_id"
|
||||
domain="[('state', 'in', ('draft', 'sent')), ('commercial_partner_id', '=', commercial_partner_id)]"
|
||||
/>
|
||||
</group>
|
||||
<group name="common">
|
||||
<field name="doc_type" />
|
||||
<field
|
||||
name="price_source"
|
||||
attrs="{'invisible': [('doc_type', '!=', 'order')], 'required': [('doc_type', '=', 'order')]}"
|
||||
/>
|
||||
<field name="confirm_order" />
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="import_order_button"
|
||||
type="object"
|
||||
states="import"
|
||||
class="oe_highlight"
|
||||
string="Import"
|
||||
/>
|
||||
<button
|
||||
name="update_order_button"
|
||||
type="object"
|
||||
states="update"
|
||||
class="oe_highlight"
|
||||
string="Update Existing"
|
||||
/>
|
||||
<button
|
||||
name="create_order_button"
|
||||
type="object"
|
||||
states="update"
|
||||
class="oe_highlight"
|
||||
string="Create New"
|
||||
/>
|
||||
<button special="cancel" string="Cancel" class="oe_link" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="sale_order_import_action" model="ir.actions.act_window">
|
||||
<field name="name">Import RFQ or Order</field>
|
||||
<field name="res_model">sale.order.import</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'sale_order_show_amount': True}</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="sale_order_import_menu"
|
||||
parent="sale.sale_order_menu"
|
||||
action="sale_order_import_action"
|
||||
sequence="12"
|
||||
/>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue