From 5c0bf0a0a0530d3f6e4f749b9264cc605da2f124 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 9 Aug 2024 03:18:10 +0000 Subject: [PATCH 1/4] [ADD] purchase_order_migration --- purchase_order_migration/README.rst | 56 +++ purchase_order_migration/__init__.py | 1 + purchase_order_migration/__manifest__.py | 16 + .../data/purchase_migration_scheduler.xml | 16 + purchase_order_migration/models/__init__.py | 2 + .../models/purchase_order.py | 10 + .../models/purchase_order_migration.py | 187 ++++++++ .../readme/DESCRIPTION.md | 2 + .../security/ir.model.access.csv | 2 + .../static/description/index.html | 410 ++++++++++++++++++ .../odoo/addons/purchase_order_migration | 1 + setup/purchase_order_migration/setup.py | 6 + 12 files changed, 709 insertions(+) create mode 100644 purchase_order_migration/README.rst create mode 100644 purchase_order_migration/__init__.py create mode 100644 purchase_order_migration/__manifest__.py create mode 100644 purchase_order_migration/data/purchase_migration_scheduler.xml create mode 100644 purchase_order_migration/models/__init__.py create mode 100644 purchase_order_migration/models/purchase_order.py create mode 100644 purchase_order_migration/models/purchase_order_migration.py create mode 100644 purchase_order_migration/readme/DESCRIPTION.md create mode 100644 purchase_order_migration/security/ir.model.access.csv create mode 100644 purchase_order_migration/static/description/index.html create mode 120000 setup/purchase_order_migration/odoo/addons/purchase_order_migration create mode 100644 setup/purchase_order_migration/setup.py diff --git a/purchase_order_migration/README.rst b/purchase_order_migration/README.rst new file mode 100644 index 00000000..53797149 --- /dev/null +++ b/purchase_order_migration/README.rst @@ -0,0 +1,56 @@ +============================= +Purchase Order Data Migration +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7840f2f9a0e7fa562cf685887cceb707340acc123a2d6adf5df63e0f9b6d5d0b + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Frmm--custom-lightgray.png?logo=github + :target: https://github.com/qrtl/rmm-custom/tree/15.0/purchase_order_migration + :alt: qrtl/rmm-custom + +|badge1| |badge2| |badge3| + +This module allows you to migrate old data from the old system to the +current environment. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Quartile Limited + +Maintainers +----------- + +This module is part of the `qrtl/rmm-custom `_ project on GitHub. + +You are welcome to contribute. diff --git a/purchase_order_migration/__init__.py b/purchase_order_migration/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/purchase_order_migration/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/purchase_order_migration/__manifest__.py b/purchase_order_migration/__manifest__.py new file mode 100644 index 00000000..3a71d05f --- /dev/null +++ b/purchase_order_migration/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2024 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Purchase Order Data Migration", + "version": "15.0.1.0.0", + "category": "Tools", + "author": "Quartile Limited", + "website": "https://www.quartile.co", + "license": "AGPL-3", + "depends": ["purchase", "data_migration"], + "data": [ + "security/ir.model.access.csv", + "data/purchase_migration_scheduler.xml", + ], + "installable": True, +} diff --git a/purchase_order_migration/data/purchase_migration_scheduler.xml b/purchase_order_migration/data/purchase_migration_scheduler.xml new file mode 100644 index 00000000..068c9873 --- /dev/null +++ b/purchase_order_migration/data/purchase_migration_scheduler.xml @@ -0,0 +1,16 @@ + + + + Purchase Order Data Migration from another odoo instance + 1 + days + -1 + code + model._run_purchase_order_data_migration() + + + + + diff --git a/purchase_order_migration/models/__init__.py b/purchase_order_migration/models/__init__.py new file mode 100644 index 00000000..6d130de0 --- /dev/null +++ b/purchase_order_migration/models/__init__.py @@ -0,0 +1,2 @@ +from . import purchase_order +from . import purchase_order_migration diff --git a/purchase_order_migration/models/purchase_order.py b/purchase_order_migration/models/purchase_order.py new file mode 100644 index 00000000..c923ce85 --- /dev/null +++ b/purchase_order_migration/models/purchase_order.py @@ -0,0 +1,10 @@ +# Copyright 2024 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + old_id = fields.Integer() diff --git a/purchase_order_migration/models/purchase_order_migration.py b/purchase_order_migration/models/purchase_order_migration.py new file mode 100644 index 00000000..007df863 --- /dev/null +++ b/purchase_order_migration/models/purchase_order_migration.py @@ -0,0 +1,187 @@ +# Copyright 2023 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import SUPERUSER_ID, api, models + + +class PurchaseOrderMigration(models.Model): + _name = "purchase.order.migration" + _inherit = ["data.migration", "data.migration.mapping"] + _description = "Purchase Order Data Migration" + + def get_or_create_dummy_product(self): + env = api.Environment(self.env.cr, SUPERUSER_ID, {}) + # Check if the dummy product already exists + dummy_product = env["product.product"].search( + [("default_code", "=", "DUMMY_PRODUCT")], limit=1 + ) + if dummy_product: + return dummy_product.id + else: + # If the dummy product does not exist, create it + dummy_product = env["product.product"].create( + { + "name": "Dummy Product", + "type": "product", + "default_code": "DUMMY_PRODUCT", + "taxes_id": False, # Assuming no taxes, adjust if necessary + } + ) + return dummy_product.id + + def _run_purchase_order_data_migration(self): + required_fields = [ + "id", + "name", + "origin", + "partner_ref", + "date_order", + "date_approve", + "partner_id", + "dest_address_id", + "currency_id", + "state", + "notes", + "date_planned", + "amount_untaxed", + "amount_tax", + "amount_total", + "fiscal_position_id", + "payment_term_id", + "incoterm_id", + "company_id", + "address", + "remark", + "picking_type_id", + "sale_prediction_amount", + "request_channel_id", + "request_medium_id", + "call_back", + "state_id", + "city", + "street", + "street2", + "zip", + "phone_update", + "phone_search", + "supplier_phone", + "supplier_mobile", + "purchase_category_id", + "employee_id", + "shop_id", + "purchase_by_id", + "allow_convert", + # 'sale_order_id', # To check need to migrate or not + ] + instance, uid_v11, models_v11 = self._data_migration_authentication() + offset = 0 + limit = 1000 + while True: + purchase_order_v11 = models_v11.execute_kw( + instance.instance_db, + uid_v11, + instance.password, + "purchase.order", + "search_read", + [], + {"fields": required_fields, "offset": offset, "limit": limit}, + ) + if not purchase_order_v11: + break + offset += limit + + for purchase in purchase_order_v11: + self.with_delay()._process_purchase_order_migration(purchase) + + def _process_purchase_order_migration(self, purchase): + env = api.Environment(self.env.cr, SUPERUSER_ID, {}) + many2one_field_mapping = { + "incoterm_id": "account.incoterms", + "fiscal_position_id": "account.fiscal.position", + "company_id": "res.company", + "payment_term_id": "account.payment.term", + "currency_id": "res.currency", + "dest_address_id": "res.partner", + "partner_id": "res.partner", + "request_channel_id": "request.channel", + "request_medium_id": "request.medium", + "purchase_category_id": "purchase.category", + "employee_id": "hr.employee", + "shop_id": "stock.warehouse", + "purchase_by_id": "hr.employee", + "state_id": "res.country.state", + "sale_order_id": "sale.order", + "picking_type_id": "stock.picking.type", + } + description = purchase["picking_type_id"][1].split(": ") + purchase["picking_type_id"][1] = description[1] + for field, model in many2one_field_mapping.items(): + if field in purchase: + purchase[field] = self.map_many2one_field_by_name( + env, model, purchase[field] + ) + state = purchase["state"] + purchase["state"] = False + purchase["old_id"] = purchase["id"] + order = env["purchase.order"].create(purchase) + self.create_purchase_order_line(order) + order.write( + { + "amount_tax": purchase["amount_tax"], + "amount_untaxed": purchase["amount_untaxed"], + "amount_total": purchase["amount_total"], + "state": state, + } + ) + + def create_purchase_order_line(self, order): + required_fields = [ + "account_analytic_id", + "analytic_tag_ids", + "company_id", + "date_planned", + "name", + "price_subtotal", + "price_tax", + "price_total", + "price_unit", + "product_qty", + "product_uom", + "qty_invoiced", + "qty_received", + "taxes_id", + ] + + instance, uid_v11, models_v11 = self._data_migration_authentication() + purchase_order_line_v11 = models_v11.execute_kw( + instance.instance_db, + uid_v11, + instance.password, + "purchase.order.line", + "search_read", + [], + {"fields": required_fields, "domain": [("order_id", "=", order.old_id)]}, + ) + for line in purchase_order_line_v11: + env = api.Environment(self.env.cr, SUPERUSER_ID, {}) + many2one_field_mapping = { + "account_analytic_id": "account.analytic.account", + "analytic_tag_ids": "account.analytic.tag", + "company_id": "res.company", + "product_uom": "uom.uom", + } + dummy_product_id = self.get_or_create_dummy_product() + line["product_id"] = dummy_product_id + for field, model in many2one_field_mapping.items(): + if field in line and line[field]: + line[field] = self.map_many2one_field_by_name( + env, model, line[field] + ) + for field, value in list(line.items()): + if isinstance(value, tuple) or isinstance(value, list): + line.pop(field, None) + + line["order_id"] = order.id + order_line = env["purchase.order.line"].create(line) + order_line.taxes_id = False + order_line.write({"price_tax": line["price_tax"]}) diff --git a/purchase_order_migration/readme/DESCRIPTION.md b/purchase_order_migration/readme/DESCRIPTION.md new file mode 100644 index 00000000..d9079681 --- /dev/null +++ b/purchase_order_migration/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module allows you to migrate old data from the old system to the +current environment. diff --git a/purchase_order_migration/security/ir.model.access.csv b/purchase_order_migration/security/ir.model.access.csv new file mode 100644 index 00000000..80810bfb --- /dev/null +++ b/purchase_order_migration/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_purchase_order_migration,purchase.order.migration,model_purchase_order_migration,base.group_system,1,1,1,1 diff --git a/purchase_order_migration/static/description/index.html b/purchase_order_migration/static/description/index.html new file mode 100644 index 00000000..7f99f287 --- /dev/null +++ b/purchase_order_migration/static/description/index.html @@ -0,0 +1,410 @@ + + + + + + +Purchase Order Data Migration + + + +
+

Purchase Order Data Migration

+ + +

Beta License: AGPL-3 qrtl/rmm-custom

+

This module allows you to migrate old data from the old system to the +current environment.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Quartile Limited
  • +
+
+
+

Maintainers

+

This module is part of the qrtl/rmm-custom project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/setup/purchase_order_migration/odoo/addons/purchase_order_migration b/setup/purchase_order_migration/odoo/addons/purchase_order_migration new file mode 120000 index 00000000..2c545ad2 --- /dev/null +++ b/setup/purchase_order_migration/odoo/addons/purchase_order_migration @@ -0,0 +1 @@ +../../../../purchase_order_migration \ No newline at end of file diff --git a/setup/purchase_order_migration/setup.py b/setup/purchase_order_migration/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/purchase_order_migration/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From ef98fb0130edf99043b9ccb045c0d5eba2a6f5ce Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Tue, 13 Aug 2024 10:49:49 +0000 Subject: [PATCH 2/4] adj --- purchase_order_migration/__manifest__.py | 2 +- purchase_order_migration/models/__init__.py | 1 - purchase_order_migration/models/purchase_order.py | 10 ---------- 3 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 purchase_order_migration/models/purchase_order.py diff --git a/purchase_order_migration/__manifest__.py b/purchase_order_migration/__manifest__.py index 3a71d05f..f1fca273 100644 --- a/purchase_order_migration/__manifest__.py +++ b/purchase_order_migration/__manifest__.py @@ -7,7 +7,7 @@ "author": "Quartile Limited", "website": "https://www.quartile.co", "license": "AGPL-3", - "depends": ["purchase", "data_migration"], + "depends": ["purchase_order_old_record", "data_migration"], "data": [ "security/ir.model.access.csv", "data/purchase_migration_scheduler.xml", diff --git a/purchase_order_migration/models/__init__.py b/purchase_order_migration/models/__init__.py index 6d130de0..89fa6f96 100644 --- a/purchase_order_migration/models/__init__.py +++ b/purchase_order_migration/models/__init__.py @@ -1,2 +1 @@ -from . import purchase_order from . import purchase_order_migration diff --git a/purchase_order_migration/models/purchase_order.py b/purchase_order_migration/models/purchase_order.py deleted file mode 100644 index c923ce85..00000000 --- a/purchase_order_migration/models/purchase_order.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright 2024 Quartile Limited -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo import fields, models - - -class PurchaseOrder(models.Model): - _inherit = "purchase.order" - - old_id = fields.Integer() From 0a183402ff540ca9486191763da8a22d1510ab08 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 16 Aug 2024 09:37:10 +0000 Subject: [PATCH 3/4] adj --- purchase_order_migration/__manifest__.py | 2 +- .../models/purchase_order_migration.py | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/purchase_order_migration/__manifest__.py b/purchase_order_migration/__manifest__.py index f1fca273..81e2a34c 100644 --- a/purchase_order_migration/__manifest__.py +++ b/purchase_order_migration/__manifest__.py @@ -7,7 +7,7 @@ "author": "Quartile Limited", "website": "https://www.quartile.co", "license": "AGPL-3", - "depends": ["purchase_order_old_record", "data_migration"], + "depends": ["purchase_order_old_id", "data_migration"], "data": [ "security/ir.model.access.csv", "data/purchase_migration_scheduler.xml", diff --git a/purchase_order_migration/models/purchase_order_migration.py b/purchase_order_migration/models/purchase_order_migration.py index 007df863..bcb632b2 100644 --- a/purchase_order_migration/models/purchase_order_migration.py +++ b/purchase_order_migration/models/purchase_order_migration.py @@ -124,7 +124,7 @@ def _process_purchase_order_migration(self, purchase): purchase["state"] = False purchase["old_id"] = purchase["id"] order = env["purchase.order"].create(purchase) - self.create_purchase_order_line(order) + self.create_purchase_order_line(order, state) order.write( { "amount_tax": purchase["amount_tax"], @@ -134,8 +134,9 @@ def _process_purchase_order_migration(self, purchase): } ) - def create_purchase_order_line(self, order): + def create_purchase_order_line(self, order, state): required_fields = [ + "product_id", "account_analytic_id", "analytic_tag_ids", "company_id", @@ -171,7 +172,15 @@ def create_purchase_order_line(self, order): "product_uom": "uom.uom", } dummy_product_id = self.get_or_create_dummy_product() - line["product_id"] = dummy_product_id + if state == "draft": + product_id = self.map_many2one_field_by_name( + env, "product.product", line["product_id"] + ) + line["product_id"] = dummy_product_id + if product_id: + line["product_id"] = product_id + else: + line["product_id"] = dummy_product_id for field, model in many2one_field_mapping.items(): if field in line and line[field]: line[field] = self.map_many2one_field_by_name( From 10f831c816e84f70d8b91a79952885c4066a9b25 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Tue, 27 Aug 2024 10:20:05 +0000 Subject: [PATCH 4/4] adj --- purchase_order_migration/models/purchase_order_migration.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/purchase_order_migration/models/purchase_order_migration.py b/purchase_order_migration/models/purchase_order_migration.py index bcb632b2..8176d9e7 100644 --- a/purchase_order_migration/models/purchase_order_migration.py +++ b/purchase_order_migration/models/purchase_order_migration.py @@ -71,6 +71,7 @@ def _run_purchase_order_data_migration(self): "shop_id", "purchase_by_id", "allow_convert", + "invoice_status", # 'sale_order_id', # To check need to migrate or not ] instance, uid_v11, models_v11 = self._data_migration_authentication() @@ -133,6 +134,7 @@ def _process_purchase_order_migration(self, purchase): "state": state, } ) + order.invoice_status = purchase["invoice_status"] def create_purchase_order_line(self, order, state): required_fields = [