Initial commit: OCA Edi packages (42 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:05 +02:00
commit df976c03db
2184 changed files with 571602 additions and 0 deletions

View file

@ -0,0 +1,47 @@
# Import Business Document EDIFACT/D96A Order
Odoo addon: sale_order_import_edifact
## Installation
```bash
pip install odoo-bringout-oca-edi-framework-sale_order_import_edifact
```
## Dependencies
This addon depends on:
- sale_management
- partner_identification_gln
- base_edifact
- sale_order_import
## Manifest Information
- **Name**: Import Business Document EDIFACT/D96A Order
- **Version**: 16.0.1.1.0
- **Category**: Sales Management
- **License**: AGPL-3
- **Installable**: False
## Source
Based on [OCA/edi-framework](https://github.com/OCA/edi-framework) branch 16.0, addon `sale_order_import_edifact`.
## 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

View file

@ -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_edifact Module - sale_order_import_edifact
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.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for sale_order_import_edifact. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,8 @@
# Dependencies
This addon depends on:
- [sale_management](../../odoo-bringout-oca-ocb-sale_management)
- partner_identification_gln
- [base_edifact](../../odoo-bringout-oca-edi-base_edifact)
- [sale_order_import](../../odoo-bringout-oca-edi-framework-sale_order_import)

View file

@ -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_edifact or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-edi-framework-sale_order_import_edifact"
# or
uv pip install odoo-bringout-oca-edi-framework-sale_order_import_edifact"
```

View file

@ -0,0 +1,12 @@
# Models
Detected core models and extensions in sale_order_import_edifact.
```mermaid
classDiagram
class business_document_import
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: sale_order_import_edifact. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon sale_order_import_edifact
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -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.

View file

@ -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_edifact
```

View file

@ -0,0 +1,8 @@
# Wizards
Transient models exposed as UI wizards in sale_order_import_edifact.
```mermaid
classDiagram
class SaleOrderImport
```

View file

@ -0,0 +1,45 @@
[project]
name = "odoo-bringout-oca-edi-framework-sale_order_import_edifact"
version = "16.0.0"
description = "Import Business Document EDIFACT/D96A Order - EDIFACT/D96A Order"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-edi-framework-sale_management>=16.0.0",
"odoo-bringout-oca-edi-framework-partner_identification_gln>=16.0.0",
"odoo-bringout-oca-edi-framework-base_edifact>=16.0.0",
"odoo-bringout-oca-edi-framework-sale_order_import>=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_edifact"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]

View file

@ -0,0 +1,137 @@
===========================================
Import Business Document EDIFACT/D96A Order
===========================================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:73a00474d97ec5b99974450168fa2e4e38572a70c95790882f1a5f2fe60d517a
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fedi-lightgray.png?logo=github
:target: https://github.com/OCA/edi/tree/16.0/sale_order_import_edifact
: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_edifact
: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|
UN/EDIFACT
United Nations rules for Elec­tronic Data Interchange for Administration, Commerce and Transport
This module plugs EDIFACT/D96A ORDER in sale_order_import process.
https://www.stedi.com/edi/edifact/D96A/messages/ORDERS
.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_
**Table of contents**
.. contents::
:local:
Configuration
=============
This module struggles with EDIFACT format, if you need X12 format you will need something like sale_order_import_x12 module.
Regardless format, a concret document should need a concret specification nammed release. For example Amazon uses "D96A" specification.
See <https://www.stedi.com/edi/edifact>
Known issues / Roadmap
======================
* Move the previews button feature to the base module
Changelog
=========
.. The change log. The goal of this file is to help readers
understand changes between versions. The primary audience is
end users and integrators. Purely technical changes such as
code refactoring must not be mentioned here.
This file may contain ONE level of section titles, underlined
with the ~ (tilde) character. Other section markers are
forbidden and will likely break the structure of the README.rst
or other documents where this fragment is included.
14.0.1.0.0 (2023-06-07)
~~~~~~~~~~~~~~~~~~~~~~~
* [14.0][ADD] sale_order_import_edifact & base_edifact.
(`#779 <https://github.com/OCA/edi/pull/779>`_)
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_edifact%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
~~~~~~~
* ALBA Software
* Camptocamp
Contributors
~~~~~~~~~~~~
* Rafa Morant <rmorant@albasoft.com> (https://www.albasoft.com)
* Marc Poch <mpoch@planetatic.com>
* Duong (Tran Quoc) <duongtq@trobz.com>
* Simone Orsi <simone.orsi@camptocamp.com>
Other credits
~~~~~~~~~~~~~
The migration of this module from 14.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.
.. |maintainer-rmorant| image:: https://github.com/rmorant.png?size=40px
:target: https://github.com/rmorant
:alt: rmorant
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-rmorant|
This module is part of the `OCA/edi <https://github.com/OCA/edi/tree/16.0/sale_order_import_edifact>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1,2 @@
from . import models
from . import wizard

View file

@ -0,0 +1,24 @@
# Copyright 2023 ALBA Software S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)
{
"name": "Import Business Document EDIFACT/D96A Order",
"summary": "EDIFACT/D96A Order",
"version": "16.0.1.1.0",
"development_status": "Alpha",
"category": "Sales Management",
"website": "https://github.com/OCA/edi",
"author": "ALBA Software, Camptocamp, Odoo Community Association (OCA)",
"maintainers": ["rmorant"],
"license": "AGPL-3",
"depends": [
"sale_management",
"partner_identification_gln",
"base_edifact",
"sale_order_import",
],
"data": [
"wizard/sale_order_import_view.xml",
],
"demo": ["demo/demo_data.xml"],
}

View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="0">
<record id="partner_edi_dm" model="res.partner">
<field name="name">AMATEST EU SARL</field>
<field name="is_company" eval="True" />
<field name="customer_rank" eval="1" />
<field name="street">38 Avenue J.F. Kennedy</field>
<field name="zip">1234</field>
<field name="city">Luxembourg</field>
<field name="country_id" ref="base.lu" />
</record>
<record id="partner_edi_shipto_dm" model="res.partner">
<field name="name">AMATEST EU (TST)</field>
<field name="parent_id" ref="partner_edi_dm" />
<field name="street">80 Bojsdoeisn</field>
<field name="zip">4321</field>
<field name="city">Gliwice</field>
<field name="country_id" ref="base.pl" />
<field name="email" />
<field name="type">delivery</field>
</record>
<record id="partner_edi_invoiceto_dm" model="res.partner">
<field name="name">AMATEST Invoice</field>
<field name="parent_id" ref="partner_edi_dm" />
<field name="function">Accountant</field>
<field name="customer_rank" eval="1" />
<field name="type">invoice</field>
</record>
<record id="res_partner_id_number_edi" model="res.partner.id_number">
<field
name="category_id"
ref="partner_identification_gln.partner_identification_gln_number_category"
/>
<field name="partner_id" ref="partner_edi_dm" />
<field name="name">5450534000017</field>
</record>
<record id="res_partner_id_number_edi_shipto" model="res.partner.id_number">
<field
name="category_id"
ref="partner_identification_gln.partner_identification_gln_number_category"
/>
<field name="partner_id" ref="partner_edi_shipto_dm" />
<field name="name">5450534008617</field>
</record>
<record id="res_partner_id_number_edi_invoiceto" model="res.partner.id_number">
<field
name="category_id"
ref="partner_identification_gln.partner_identification_gln_number_category"
/>
<field name="partner_id" ref="partner_edi_invoiceto_dm" />
<field name="name">5450534008143</field>
</record>
<record id="product_product_edifact1_dm" model="product.product">
<field name="name">EDIFACT Demo 1</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">edifact1</field>
<field name="categ_id" ref="product.product_category_all" />
<field name="barcode">9783898307529</field>
</record>
<record id="product_product_edifact2_dm" model="product.product">
<field name="name">EDIFACT Demo 2</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">edifac2</field>
<field name="categ_id" ref="product.product_category_all" />
<field name="barcode">9783898307538</field>
</record>
<record id="product_product_edifact3_dm" model="product.product">
<field name="name">EDIFACT Demo 3</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">edifact</field>
<field name="categ_id" ref="product.product_category_all" />
<field name="barcode">9783898307645</field>
</record>
<record id="product_product_edifact4_dm" model="product.product">
<field name="name">Product1</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">1276</field>
<field name="categ_id" ref="product.product_category_all" />
</record>
<record id="product_product_edifact5_dm" model="product.product">
<field name="name">Product2</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">46630</field>
<field name="categ_id" ref="product.product_category_all" />
</record>
<record id="product_product_edifact6_dm" model="product.product">
<field name="name">Product3</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">98891 75</field>
<field name="categ_id" ref="product.product_category_all" />
</record>
<record id="product_product_edifact7_dm" model="product.product">
<field name="name">Product4</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">37230</field>
<field name="categ_id" ref="product.product_category_all" />
</record>
<record id="product_product_edifact8_dm" model="product.product">
<field name="name">Product5</field>
<field name="sale_ok" eval="True" />
<field name="type">consu</field>
<field name="default_code">1076</field>
<field name="categ_id" ref="product.product_category_all" />
</record>
</odoo>

View file

@ -0,0 +1,149 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_import_edifact
#
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_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/wizard/sale_order_import.py:0
#, python-format
msgid "%s document is not a Sale Order document"
msgstr "%s dokument nije dokument prodajnog naloga"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_business_document_import
msgid "Common methods to import business documents"
msgstr "Zajedničke metode za uvoz poslovnih dokumenata"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__doc_type
msgid "Document Type"
msgstr "Tip dokumenta"
#. module: sale_order_import_edifact
#: model:ir.model.fields.selection,name:sale_order_import_edifact.selection__sale_order_import__import_type__edifact
msgid "EDIFACT"
msgstr "EDIFACT"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact1_dm_product_template
msgid "EDIFACT Demo 1"
msgstr "EDIFACT Demo 1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact2_dm_product_template
msgid "EDIFACT Demo 2"
msgstr "EDIFACT Demo 2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact3_dm_product_template
msgid "EDIFACT Demo 3"
msgstr "EDIFACT Demo 3"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__edifact_ok
msgid "Edifact Ok"
msgstr "Edifact u redu"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__file_ext
msgid "File Ext"
msgstr "Ekstenzija datoteke"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Import Type"
msgstr "Tip uvoza"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid "Json Data Preview"
msgstr "Pregled JSON podataka"
#. module: sale_order_import_edifact
#: model_terms:ir.ui.view,arch_db:sale_order_import_edifact.sale_order_import_form
msgid "Parse"
msgstr "Parsiraj"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"Partner GLN Code: %(party)s not found in order file: '%(file)s' from VAT "
"registration number '%(vat)s'."
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact4_dm_product_template
msgid "Product1"
msgstr "Proizvod1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact5_dm_product_template
msgid "Product2"
msgstr "Proizvod2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact6_dm_product_template
msgid "Product3"
msgstr "Proizvod3"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact7_dm_product_template
msgid "Product4"
msgstr "Proizvod4"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact8_dm_product_template
msgid "Product5"
msgstr "Proizvod5"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__release
msgid "Release"
msgstr "Verzija"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_sale_order_import
msgid "Sale Order Import from Files"
msgstr "Uvoz prodajnog naloga iz datoteka"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.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_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid "Unknown"
msgstr "Nepoznat"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid ""
"Used by the btn `button_parse_order_preview` to preview data before "
"importing"
msgstr ""
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"partner_identification_gln module should be installed with a xmlid: "
"partner_identification_gln_number_category"
msgstr ""

View file

@ -0,0 +1,158 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_import_edifact
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-11-26 20:35+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/wizard/sale_order_import.py:0
#, python-format
msgid "%s document is not a Sale Order document"
msgstr "El documento %s no es un documento de Orden de Venta"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_business_document_import
msgid "Common methods to import business documents"
msgstr "Métodos habituales para importar documentos comerciales"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__doc_type
msgid "Document Type"
msgstr "Tipo de documento"
#. module: sale_order_import_edifact
#: model:ir.model.fields.selection,name:sale_order_import_edifact.selection__sale_order_import__import_type__edifact
msgid "EDIFACT"
msgstr "FACTUREDI"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact1_dm_product_template
msgid "EDIFACT Demo 1"
msgstr "EDIFACT Demo 1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact2_dm_product_template
msgid "EDIFACT Demo 2"
msgstr "EDIFACT Demo 2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact3_dm_product_template
msgid "EDIFACT Demo 3"
msgstr "EDIFACT Demo 3"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__edifact_ok
msgid "Edifact Ok"
msgstr "Edifact Ok"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__file_ext
msgid "File Ext"
msgstr "Archivo Ext"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Import Type"
msgstr "Tipo de Importación"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid "Json Data Preview"
msgstr "Vista Preliminar de Datos Json"
#. module: sale_order_import_edifact
#: model_terms:ir.ui.view,arch_db:sale_order_import_edifact.sale_order_import_form
msgid "Parse"
msgstr "Analice"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"Partner GLN Code: %(party)s not found in order file: '%(file)s' from VAT "
"registration number '%(vat)s'."
msgstr ""
"Código GLN de socio: %(party)s no se encuentra en el fichero de pedidos: "
"%(file)s' del número de registro de IVA '%(vat)s'."
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact4_dm_product_template
msgid "Product1"
msgstr "Producto1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact5_dm_product_template
msgid "Product2"
msgstr "Producto2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact6_dm_product_template
msgid "Product3"
msgstr "Producto3"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact7_dm_product_template
msgid "Product4"
msgstr "Producto4"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact8_dm_product_template
msgid "Product5"
msgstr "Producto5"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__release
msgid "Release"
msgstr "Liberar"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_sale_order_import
msgid "Sale Order Import from Files"
msgstr "Importación de Órdenes de Venta desde Archivos"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.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_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid "Unknown"
msgstr "Desconocido"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid ""
"Used by the btn `button_parse_order_preview` to preview data before "
"importing"
msgstr ""
"Utilizado por el btn `button_parse_order_preview` para previsualizar los "
"datos antes de importarlos"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"partner_identification_gln module should be installed with a xmlid: "
"partner_identification_gln_number_category"
msgstr ""
"El módulo partner_identification_gln debe instalarse con un xmlid: "
"partner_identification_gln_number_category"

View file

@ -0,0 +1,158 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_import_edifact
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-05-01 15:34+0000\n"
"Last-Translator: c2cdidier <didier.donze@camptocamp.com>\n"
"Language-Team: none\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/wizard/sale_order_import.py:0
#, python-format
msgid "%s document is not a Sale Order document"
msgstr "%s document n'est pas un bon de commande"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_business_document_import
msgid "Common methods to import business documents"
msgstr "Méthode générique pour l'importation de documents de type business"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__doc_type
msgid "Document Type"
msgstr "Type de document"
#. module: sale_order_import_edifact
#: model:ir.model.fields.selection,name:sale_order_import_edifact.selection__sale_order_import__import_type__edifact
msgid "EDIFACT"
msgstr "EDIFACT"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact1_dm_product_template
msgid "EDIFACT Demo 1"
msgstr "EDIFACT Demo 1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact2_dm_product_template
msgid "EDIFACT Demo 2"
msgstr "EDIFACT Démo 2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact3_dm_product_template
msgid "EDIFACT Demo 3"
msgstr "EDIFACT Démo 3"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__edifact_ok
msgid "Edifact Ok"
msgstr "OK Edifact"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__file_ext
msgid "File Ext"
msgstr "Extension de fichier"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Import Type"
msgstr "Type d'importation"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid "Json Data Preview"
msgstr "Prévisualisation données Json"
#. module: sale_order_import_edifact
#: model_terms:ir.ui.view,arch_db:sale_order_import_edifact.sale_order_import_form
msgid "Parse"
msgstr "Analyser"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"Partner GLN Code: %(party)s not found in order file: '%(file)s' from VAT "
"registration number '%(vat)s'."
msgstr ""
"Le numéro d'adhérent GLN: %(party)s n'a pas été trouvé dans le document de "
"commande: '%(file)s' à partir du numéro TVA '%(vat)s'."
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact4_dm_product_template
msgid "Product1"
msgstr "Article1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact5_dm_product_template
msgid "Product2"
msgstr "Article2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact6_dm_product_template
msgid "Product3"
msgstr "Article3"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact7_dm_product_template
msgid "Product4"
msgstr "Article4"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact8_dm_product_template
msgid "Product5"
msgstr "Article5"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__release
msgid "Release"
msgstr "Libérer"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_sale_order_import
msgid "Sale Order Import from Files"
msgstr "Importer la commande client à partir des fichiers"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Select a type which you want to import"
msgstr "Sélectionner le type d'importation souhaité"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid "Unknown"
msgstr "Inconnu"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid ""
"Used by the btn `button_parse_order_preview` to preview data before "
"importing"
msgstr ""
"Est utilisé par le bouton `button_parse_order_preview` afin de prévisualiser "
"avant d'importer les données"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"partner_identification_gln module should be installed with a xmlid: "
"partner_identification_gln_number_category"
msgstr ""
"le module partner_identification_gln module devrait être installé avec un "
"xmlid: partner_identification_gln_number_category"

View file

@ -0,0 +1,158 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_import_edifact
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-08-23 12:06+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.6.2\n"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/wizard/sale_order_import.py:0
#, python-format
msgid "%s document is not a Sale Order document"
msgstr "Il documento %s non è un documento ordine di vendita"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_business_document_import
msgid "Common methods to import business documents"
msgstr "Metodi comuni per l'importazione di documenti di lavoro"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__doc_type
msgid "Document Type"
msgstr "Tipo documento"
#. module: sale_order_import_edifact
#: model:ir.model.fields.selection,name:sale_order_import_edifact.selection__sale_order_import__import_type__edifact
msgid "EDIFACT"
msgstr "EDIFACT"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact1_dm_product_template
msgid "EDIFACT Demo 1"
msgstr "Demo 1 EDIFACT"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact2_dm_product_template
msgid "EDIFACT Demo 2"
msgstr "Demo 2 EDIFACT"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact3_dm_product_template
msgid "EDIFACT Demo 3"
msgstr "Demo 3 EDIFACT"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__edifact_ok
msgid "Edifact Ok"
msgstr "EDIFACT OK"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__file_ext
msgid "File Ext"
msgstr "Ext file"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Import Type"
msgstr "Tipo importazione"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid "Json Data Preview"
msgstr "Anteprima dati JSON"
#. module: sale_order_import_edifact
#: model_terms:ir.ui.view,arch_db:sale_order_import_edifact.sale_order_import_form
msgid "Parse"
msgstr "Analizza"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"Partner GLN Code: %(party)s not found in order file: '%(file)s' from VAT "
"registration number '%(vat)s'."
msgstr ""
"Codice partner GLN: %(party)s non trovato nel file ordine: '%(file)s' per "
"registrazione IVA numero '%(vat)s'."
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact4_dm_product_template
msgid "Product1"
msgstr "Prodotto1"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact5_dm_product_template
msgid "Product2"
msgstr "Prodotto2"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact6_dm_product_template
msgid "Product3"
msgstr "Prodotto3"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact7_dm_product_template
msgid "Product4"
msgstr "Prodotto4"
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact8_dm_product_template
msgid "Product5"
msgstr "Prodotto5"
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__release
msgid "Release"
msgstr "Rilascio"
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_sale_order_import
msgid "Sale Order Import from Files"
msgstr "Importazione ordine di vendita da file"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.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_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid "Unknown"
msgstr "Sconosciuto"
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid ""
"Used by the btn `button_parse_order_preview` to preview data before "
"importing"
msgstr ""
"Utilizzato dal pulsante `button_parse_order_preview` per anteprima data "
"prima dell'importazione"
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"partner_identification_gln module should be installed with a xmlid: "
"partner_identification_gln_number_category"
msgstr ""
"Il modulo partner_identification_gln deve essere installato con un xmlid: "
"partner_identification_gln_number_category"

View file

@ -0,0 +1,149 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_import_edifact
#
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_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/wizard/sale_order_import.py:0
#, python-format
msgid "%s document is not a Sale Order document"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_business_document_import
msgid "Common methods to import business documents"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__doc_type
msgid "Document Type"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields.selection,name:sale_order_import_edifact.selection__sale_order_import__import_type__edifact
msgid "EDIFACT"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact1_dm_product_template
msgid "EDIFACT Demo 1"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact2_dm_product_template
msgid "EDIFACT Demo 2"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact3_dm_product_template
msgid "EDIFACT Demo 3"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__edifact_ok
msgid "Edifact Ok"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__file_ext
msgid "File Ext"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Import Type"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid "Json Data Preview"
msgstr ""
#. module: sale_order_import_edifact
#: model_terms:ir.ui.view,arch_db:sale_order_import_edifact.sale_order_import_form
msgid "Parse"
msgstr ""
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"Partner GLN Code: %(party)s not found in order file: '%(file)s' from VAT "
"registration number '%(vat)s'."
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact4_dm_product_template
msgid "Product1"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact5_dm_product_template
msgid "Product2"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact6_dm_product_template
msgid "Product3"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact7_dm_product_template
msgid "Product4"
msgstr ""
#. module: sale_order_import_edifact
#: model:product.template,name:sale_order_import_edifact.product_product_edifact8_dm_product_template
msgid "Product5"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,field_description:sale_order_import_edifact.field_sale_order_import__release
msgid "Release"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model,name:sale_order_import_edifact.model_sale_order_import
msgid "Sale Order Import from Files"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__import_type
msgid "Select a type which you want to import"
msgstr ""
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid "Unknown"
msgstr ""
#. module: sale_order_import_edifact
#: model:ir.model.fields,help:sale_order_import_edifact.field_sale_order_import__json_data_preview
msgid ""
"Used by the btn `button_parse_order_preview` to preview data before "
"importing"
msgstr ""
#. module: sale_order_import_edifact
#. odoo-python
#: code:addons/sale_order_import_edifact/models/business_document_import.py:0
#, python-format
msgid ""
"partner_identification_gln module should be installed with a xmlid: "
"partner_identification_gln_number_category"
msgstr ""

View file

@ -0,0 +1 @@
from . import business_document_import

View file

@ -0,0 +1,57 @@
# Copyright 2019 PlanetaTIC - Marc Poch <mpoch@planetatic.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, exceptions, models
class BusinessDocumentImport(models.AbstractModel):
_inherit = "business.document.import"
# TODO: refactor code in partner_identification_import and drop this one
@api.model
def _hook_match_partner(self, partner_dict, chatter_msg, domain, order):
"""
2 types
partner_dict = {'gln':""}
partner_dict = {'partner': {'gln':""}, 'address':{'country_code':"ES",...}}
"""
partner = partner_dict.get("partner", partner_dict)
partner_dict.get("address", False)
if not partner.get("gln"):
return super()._hook_match_partner(partner_dict, chatter_msg, domain, order)
party_id = partner["gln"]
partner_id_category = self.env.ref(
"partner_identification_gln.partner_identification_gln_number_category"
)
if not partner_id_category:
raise exceptions.UserError(
_(
"partner_identification_gln module should be installed with a xmlid: "
"partner_identification_gln_number_category"
)
)
id_number = self.env["res.partner.id_number"].search(
[("category_id", "=", int(partner_id_category)), ("name", "=", party_id)],
limit=1,
)
if not id_number:
ctx = partner.get(
"edi_ctx", {"order_filename": _("Unknown"), "rff_va": _("Unknown")}
)
raise exceptions.UserError(
_(
"Partner GLN Code: %(party)s not found in order file: '%(file)s' "
"from VAT registration number '%(vat)s'.",
party=party_id,
file=ctx.get("order_filename"),
vat=ctx.get("rff_va"),
)
)
return id_number.partner_id
# @api.model
# def post_create_or_update(self, parsed_dict, record, doc_filename=None):
# if 'origin_exchange_record_id' in record.fields_get():
# record.origin_exchange_record_id =

View file

@ -0,0 +1,6 @@
This module struggles with EDIFACT format, if you need X12 format you will need something like sale_order_import_x12 module.
Regardless format, a concret document should need a concret specification nammed release. For example Amazon uses "D96A" specification.
See <https://www.stedi.com/edi/edifact>

View file

@ -0,0 +1,4 @@
* Rafa Morant <rmorant@albasoft.com> (https://www.albasoft.com)
* Marc Poch <mpoch@planetatic.com>
* Duong (Tran Quoc) <duongtq@trobz.com>
* Simone Orsi <simone.orsi@camptocamp.com>

View file

@ -0,0 +1 @@
The migration of this module from 14.0 to 16.0 was financially supported by Camptocamp

View file

@ -0,0 +1,6 @@
UN/EDIFACT
United Nations rules for Elec­tronic Data Interchange for Administration, Commerce and Transport
This module plugs EDIFACT/D96A ORDER in sale_order_import process.
https://www.stedi.com/edi/edifact/D96A/messages/ORDERS

View file

@ -0,0 +1,15 @@
.. The change log. The goal of this file is to help readers
understand changes between versions. The primary audience is
end users and integrators. Purely technical changes such as
code refactoring must not be mentioned here.
This file may contain ONE level of section titles, underlined
with the ~ (tilde) character. Other section markers are
forbidden and will likely break the structure of the README.rst
or other documents where this fragment is included.
14.0.1.0.0 (2023-06-07)
~~~~~~~~~~~~~~~~~~~~~~~
* [14.0][ADD] sale_order_import_edifact & base_edifact.
(`#779 <https://github.com/OCA/edi/pull/779>`_)

View file

@ -0,0 +1 @@
* Move the previews button feature to the base module

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

View file

@ -0,0 +1,479 @@
<!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>Import Business Document EDIFACT/D96A Order</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
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: grey; } /* 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 {
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" id="import-business-document-edifact-d96a-order">
<h1 class="title">Import Business Document EDIFACT/D96A Order</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:73a00474d97ec5b99974450168fa2e4e38572a70c95790882f1a5f2fe60d517a
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Alpha" src="https://img.shields.io/badge/maturity-Alpha-red.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/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/edi/tree/16.0/sale_order_import_edifact"><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_edifact"><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&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<dl class="docutils">
<dt>UN/EDIFACT</dt>
<dd>United Nations rules for Elec­tronic Data Interchange for Administration, Commerce and Transport</dd>
</dl>
<p>This module plugs EDIFACT/D96A ORDER in sale_order_import process.</p>
<p><a class="reference external" href="https://www.stedi.com/edi/edifact/D96A/messages/ORDERS">https://www.stedi.com/edi/edifact/D96A/messages/ORDERS</a></p>
<div class="admonition important">
<p class="first admonition-title">Important</p>
<p class="last">This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
<a class="reference external" href="https://odoo-community.org/page/development-status">More details on development status</a></p>
</div>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-2">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-3">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-4">14.0.1.0.0 (2023-06-07)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-5">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-6">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-7">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-8">Contributors</a></li>
<li><a class="reference internal" href="#other-credits" id="toc-entry-9">Other credits</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-10">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>This module struggles with EDIFACT format, if you need X12 format you will need something like sale_order_import_x12 module.</p>
<p>Regardless format, a concret document should need a concret specification nammed release. For example Amazon uses “D96A” specification.</p>
<p>See &lt;<a class="reference external" href="https://www.stedi.com/edi/edifact">https://www.stedi.com/edi/edifact</a>&gt;</p>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Move the previews button feature to the base module</li>
</ul>
</div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#toc-entry-3">Changelog</a></h1>
<!-- The change log. The goal of this file is to help readers
understand changes between versions. The primary audience is
end users and integrators. Purely technical changes such as
code refactoring must not be mentioned here.
This file may contain ONE level of section titles, underlined
with the ~ (tilde) character. Other section markers are
forbidden and will likely break the structure of the README.rst
or other documents where this fragment is included. -->
<div class="section" id="section-1">
<h2><a class="toc-backref" href="#toc-entry-4">14.0.1.0.0 (2023-06-07)</a></h2>
<ul class="simple">
<li>[14.0][ADD] sale_order_import_edifact &amp; base_edifact.
(<a class="reference external" href="https://github.com/OCA/edi/pull/779">#779</a>)</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-5">Bug Tracker</a></h1>
<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_edifact%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">
<h1><a class="toc-backref" href="#toc-entry-6">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-7">Authors</a></h2>
<ul class="simple">
<li>ALBA Software</li>
<li>Camptocamp</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-8">Contributors</a></h2>
<ul class="simple">
<li>Rafa Morant &lt;<a class="reference external" href="mailto:rmorant&#64;albasoft.com">rmorant&#64;albasoft.com</a>&gt; (<a class="reference external" href="https://www.albasoft.com">https://www.albasoft.com</a>)</li>
<li>Marc Poch &lt;<a class="reference external" href="mailto:mpoch&#64;planetatic.com">mpoch&#64;planetatic.com</a>&gt;</li>
<li>Duong (Tran Quoc) &lt;<a class="reference external" href="mailto:duongtq&#64;trobz.com">duongtq&#64;trobz.com</a>&gt;</li>
<li>Simone Orsi &lt;<a class="reference external" href="mailto:simone.orsi&#64;camptocamp.com">simone.orsi&#64;camptocamp.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="other-credits">
<h2><a class="toc-backref" href="#toc-entry-9">Other credits</a></h2>
<p>The migration of this module from 14.0 to 16.0 was financially supported by Camptocamp</p>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-10">Maintainers</a></h2>
<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>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/rmorant"><img alt="rmorant" src="https://github.com/rmorant.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/edi/tree/16.0/sale_order_import_edifact">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>
</body>
</html>

View file

@ -0,0 +1 @@
from . import test_edifact_order_import

View file

@ -0,0 +1,92 @@
# Copyright 2016 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).
from functools import partial
from odoo.tools import DotDict, file_open
def _get_file_content(filename):
path = "base_edifact/tests/files/" + filename
with file_open(path, "rb") as fd:
return fd.read()
def get_test_data(env):
ref = env.ref
return {
"Retail_EDIFACT_ORDERS_sample1.txt": DotDict(
{
"_get_content": partial(
_get_file_content, "Retail_EDIFACT_ORDERS_sample1.txt"
),
"client_order_ref": "1AA1TEST",
"date_order": "2023-06-06",
"partner": ref("sale_order_import_edifact.partner_edi_invoiceto_dm"),
"shipping_partner": ref(
"sale_order_import_edifact.partner_edi_shipto_dm"
),
# "invoicing_partner": ref(
# "sale_order_import_edifact.partner_edi_invoiceto_dm"
# ),
# "currency": ref("base.SEK"),
# "commitment_date": "",
"products": ref("sale_order_import_edifact.product_product_edifact1_dm")
+ ref("sale_order_import_edifact.product_product_edifact2_dm")
+ ref("sale_order_import_edifact.product_product_edifact3_dm"),
}
)
}
def get_test_data_no_ean_in_lin(env):
ref = env.ref
return {
"test_orders_-_no_ean_in_LIN_segments.txt": DotDict(
{
"_get_content": partial(
_get_file_content, "test_orders_-_no_ean_in_LIN_segments.txt"
),
"client_order_ref": "467819",
"date_order": "2023-03-20",
"commitment_date": "2023-03-22 00:00:00",
"partner": ref("sale_order_import_edifact.partner_edi_shipto_dm"),
"shipping_partner": ref(
"sale_order_import_edifact.partner_edi_shipto_dm"
),
"products": ref("sale_order_import_edifact.product_product_edifact4_dm")
+ ref("sale_order_import_edifact.product_product_edifact5_dm")
+ ref("sale_order_import_edifact.product_product_edifact6_dm")
+ ref("sale_order_import_edifact.product_product_edifact7_dm")
+ ref("sale_order_import_edifact.product_product_edifact8_dm"),
"qty": [12.0, 24.0, 12.0, 24.0, 90.0],
}
)
}
def get_test_data_no_price(env):
ref = env.ref
return {
"test_orders_-_no_PRI_segments.txt": DotDict(
{
"_get_content": partial(
_get_file_content, "test_orders_-_no_PRI_segments.txt"
),
"client_order_ref": "COM-004017",
"date_order": "2023-03-20",
"commitment_date": "2023-03-21 00:00:00",
"partner": ref("sale_order_import_edifact.partner_edi_invoiceto_dm"),
"shipping_partner": ref(
"sale_order_import_edifact.partner_edi_shipto_dm"
),
"products": ref("sale_order_import_edifact.product_product_edifact1_dm")
+ ref("sale_order_import_edifact.product_product_edifact2_dm")
+ ref("sale_order_import_edifact.product_product_edifact3_dm"),
"price": [1.0, 1.0, 1.0],
}
)
}

View file

@ -0,0 +1,115 @@
# Copyright 2023 ALBA Software S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)
import base64
from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger
from .common import get_test_data, get_test_data_no_ean_in_lin, get_test_data_no_price
class TestEdifactOrderImport(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
@mute_logger("odoo.addons.sale_order_import.wizard.sale_order_import")
def test_edifact_order_import(self):
tests = get_test_data(self.env)
for filename, expected in tests.items():
edifact_file = expected._get_content()
wiz = self.env["sale.order.import"].create(
{
"import_type": "edifact",
"order_file": base64.b64encode(edifact_file),
"order_filename": filename,
}
)
action = wiz.import_order_button()
so = self.env["sale.order"].browse(action["res_id"])
self.assertEqual(so.partner_id, expected["partner"])
if expected.get("client_order_ref"):
self.assertEqual(so.client_order_ref, expected["client_order_ref"])
if expected.get("shipping_partner"):
self.assertEqual(so.partner_shipping_id, expected["shipping_partner"])
if expected.get("invoicing_partner"):
self.assertEqual(so.partner_invoice_id, expected["invoicing_partner"])
if expected.get("products"):
expected_ids = sorted(expected["products"].ids)
self.assertEqual(
sorted(so.order_line.mapped("product_id").ids), expected_ids
)
@mute_logger("odoo.addons.sale_order_import.wizard.sale_order_import")
def test_edifact_order_import_no_ean_in_lin(self):
tests = get_test_data_no_ean_in_lin(self.env)
for filename, expected in tests.items():
edifact_file = expected._get_content()
wiz = self.env["sale.order.import"].create(
{
"import_type": "edifact",
"order_file": base64.b64encode(edifact_file),
"order_filename": filename,
}
)
action = wiz.import_order_button()
so = self.env["sale.order"].browse(action["res_id"])
self.assertEqual(so.partner_id, expected["partner"])
if expected.get("commitment_date"):
self.assertEqual(str(so.commitment_date), expected["commitment_date"])
if expected.get("client_order_ref"):
self.assertEqual(so.client_order_ref, expected["client_order_ref"])
if expected.get("shipping_partner"):
self.assertEqual(so.partner_shipping_id, expected["shipping_partner"])
if expected.get("products"):
expected_ids = sorted(expected["products"].ids)
self.assertEqual(
sorted(so.order_line.mapped("product_id").ids), expected_ids
)
self.assertEqual(
so.order_line.mapped("product_uom_qty"), expected["qty"]
)
self.assertEqual(
so.order_line.mapped("name")[0], "Product1 description"
)
@mute_logger("odoo.addons.sale_order_import.wizard.sale_order_import")
def test_edifact_order_import_no_price(self):
tests = get_test_data_no_price(self.env)
for filename, expected in tests.items():
edifact_file = expected._get_content()
wiz = self.env["sale.order.import"].create(
{
"import_type": "edifact",
"order_file": base64.b64encode(edifact_file),
"order_filename": filename,
}
)
action = wiz.import_order_button()
so = self.env["sale.order"].browse(action["res_id"])
self.assertEqual(so.partner_id, expected["partner"])
if expected.get("commitment_date"):
self.assertEqual(str(so.commitment_date), expected["commitment_date"])
if expected.get("client_order_ref"):
self.assertEqual(so.client_order_ref, expected["client_order_ref"])
if expected.get("shipping_partner"):
self.assertEqual(so.partner_shipping_id, expected["shipping_partner"])
if expected.get("products"):
expected_ids = sorted(expected["products"].ids)
self.assertEqual(
sorted(so.order_line.mapped("product_id").ids), expected_ids
)
self.assertEqual(so.order_line.mapped("price_unit"), expected["price"])

View file

@ -0,0 +1 @@
from . import sale_order_import

View file

@ -0,0 +1,276 @@
import json
import logging
import os
from base64 import b64decode
from collections import defaultdict
from odoo import _, api, fields, models
from odoo.exceptions import UserError
logger = logging.getLogger(__name__)
class SaleOrderImport(models.TransientModel):
_inherit = "sale.order.import"
import_type = fields.Selection(
selection_add=[("edifact", "EDIFACT")], ondelete={"edifact": "cascade"}
)
# Make doc_type field support for EDIFACT type
doc_type = fields.Selection(readonly=False)
# TODO: Move this feature to the base module or to an additional module.
json_data_preview = fields.Text(
help="Used by the btn `button_parse_order_preview` to preview data before importing"
)
edifact_ok = fields.Boolean(compute="_compute_edifact_ok")
# Techincal fields used to get the extension part of files
file_ext = fields.Char(default="txt,d96a")
# EDIFACT format release
release = fields.Char(default="d96a")
@api.depends("order_file", "order_filename")
def _compute_edifact_ok(self):
for rec in self:
if not (rec.order_file and rec.order_filename):
rec.edifact_ok = False
continue
extensions = rec.file_ext.split(",")
path, ext = os.path.splitext(self.order_filename)
ok = ext and ext[1:] in extensions
if not ok:
ok = b64decode(self.order_file[:4]) in (b"UNA", b"UNB")
rec.edifact_ok = ok
# TODO: Move this feature to the base module or to an additional module.
def button_parse_order_preview(self):
"""
Generate a preview of the data before importing.
This method is called by the button to take a quick look at the pydifact
structure ('edifact' type) and the parsed object ('order') from
the original document before importing the document.
"""
self.ensure_one()
edifact_model = self.env["base.edifact"]
order_file_decoded = b64decode(self.order_file)
parsed_obj = dict(edifact=None, order=None)
if self.edifact_ok:
parsed_obj["edifact"] = edifact_model.pydifact_obj(order_file_decoded)
parsed_order = self.parse_order(
order_file_decoded, self.order_filename, self.partner_id
)
del parsed_order["attachments"]
parsed_obj["order"] = parsed_order
self.write(
{
"json_data_preview": json.dumps(parsed_obj, indent=4, default=str),
}
)
action = self.env["ir.actions.act_window"]._for_xml_id(
"sale_order_import.sale_order_import_action"
)
action["res_id"] = self.id
return action
def _get_supported_types(self):
# Add more types for EDIFACT
res = super()._get_supported_types()
res.update({"edifact": ("text/plain", None)})
return res
@api.model
def parse_edifact_order(self, filecontent, detect_doc_type=False):
# https://github.com/nerdocs/pydifact/blob/master/pydifact/segmentcollection.py
if detect_doc_type:
if not self.edifact_ok:
return None
return self.env.context.get("default_doc_type", "rfq")
edifact_model = self.env["base.edifact"]
interchange = edifact_model._loads_edifact(filecontent)
header = interchange.get_header_segment()
# > UNB segment: [['UNOA', '2'], ['5450534000000', '14'],
# ['8435337000003', '14'], ['230306', '0435'], '5506']
msg_type, msg_type_release = edifact_model._get_msg_type(interchange)
supported = ["ORDERS"]
if msg_type not in supported:
raise UserError(_("%s document is not a Sale Order document"))
bgm = interchange.get_segment("BGM")
# Customer PO number
# BGM segment: ['220', '1LP6WZGF', '9']
order_ref = bgm[1]
rd = {
"doc_type": self.doc_type,
# Customer PO number
"order_ref": order_ref,
"edi_ctx": {"sender": header[1], "recipient": header[2]}, # header[1][0]
}
parties = self._prepare_edifact_parties(interchange)
order_dict = {
**rd,
**self._prepare_edifact_dates(interchange),
**self._prepare_edifact_currencies(interchange),
**parties,
}
lines = self._prepare_edifact_lines(interchange)
if lines:
order_dict["lines"] = lines
return order_dict
@api.model
def _prepare_edifact_parties(self, interchange):
references = self._prepare_edifact_references(interchange)
parties = self._prepare_edifact_name_and_address(interchange)
if references.get("vat") and parties.get("invoice_to"):
# just for check vat
if parties["invoice_to"].get("partner"):
parties["invoice_to"]["partner"]["rff_va"] = references["vat"]
if parties.get("invoice_to") and parties["invoice_to"].get("partner"):
newpartner = parties["invoice_to"]["partner"].copy()
if parties.get("partner") and parties["partner"].get("gln"):
# To see if NAD_BY is different NAD_IV
newpartner["gln_by"] = parties["partner"]["gln"]
parties["partner"] = newpartner
# add context information
for pval in parties.values():
partner_dict = pval.get("partner", pval)
partner_dict["edi_ctx"] = {
"order_filename": self.order_filename,
}
if references.get("vat"):
partner_dict["edi_ctx"]["rff_va"] = references["vat"]
if parties.get("company"):
parties["company"]["edi_ctx"]["vendor_code"] = references.get("vendor_code")
return parties
@api.model
def _prepare_edifact_dates(self, interchange):
dates = defaultdict(dict)
edifact_model = self.env["base.edifact"]
for seg in interchange.get_segments("DTM"):
date_meaning_code = seg[0][0]
if date_meaning_code == "137":
dates["date"] = edifact_model.map2odoo_date(seg[0])
elif date_meaning_code == "63":
# latest delivery date
# dates.setdefault("delivery_detail",{})
dates["delivery_detail"]["validity_date"] = edifact_model.map2odoo_date(
seg[0]
)
elif date_meaning_code == "2":
# Delivery date
dates["delivery_detail"][
"commitment_date"
] = edifact_model.map2odoo_date(seg[0])
return dates
@api.model
def _prepare_edifact_references(self, interchange):
"""
RFF segment: [['CR', 'IK142']]
"""
refs = {}
for seg in interchange.get_segments("RFF"):
reference = seg[0]
reference_code = reference[0]
if reference_code == "ADE":
# ['firstorder','backorder','advantage','nyp']
refs["account_reference"] = reference[1]
elif reference_code == "CR":
# Customer reference Number
refs["vendor_code"] = reference[1]
elif reference_code == "PD":
# Promotion Deal Number
# Number assigned by a vendor to a special promotion activity
refs["promotion_number"] = reference[1]
elif reference_code == "VA":
# Unique number assigned by the relevant tax authority to identify a
# party for use in relation to Value Added Tax (VAT).
refs["vat"] = reference[1]
return refs
@api.model
def _prepare_edifact_name_and_address(self, interchange):
nads = {}
edifact_model = self.env["base.edifact"]
for seg in interchange.get_segments("NAD"):
reference_code = seg[0]
if reference_code == "BY":
# NAD segment: ['BY', ['5450534001649', '', '9']]
# Customer (Buyer's GLN)
nads["partner"] = edifact_model.map2odoo_partner(seg)
elif reference_code == "SU":
# Our number of Supplier's GLN
# Can be used to check that we are not importing the order
# in the wrong company by mistake
nads["company"] = edifact_model.map2odoo_partner(seg)
elif reference_code == "DP":
# Delivery Party
nads["ship_to"] = edifact_model.map2odoo_address(seg)
elif reference_code == "IV":
# Invoice Party
nads["invoice_to"] = edifact_model.map2odoo_address(seg)
return nads
@api.model
def _prepare_edifact_currencies(self, interchange):
currencies = {}
edifact_model = self.env["base.edifact"]
for seg in interchange.get_segments("CUX"):
usage_code = seg[0]
if usage_code == "2":
currencies["currency"] = edifact_model.map2odoo_currency(seg)
return currencies
@api.model
def _prepare_edifact_lines(self, interchange):
edifact_model = self.env["base.edifact"]
lines = []
pia_list = []
qty_list = []
pri_list = []
imd_list = []
for i in interchange.get_segments("PIA"):
if i[1][1] == "SA":
pia_list.append(i)
for i in interchange.get_segments("QTY"):
if i[0][0] == "21":
qty_list.append(i)
for i in interchange.get_segments("PRI"):
pri_list.append(i)
for i in interchange.get_segments("IMD"):
if i[1] == "79":
imd_list.append(i)
for linseg in interchange.get_segments("LIN"):
piaseg = pia_list.pop(0) if pia_list else None
qtyseg = qty_list.pop(0) if qty_list else None
priseg = pri_list.pop(0) if pri_list else None
imdseg = imd_list.pop(0) if imd_list else None
line = {
"sequence": int(linseg[0]),
"product": edifact_model.map2odoo_product(linseg, piaseg),
"qty": edifact_model.map2odoo_qty(qtyseg),
}
price_unit = edifact_model.map2odoo_unit_price(priseg)
# If the product price is not provided, the price will be taken from the system
if price_unit != 0.0:
line["price_unit"] = price_unit
description = edifact_model.map2odoo_description(imdseg)
if description:
line["name"] = description
lines.append(line)
return lines

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="sale_order_import_form" model="ir.ui.view">
<field name="name">sale.order.import.form.dev</field>
<field name="model">sale.order.import</field>
<field name="inherit_id" ref="sale_order_import.sale_order_import_form" />
<field name="arch" type="xml">
<!-- Support doc_type for import_type = 'edifact' -->
<field name="doc_type" position="attributes">
<attribute
name="attrs"
>{'readonly': [('import_type','!=','edifact')]}</attribute>
</field>
<footer position="before">
<group
name="tech"
attrs="{'invisible':[('json_data_preview','=', False)]}"
>
<field name="json_data_preview" readonly="1" />
</group>
</footer>
<footer position="inside">
<button
name="button_parse_order_preview"
type="object"
string="Parse"
attrs="{'invisible': ['|', ('import_type','!=','edifact'), ('state','!=','import')]}"
groups="base.group_system,base.group_no_one"
/>
</footer>
</field>
</record>
</odoo>