Skip to content
Open
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
55 changes: 55 additions & 0 deletions data_migration/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
==============
Data Migration
==============

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

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-qrtl%2Fsst--custom-lightgray.png?logo=github
:target: https://github.com/qrtl/sst-custom/tree/15.0/data_migration
:alt: qrtl/sst-custom

|badge1| |badge2| |badge3|

This module reads the data from another odoo instance and create in current odoo instance.

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `GitHub Issues <https://github.com/qrtl/sst-custom/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/qrtl/sst-custom/issues/new?body=module:%20data_migration%0Aversion:%2015.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
~~~~~~~

* Quartile Limited

Maintainers
~~~~~~~~~~~

This module is part of the `qrtl/sst-custom <https://github.com/qrtl/sst-custom/tree/15.0/data_migration>`_ project on GitHub.

You are welcome to contribute.
1 change: 1 addition & 0 deletions data_migration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
17 changes: 17 additions & 0 deletions data_migration/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2023 Quartile Limited
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Data Migration",
"version": "15.0.1.0.0",
"category": "Tools",
"author": "Quartile Limited",
"website": "https://www.quartile.co",
"license": "AGPL-3",
"depends": ["base", "queue_job"],
"data": [
"security/ir.model.access.csv",
"data/data_migration_scheduler.xml",
"views/odoo_instance_views.xml",
],
"installable": True,
}
14 changes: 14 additions & 0 deletions data_migration/data/data_migration_scheduler.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding='UTF-8' ?>
<odoo noupdate="1">
<record model="ir.cron" id="ir_cron_partner_data_migration">
<field name="name">Partner Data Migration from another odoo instance</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="state">code</field>
<field name="code">model._run_partner_data_migration()</field>
<field name="doall" eval="False" />
<field name="active" eval="False" />
<field name="model_id" ref="model_partner_data_migration" />
</record>
</odoo>
5 changes: 5 additions & 0 deletions data_migration/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import data_migration
from . import data_migration_mapping
from . import odoo_instance
from . import partner_data_migration
from . import res_partner
25 changes: 25 additions & 0 deletions data_migration/models/data_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2023 Quartile Limited
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

import xmlrpc.client

from odoo import models


class DataMigration(models.AbstractModel):
_name = "data.migration"
_description = "Data Migration"

def _data_migration_authentication(self):
instance = self.env["odoo.instance"].search([])
# Authenticate for v11
common_v11 = xmlrpc.client.ServerProxy(
"{}/xmlrpc/2/common".format(instance.instance_url)
)
uid_v11 = common_v11.authenticate(
instance.instance_db, instance.login, instance.password, {}
)
models_v11 = xmlrpc.client.ServerProxy(
"{}/xmlrpc/2/object".format(instance.instance_url)
)
return instance, uid_v11, models_v11
29 changes: 29 additions & 0 deletions data_migration/models/data_migration_mapping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 Quartile Limited
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import models


class DataMigrationMapping(models.AbstractModel):
_name = "data.migration.mapping"

def map_many2one_field_by_name(self, env, model_name, field_value):
"""
Return the ID of a record in the specified model based on its name.

:param env: Odoo environment.
:param model_name: The name of the model (e.g., 'res.partner').
:param field_value: Tuple containing the ID and name of the record in the old system.
:return: ID of the record in the new system with the same name.
"""

if not isinstance(field_value, (tuple, list)):
return field_value

old_id, name = field_value
if model_name == "res.partner":
record = env[model_name].search([("old_id", "=", old_id),('active', 'in', [True, False])], limit=1)
else:
record = env[model_name].search([("name", "=", name)], limit=1)

return record.id if record else False
15 changes: 15 additions & 0 deletions data_migration/models/odoo_instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2023 Quartile Limited
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class OdooInstance(models.Model):
_name = "odoo.instance"
_description = "Odoo Instances"

name = fields.Char(required=True)
instance_url = fields.Char(required=True)
instance_db = fields.Char(required=True)
login = fields.Char(required=True)
password = fields.Char(required=True)
132 changes: 132 additions & 0 deletions data_migration/models/partner_data_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Copyright 2023 Quartile Limited
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import SUPERUSER_ID, api, models


class PartnerDataMigration(models.Model):
_name = "partner.data.migration"
_inherit = ["data.migration", "data.migration.mapping"]
_description = "Partner Data Migration"

def _run_partner_data_migration(self):
required_fields = [
"is_invoice_issuer",
"team_id",
"identification_type_id",
"occupation_id",
"website_published",
"date_of_birth",
"company_id",
"date",
"title",
"parent_id",
# "user_id", # user migration will handle it.
"active",
"customer",
"supplier",
"employee",
"state_id",
"country_id",
"is_company",
# "commercial_partner_id", # compute function will handle it.
"name",
"display_name",
"lang",
"tz",
"vat",
"website",
"comment",
"return_policy",
"invoice_warn",
"invoice_warn_msg",
"picking_warn",
"function",
"type",
"street",
"street2",
"zip",
"city",
"picking_warn_msg",
"sale_warn",
"email",
"phone",
"mobile",
"sale_warn_msg",
"shipping_policy",
"purchase_warn",
"purchase_warn_msg",
"profile_msg",
"identification_number",
"company_name",
"fax",
"gender",
]
instance, uid_v11, models_v11 = self._data_migration_authentication()
offset = 0
limit = 1000
while True:
partners_v11 = models_v11.execute_kw(
instance.instance_db,
uid_v11,
instance.password,
"res.partner",
"search_read",
[[('active', 'in', [True, False])]],
{"fields": required_fields, "offset": offset, "limit": limit},
)
if not partners_v11:
break
top_level_partners = [
partner for partner in partners_v11 if not partner.get("parent_id")
]
child_partners = [
partner for partner in partners_v11 if partner.get("parent_id")
]
offset += limit

for partner in top_level_partners:
self.with_delay()._process_partner_migration(partner, is_child=False)

for partner in child_partners:
self.with_delay()._process_partner_migration(partner, is_child=True)

def _process_partner_migration(self, partner, is_child=False):
env = api.Environment(self.env.cr, SUPERUSER_ID, {})
many2one_field_mapping = {
"team_id": "crm.team",
"identification_type_id": "identification.type",
"occupation_id": "res.occupation",
"company_id": "res.company",
"state_id": "res.country.state",
"country_id": "res.country",
"title": "res.partner.title",
}

if partner.pop("customer", False):
partner["customer_rank"] = 1
if partner.pop("supplier", False):
partner["supplier_rank"] = 1
date_of_birth = partner.pop("date_of_birth", False)
if date_of_birth:
partner["date_birth"] = date_of_birth

for field, model in many2one_field_mapping.items():
if field in partner:
partner[field] = self.map_many2one_field_by_name(
env, model, partner[field]
)
for field, value in list(partner.items()):
if (not is_child or field != "parent_id") and (
isinstance(value, tuple) or isinstance(value, list)
):
partner.pop(field, None)

if is_child and partner.get("parent_id"):
parent_id = env["res.partner"].search(
[("old_id", "=", partner["parent_id"][0])]
)
partner["parent_id"] = parent_id.id

partner["old_id"] = partner["id"]
env["res.partner"].create(partner)
10 changes: 10 additions & 0 deletions data_migration/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright 2023 Quartile Limited
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ResPartner(models.Model):
_inherit = "res.partner"

old_id = fields.Integer()
1 change: 1 addition & 0 deletions data_migration/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module reads the data from another odoo instance and create in current odoo instance.
5 changes: 5 additions & 0 deletions data_migration/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_odoo_instance,odoo.instance,model_odoo_instance,base.group_system,1,1,1,1
access_data_migration,data.migration,model_data_migration,base.group_system,1,1,1,1
access_data_migration_mapping,data.migration.mapping,model_data_migration_mapping,base.group_system,1,1,1,1
access_partner_data_migration,partner.data.migration,model_partner_data_migration,base.group_system,1,1,1,1
Loading