|
| 1 | +# Copyright 2023 Quartile Limited |
| 2 | +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). |
| 3 | + |
| 4 | +from odoo import SUPERUSER_ID, api, models |
| 5 | + |
| 6 | + |
| 7 | +class PurchaseOrderMigration(models.Model): |
| 8 | + _name = "purchase.order.migration" |
| 9 | + _inherit = ["data.migration", "data.migration.mapping"] |
| 10 | + _description = "Purchase Order Data Migration" |
| 11 | + |
| 12 | + def _run_purchase_order_data_migration(self): |
| 13 | + required_fields = [ |
| 14 | + "id", |
| 15 | + "origin", |
| 16 | + "partner_ref", |
| 17 | + "date_order", |
| 18 | + "date_approve", |
| 19 | + "partner_id", |
| 20 | + "dest_address_id", |
| 21 | + "currency_id", |
| 22 | + "state", |
| 23 | + "notes", |
| 24 | + "date_planned", |
| 25 | + "amount_untaxed", |
| 26 | + "amount_tax", |
| 27 | + "amount_total", |
| 28 | + "fiscal_position_id", |
| 29 | + "payment_term_id", |
| 30 | + "incoterm_id", |
| 31 | + "company_id", |
| 32 | + "address", |
| 33 | + "remark", |
| 34 | + "sale_prediction_amount", |
| 35 | + "request_channel_id", |
| 36 | + "request_medium_id", |
| 37 | + "call_back", |
| 38 | + "state_id", |
| 39 | + "city", |
| 40 | + "street", |
| 41 | + "street2", |
| 42 | + "zip", |
| 43 | + "phone_update", |
| 44 | + "phone_search", |
| 45 | + "supplier_phone", |
| 46 | + "supplier_mobile", |
| 47 | + "tentative_name", |
| 48 | + "purchase_category_id", |
| 49 | + "employee_id", |
| 50 | + "shop_id", |
| 51 | + "purchase_by_id", |
| 52 | + "allow_convert", |
| 53 | + # 'sale_order_id', # To check need to migrate or not |
| 54 | + ] |
| 55 | + instance, uid_v11, models_v11 = self._data_migration_authentication() |
| 56 | + offset = 0 |
| 57 | + limit = 1000 |
| 58 | + while True: |
| 59 | + purchase_order_v11 = models_v11.execute_kw( |
| 60 | + instance.instance_db, |
| 61 | + uid_v11, |
| 62 | + instance.password, |
| 63 | + "purchase.order", |
| 64 | + "search_read", |
| 65 | + [], |
| 66 | + {"fields": required_fields, "offset": offset, "limit": limit}, |
| 67 | + ) |
| 68 | + if not purchase_order_v11: |
| 69 | + break |
| 70 | + offset += limit |
| 71 | + |
| 72 | + for purchase in purchase_order_v11: |
| 73 | + self.with_delay()._process_purchase_order_migration(purchase) |
| 74 | + |
| 75 | + def _process_purchase_order_migration(self, purchase): |
| 76 | + env = api.Environment(self.env.cr, SUPERUSER_ID, {}) |
| 77 | + many2one_field_mapping = { |
| 78 | + "incoterm_id": "account.incoterms", |
| 79 | + "fiscal_position_id": "account.fiscal.position", |
| 80 | + "company_id": "res.company", |
| 81 | + "payment_term_id": "account.payment.term", |
| 82 | + "currency_id": "res.currency", |
| 83 | + "dest_address_id": "res.partner", |
| 84 | + "partner_id": "res.partner", |
| 85 | + "request_channel_id": "request.channel", |
| 86 | + "request_medium_id": "request.medium", |
| 87 | + "purchase_category_id": "purchase.category", |
| 88 | + "employee_id": "hr.employee", |
| 89 | + "shop_id": "stock.warehouse", |
| 90 | + "purchase_by_id": "hr.employee", |
| 91 | + "state_id": "res.country.state", |
| 92 | + # 'sale_order_id': 'sale.order', |
| 93 | + } |
| 94 | + for field, model in many2one_field_mapping.items(): |
| 95 | + if field in purchase: |
| 96 | + purchase[field] = self.map_many2one_field_by_name( |
| 97 | + env, model, purchase[field] |
| 98 | + ) |
| 99 | + |
| 100 | + purchase["old_id"] = purchase["id"] |
| 101 | + order = env["purchase.order"].create(purchase) |
| 102 | + self.create_purchase_order_line(order) |
| 103 | + order.write( |
| 104 | + { |
| 105 | + "amount_tax": purchase["amount_tax"], |
| 106 | + "amount_untaxed": purchase["amount_untaxed"], |
| 107 | + "amount_total": purchase["amount_total"], |
| 108 | + } |
| 109 | + ) |
| 110 | + |
| 111 | + def create_purchase_order_line(self, order): |
| 112 | + required_fields = [ |
| 113 | + "account_analytic_id", |
| 114 | + "analytic_tag_ids", |
| 115 | + "company_id", |
| 116 | + "date_planned", |
| 117 | + "name", |
| 118 | + "price_subtotal", |
| 119 | + "price_tax", |
| 120 | + "price_total", |
| 121 | + "price_unit", |
| 122 | + "product_id", |
| 123 | + "product_qty", |
| 124 | + "product_uom", |
| 125 | + "qty_invoiced", |
| 126 | + "qty_received", |
| 127 | + "taxes_id", |
| 128 | + ] |
| 129 | + |
| 130 | + instance, uid_v11, models_v11 = self._data_migration_authentication() |
| 131 | + purchase_order_line_v11 = models_v11.execute_kw( |
| 132 | + instance.instance_db, |
| 133 | + uid_v11, |
| 134 | + instance.password, |
| 135 | + "purchase.order.line", |
| 136 | + "search_read", |
| 137 | + [], |
| 138 | + {"fields": required_fields, "domain": [("order_id", "=", order.old_id)]}, |
| 139 | + ) |
| 140 | + for line in purchase_order_line_v11: |
| 141 | + env = api.Environment(self.env.cr, SUPERUSER_ID, {}) |
| 142 | + many2one_field_mapping = { |
| 143 | + "account_analytic_id": "account.analytic.account", |
| 144 | + "analytic_tag_ids": "account.analytic.tag", |
| 145 | + "company_id": "res.company", |
| 146 | + "product_id": "product.product", |
| 147 | + "product_uom": "uom.uom", |
| 148 | + } |
| 149 | + product_id_info = line["product_id"] |
| 150 | + if product_id_info and len(product_id_info) == 2: |
| 151 | + if "] " in product_id_info[1]: |
| 152 | + # Case: [ID, '[CODE] Name'] |
| 153 | + product_name = product_id_info[1].split("] ")[1] |
| 154 | + else: |
| 155 | + # Case: [ID, 'Name'] |
| 156 | + product_name = product_id_info[1] |
| 157 | + |
| 158 | + line["product_id"] = [product_id_info[0], product_name] |
| 159 | + for field, model in many2one_field_mapping.items(): |
| 160 | + if field in line and line[field]: |
| 161 | + line[field] = self.map_many2one_field_by_name( |
| 162 | + env, model, line[field] |
| 163 | + ) |
| 164 | + for field, value in list(line.items()): |
| 165 | + if isinstance(value, tuple) or isinstance(value, list): |
| 166 | + line.pop(field, None) |
| 167 | + |
| 168 | + line["order_id"] = order.id |
| 169 | + order_line = env["purchase.order.line"].create(line) |
| 170 | + order_line.taxes_id = False |
| 171 | + order_line.write({"price_tax": line["price_tax"]}) |
0 commit comments