Skip to content

Commit 5a16763

Browse files
committed
[ADD] edi_purchase_edifact_oca
1 parent de571bc commit 5a16763

28 files changed

+2134
-0
lines changed

edi_purchase_edifact_oca/README.rst

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
========================
2+
EDI PURCHASE EDIFACT OCA
3+
========================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:d2e2602bb615321d18583caff366876c642564652bdfcd412395f69355aa8d72
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Alpha
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fedi-lightgray.png?logo=github
20+
:target: https://github.com/OCA/edi/tree/12.0/edi_purchase_edifact_oca
21+
:alt: OCA/edi
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/edi-12-0/edi-12-0-edi_purchase_edifact_oca
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/edi&target_branch=12.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
UN/EDIFACT
32+
United Nations rules for Elec­tronic Data Interchange for Administration, Commerce and Transport
33+
34+
This module will support exporting and confirming orders in EDIFACT format.
35+
36+
https://www.stedi.com/edi/edifact/D01B/messages/ORDERS
37+
https://www.stedi.com/edi/edifact/D96A/messages/ORDERS
38+
https://www.stedi.com/edi/edifact/D01B/messages/DESADV
39+
https://www.stedi.com/edi/edifact/D96A/messages/DESADV
40+
41+
.. IMPORTANT::
42+
This is an alpha version, the data model and design can change at any time without warning.
43+
Only for development or testing purpose, do not use in production.
44+
`More details on development status <https://odoo-community.org/page/development-status>`_
45+
46+
**Table of contents**
47+
48+
.. contents::
49+
:local:
50+
51+
Bug Tracker
52+
===========
53+
54+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/edi/issues>`_.
55+
In case of trouble, please check there if your issue has already been reported.
56+
If you spotted it first, help us to smash it by providing a detailed and welcomed
57+
`feedback <https://github.com/OCA/edi/issues/new?body=module:%20edi_purchase_edifact_oca%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
58+
59+
Do not contact contributors directly about support or help with technical issues.
60+
61+
Credits
62+
=======
63+
64+
Authors
65+
~~~~~~~
66+
67+
* Trobz
68+
69+
Contributors
70+
~~~~~~~~~~~~
71+
72+
* Thien (Vo Hong) <thienvh@trobz.com>
73+
74+
Other credits
75+
~~~~~~~~~~~~~
76+
77+
The development of this module has been financially supported by:
78+
79+
* Trobz
80+
81+
Maintainers
82+
~~~~~~~~~~~
83+
84+
This module is maintained by the OCA.
85+
86+
.. image:: https://odoo-community.org/logo.png
87+
:alt: Odoo Community Association
88+
:target: https://odoo-community.org
89+
90+
OCA, or the Odoo Community Association, is a nonprofit organization whose
91+
mission is to support the collaborative development of Odoo features and
92+
promote its widespread use.
93+
94+
This module is part of the `OCA/edi <https://github.com/OCA/edi/tree/12.0/edi_purchase_edifact_oca>`_ project on GitHub.
95+
96+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

edi_purchase_edifact_oca/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import models
2+
from . import components
3+
from . import wizard
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2024 Trobz
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)
3+
{
4+
"name": "EDI PURCHASE EDIFACT OCA",
5+
"summary": "Create and send EDIFACT order files",
6+
"version": "12.0.1.0.0",
7+
"development_status": "Alpha",
8+
"website": "https://github.com/OCA/edi",
9+
"author": "Trobz, Odoo Community Association (OCA)",
10+
"license": "AGPL-3",
11+
"application": False,
12+
"installable": True,
13+
"depends": [
14+
"base_edifact",
15+
"stock",
16+
"edi_storage_oca",
17+
"edi_purchase_oca",
18+
"partner_identification_gln",
19+
"base_business_document_import",
20+
],
21+
"data": [
22+
"security/ir.model.access.csv",
23+
"views/purchase.xml",
24+
"views/res_partner.xml",
25+
"data/edi_backend.xml",
26+
"data/edi_exchange_type.xml",
27+
"wizard/purchase_order_import_view.xml",
28+
],
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import listener_edifact_output
2+
from . import generate_edifact_output
3+
from . import process_edifact_input
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2024 Trobz
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo.addons.component.core import Component
5+
6+
7+
class EDIExchangeEDIFACTOutGenerate(Component):
8+
_name = "edi.output.edifact.out.generate"
9+
_inherit = "edi.component.output.mixin"
10+
_usage = "output.generate.edifact"
11+
12+
def generate(self):
13+
data = False
14+
exchange_record = self.exchange_record
15+
16+
if exchange_record:
17+
if exchange_record.model == "purchase.order" and exchange_record.res_id:
18+
order = self.env["purchase.order"].browse(exchange_record.res_id)
19+
if order:
20+
data = order.edifact_purchase_generate_data(exchange_record)
21+
return data
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2024 Trobz
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
import logging
5+
6+
from odoo.addons.component.core import Component
7+
8+
_logger = logging.getLogger(__name__)
9+
10+
11+
class PurchaseOrderEdifactListener(Component):
12+
_name = "purchase.order.event.listener.edifact"
13+
_inherit = "base.event.listener"
14+
_apply_on = ["purchase.order"]
15+
16+
def on_button_confirm_purchase_order(self, order):
17+
if not self._should_create_exchange_record(order):
18+
return None
19+
exchange_type = self.env.ref(
20+
"edi_purchase_edifact_oca.edi_exchange_type_purchase_order_out"
21+
)
22+
record = exchange_type.backend_id.create_record(
23+
exchange_type.code, self._storage_new_exchange_record_vals()
24+
)
25+
# Set related record
26+
record._set_related_record(order)
27+
_logger.info(
28+
"Exchange record for purchase order %s was created: %s",
29+
order.name,
30+
record.identifier,
31+
)
32+
33+
def _should_create_exchange_record(self, order):
34+
if self.env.context.get("skip_send_edifact", False):
35+
return False
36+
37+
partner = order.partner_id
38+
return (partner and partner.edifact_purchase_order_out)
39+
40+
def _storage_new_exchange_record_vals(self):
41+
return {"edi_exchange_state": "new"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright 2024 Trobz
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
import base64
5+
import json
6+
from odoo.addons.component.core import Component
7+
8+
9+
class EDIExchangeEDIFACTInput(Component):
10+
11+
_name = "edi.input.process.edifact.input"
12+
_inherit = "edi.component.input.mixin"
13+
_usage = "input.process.edifact.input"
14+
15+
def process(self):
16+
"""Process incoming EDIFACT record and confirm record."""
17+
file_content = self.exchange_record._get_file_content()
18+
wizard = self.env["purchase.order.import"].create(
19+
{
20+
"import_type": "edifact",
21+
"order_file": base64.b64encode(file_content.encode()),
22+
"order_filename": self.exchange_record.exchange_filename,
23+
}
24+
)
25+
file_name = self.exchange_record.exchange_filename
26+
action = wizard.import_order_button()
27+
if action and action.get("res_model", False):
28+
self.exchange_record.update(
29+
{
30+
"model": action["res_model"],
31+
"res_id": action["res_id"],
32+
}
33+
)
34+
self.exchange_record.exchange_filename = file_name
35+
36+
return self._create_expected_reception_message(action)
37+
38+
def _create_expected_reception_message(self, action):
39+
message = """
40+
\nDone quantities were updated on {} lines out of the {} Reception lines
41+
""".format(
42+
action.get("number_line_updated", 0), action.get("reception_lines", 0)
43+
)
44+
45+
unknown_products = action.get("unknown_products", False)
46+
if unknown_products:
47+
message += "\nUnknow Product: \n"
48+
message += " * " + "\n * ".join(
49+
json.dumps(rec, indent=4) for rec in unknown_products
50+
)
51+
qty_diff = action.get("qty_diff", False)
52+
if qty_diff:
53+
message += "\nDifference of Qty: \n"
54+
message += " * " + "\n * ".join(
55+
json.dumps(rec, indent=4) for rec in qty_diff
56+
)
57+
return message
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo>
3+
<record id="edi_backend_type_edifact" model="edi.backend.type">
4+
<field name="name">EDIFACT</field>
5+
<field name="code">edifact</field>
6+
</record>
7+
<record id="edi_backend_edifact" model="edi.backend">
8+
<field name="name">EDIFACT</field>
9+
<field name="backend_type_id" ref="edi_backend_type_edifact" />
10+
</record>
11+
</odoo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<odoo noupdate="0">
3+
<record id="edi_exchange_type_purchase_order_out" model="edi.exchange.type">
4+
<field name="backend_id" ref="edi_backend_edifact" />
5+
<field name="backend_type_id" ref="edi_backend_type_edifact" />
6+
<field name="name">EDIFACT-OUT-ORDER</field>
7+
<field name="code">edifact_out_order</field>
8+
<field name="direction">output</field>
9+
<field name="exchange_filename_pattern">D{dt}</field>
10+
<field name="exchange_file_ext">txt</field>
11+
<field name="exchange_file_auto_generate">True</field>
12+
<field name="encoding">iso-8859-1</field>
13+
<field name="encoding_out_error_handler">strict</field>
14+
<field name="encoding_in_error_handler">strict</field>
15+
<field name="quick_exec" eval="True" />
16+
<field name="advanced_settings_edit">
17+
components:
18+
generate:
19+
usage: output.generate.edifact
20+
env_ctx:
21+
msg_type: Picking
22+
filename_pattern:
23+
force_tz: Europe/Zurich
24+
date_pattern: "%Y%m%d%H%M%S%f"
25+
</field>
26+
</record>
27+
28+
<record id="edi_exchange_type_purchase_order_input" model="edi.exchange.type">
29+
<field name="backend_id" ref="edi_backend_edifact" />
30+
<field name="backend_type_id" ref="edi_backend_type_edifact" />
31+
<field name="name">EDIFACT-IN-DESPATCH-ADVICE</field>
32+
<field name="code">edifact_in_despatch_advice</field>
33+
<field name="exchange_filename_pattern">output.*</field>
34+
<field name="exchange_file_ext">edi</field>
35+
<field name="direction">input</field>
36+
<field name="quick_exec" eval="True" />
37+
<field name="exchange_file_auto_generate">True</field>
38+
<field name="encoding">iso-8859-1</field>
39+
<field name="encoding_out_error_handler">strict</field>
40+
<field name="encoding_in_error_handler">strict</field>
41+
<field name="advanced_settings_edit">
42+
components:
43+
process:
44+
usage: input.process.edifact.input
45+
env_ctx:
46+
msg_type: "EDIFACT Input"
47+
</field>
48+
</record>
49+
</odoo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from . import purchase
2+
from . import res_partner
3+
from . import business_document_import
4+
from . import edi_exchange_record
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright 2024 Trobz
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo import _, api, exceptions, models
5+
6+
7+
class BusinessDocumentImport(models.AbstractModel):
8+
_inherit = "business.document.import"
9+
10+
@api.model
11+
def _hook_match_partner(self, partner_dict, chatter_msg, domain, order):
12+
"""
13+
2 types
14+
partner_dict = {'gln':""}
15+
partner_dict = {'partner': {'gln':""}, 'address':{'country_code':"ES",...}}
16+
"""
17+
partner = partner_dict.get("partner", partner_dict)
18+
partner_dict.get("address", False)
19+
if not partner.get("gln"):
20+
return super()._hook_match_partner(partner_dict, chatter_msg, domain, order)
21+
party_id = partner["gln"]
22+
23+
partner_id_category = self.env.ref(
24+
"partner_identification_gln.partner_identification_gln_number_category"
25+
)
26+
if not partner_id_category:
27+
raise exceptions.UserError(
28+
_(
29+
"partner_identification_gln module"
30+
" should be installed with a xmlid: "
31+
"partner_identification_gln_number_category"
32+
)
33+
)
34+
id_number = self.env["res.partner.id_number"].search(
35+
[("category_id", "=", int(partner_id_category)), ("name", "=", party_id)],
36+
limit=1,
37+
)
38+
if not id_number:
39+
ctx = partner.get(
40+
"edi_ctx", {"order_filename": _("Unknown"), "rff_va": _("Unknown")}
41+
)
42+
raise exceptions.UserError(
43+
_("Partner GLN Code: {party} not found in order file: '{file}' "
44+
"from VAT registration number '{vat}'.").format(
45+
party=party_id,
46+
file=ctx.get("order_filename"),
47+
vat=ctx.get("rff_va"),
48+
)
49+
)
50+
51+
return id_number.partner_id
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright 2024 Trobz
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo import models
5+
from odoo.addons.edi_oca.models.edi_exchange_record import EDIExchangeRecord
6+
7+
8+
class EDIExchangeRecord(models.Model):
9+
_inherit = "edi.exchange.record"
10+
11+
_rollback_state_mapping = {
12+
**EDIExchangeRecord._rollback_state_mapping,
13+
"input_processed": "input_received",
14+
}

0 commit comments

Comments
 (0)