Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions import_processor/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

================
Import Processor
================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:118ec811b0d4cc99553b35e5fc3c561e8753f5488439d41a8cfdc16e51718f55
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
:target: https://github.com/OCA/server-tools/tree/19.0/import_processor
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-tools-19-0/server-tools-19-0-import_processor
: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/server-tools&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This modules offers users additional imports of JSON, CSV, XLSX and XML
files based on configurable code snippets. This allows import of data
from structured data without installation of modules.

**Table of contents**

.. contents::
:local:

Usage
=====

To use this module, the administrator can create different processors in
Settings > Technical > Import Processors. It offers 3 different kind of
snippets depending on the import stage:

1. Pre-Processor: This snippet is executed once after loading the file.
This snippet is useful to set global variables or set configurations
prior to the import of each entry
2. Processor: This snippet is executed on single entries or chunks of
entries depending on the configuration.
3. Post-Processor: This snippet is executed after the entries are
processed and can be used to clean up things in the database or log
the processed data.

After configuration every user can use the processors Favorites > Import
Processor on the specified models.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/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/server-tools/issues/new?body=module:%20import_processor%0Aversion:%2019.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
-------

* initOS GmbH

Contributors
------------

- Dhara Solanki <dhara.solanki@initos.com>
- Florian Kantelberg <florian.kantelberg@initos.com>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

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

This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/19.0/import_processor>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
4 changes: 4 additions & 0 deletions import_processor/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# © 2022 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models, wizards
36 changes: 36 additions & 0 deletions import_processor/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# © 2022 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Import Processor",
"summary": "Generic import processor",
"license": "AGPL-3",
"version": "19.0.1.0.0",
"website": "https://github.com/OCA/server-tools",
"application": True,
"author": "initOS GmbH, Odoo Community Association (OCA)",
"category": "Tools",
"depends": [
"base",
"web",
],
"external_dependencies": {
"python": [
"jsonpath_ng",
],
},
"data": [
"security/ir.model.access.csv",
"views/import_processor_views.xml",
"wizards/import_processor_wizard_views.xml",
],
"demo": [
"data/processor_data.xml",
],
"assets": {
"web.assets_backend": [
"import_processor/static/src/*.js",
"import_processor/static/src/*.xml",
],
},
}
100 changes: 100 additions & 0 deletions import_processor/data/processor_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="demo_import_processor_csv" model="import.processor">
<field name="name">Import Res Partner (CSV with chunk size)</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="active" eval="1" />
<field name="file_type">csv</field>
<field name="chunk_size">2</field>
<field name="preprocessor">
regex = r"^[a-z0-9]+[\._]?[a-z0-9]+[@][a-zA-Z]+[.][a-zA-Z]{2,3}$"
fields_list = ["name", "email", "phone", "street", "street2", "zip", "city"]
</field>
<field name="processor">
for contact in entry:
email = contact.get("email")
if re.search(regex, email):
data = {key: value for key, value in contact.items() if key in fields_list}
rec = model.search([("email", "=", email)])
if rec:
rec.update(data)
else:
rec = model.create(data)

records |= rec
</field>
<field name="postprocessor">
log("Processed the following records: %s", records)
</field>
</record>

<record id="demo_import_processor_xml" model="import.processor">
<field name="name">Import Res Partner (XML)</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="active" eval="1" />
<field name="file_type">xml</field>
<field name="xml_path_entry">//Customer</field>
<field name="preprocessor">
# Regex Email Validation
regex = r"^[a-z0-9]+[\._]?[a-z0-9]+[@][a-zA-Z]+[.][a-zA-Z]{2,3}$"

fields_list = ["name", "email", "phone", "street", "street2", "zip", "city"]

# Converts XML file to Dictionary
def xml_to_dict(xml_element):
result = {}
for child in xml_element:
if len(child) == 0:
result[child.tag] = child.text
else:
result[child.tag] = xml_to_dict(child)
return result
</field>
<field name="processor">
entry = xml_to_dict(entry)

email = entry.get("email")
if re.search(regex, email):
rec = model.search([("email", "=", email)])
data = {key: value for key, value in entry.items() if key in fields_list}
if rec:
rec.update(data)
else:
rec = model.create(data)

records |= rec
</field>
<field name="postprocessor">
log("Processed the following records: %s", records)
</field>
</record>

<record id="demo_import_processor_json" model="import.processor">
<field name="name">Import Res Partner (JSON)</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="active" eval="1" />
<field name="file_type">json</field>
<field name="json_path_entry">'contact'</field>
<field name="preprocessor">
# Regex Email Validation
regex = r"^[a-z0-9]+[\._]?[a-z0-9]+[@][a-zA-Z]+[.][a-zA-Z]{2,3}$"
fields_list = ["name", "email", "phone", "street", "street2", "zip", "city"]
</field>
<field name="processor">
for contact in entry:
email = contact.get("email")
if re.search(regex, email):
rec = model.search([("email", "=", email)])
data = {key: value for key, value in contact.items() if key in fields_list}
if rec:
rec.update(data)
else:
rec = model.create(data)

records |= rec
</field>
<field name="postprocessor">
log("Processed the following records: %s", records)
</field>
</record>
</odoo>
4 changes: 4 additions & 0 deletions import_processor/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# © 2022 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import import_processor
Loading