|
1 | 1 | import logging |
2 | 2 |
|
3 | | -from openupgradelib import openupgrade_merge_records |
4 | | - |
5 | | -from odoo import SUPERUSER_ID, api |
6 | | - |
7 | 3 | logger = logging.getLogger(__name__) |
8 | 4 |
|
9 | 5 |
|
10 | | -def _cleanup_orphan_references(cr, model_table): |
11 | | - """Nullify references to activities that no longer exist after merging.""" |
12 | | - logger.info("Cleaning up orphan references to %s", model_table) |
13 | | - column = "l10n_ar_arca_activity_id" |
14 | | - for table in ["res_company", "account_account"]: |
15 | | - cr.execute( |
16 | | - f""" |
17 | | - UPDATE {table} |
18 | | - SET {column} = NULL |
19 | | - WHERE NOT EXISTS ( |
20 | | - SELECT 1 FROM {model_table} WHERE id = {table}.{column} |
21 | | - ) |
22 | | - """ |
23 | | - ) |
24 | | - if cr.rowcount: |
25 | | - logger.info( |
26 | | - "Cleaned %d orphan references in table '%s'", cr.rowcount, table |
27 | | - ) |
28 | | - |
29 | | - |
30 | 6 | def migrate(cr, version): |
31 | | - """Merge duplicate records in l10n_ar.arca.activity based on the 'code' field. |
32 | | -
|
33 | | - This handles the case where activities were user-created in the old model (afip.activity) |
34 | | - but are now created as data in the new model (l10n_ar.arca.activity), which can lead |
35 | | - to duplicates after migration. |
| 7 | + """Update references to use new activity records based on code matching. |
| 8 | + After the module loads new l10n_ar.arca.activity records, we update the foreign keys |
| 9 | + in account_account and res_company to point to these new records based on matching codes. |
36 | 10 | """ |
37 | | - model_name = "l10n_ar.arca.activity" |
38 | | - model_table = "l10n_ar_arca_activity" |
| 11 | + new_table = "l10n_ar_arca_activity" |
| 12 | + backup_table = "afip_activity_bu" |
| 13 | + new_field = "l10n_ar_arca_activity_id" |
| 14 | + backup_field = "l10n_ar_afip_activity_id_bu" |
39 | 15 |
|
40 | | - # Find duplicate codes |
| 16 | + # Update account_account references |
| 17 | + logger.info("Updating %s references in account_account", new_field) |
41 | 18 | cr.execute( |
42 | 19 | f""" |
43 | | - SELECT code, array_agg(id ORDER BY id) as ids |
44 | | - FROM {model_table} |
45 | | - WHERE code IS NOT NULL |
46 | | - GROUP BY code |
47 | | - HAVING COUNT(*) > 1 |
| 20 | + UPDATE account_account |
| 21 | + SET {new_field} = ( |
| 22 | + SELECT new_act.id |
| 23 | + FROM {new_table} new_act |
| 24 | + JOIN {backup_table} old_act ON new_act.code = old_act.code |
| 25 | + WHERE old_act.id = account_account.{backup_field} |
| 26 | + ) |
| 27 | + WHERE {backup_field} IS NOT NULL |
48 | 28 | """ |
49 | 29 | ) |
| 30 | + logger.info("Updated %d records in account_account", cr.rowcount) |
50 | 31 |
|
51 | | - duplicates = cr.fetchall() |
52 | | - if not duplicates: |
53 | | - logger.info("No duplicate activities found based on 'code' field") |
54 | | - return |
55 | | - |
56 | | - logger.info("Found %s groups of duplicate activities to merge", len(duplicates)) |
57 | | - env = api.Environment(cr, SUPERUSER_ID, {}) |
58 | | - |
59 | | - for code, record_ids in duplicates: |
60 | | - if len(record_ids) < 2: |
61 | | - continue |
62 | | - |
63 | | - # Use the last record (highest ID) as target, which is the original user-created record |
64 | | - # The lower IDs are typically the new data records that were loaded |
65 | | - target_record_id = record_ids[-1] |
66 | | - records_to_merge = record_ids[:-1] |
67 | | - |
68 | | - logger.info( |
69 | | - "Merging duplicate activities with code '%s': merging %s into %s", |
70 | | - code, |
71 | | - records_to_merge, |
72 | | - target_record_id, |
| 32 | + # Update res_company references |
| 33 | + logger.info("Updating %s references in res_company", new_field) |
| 34 | + cr.execute( |
| 35 | + f""" |
| 36 | + UPDATE res_company |
| 37 | + SET {new_field} = ( |
| 38 | + SELECT new_act.id |
| 39 | + FROM {new_table} new_act |
| 40 | + JOIN {backup_table} old_act ON new_act.code = old_act.code |
| 41 | + WHERE old_act.id = res_company.{backup_field} |
73 | 42 | ) |
| 43 | + WHERE {backup_field} IS NOT NULL |
| 44 | + """ |
| 45 | + ) |
| 46 | + logger.info("Updated %d records in res_company", cr.rowcount) |
74 | 47 |
|
75 | | - try: |
76 | | - openupgrade_merge_records.merge_records( |
77 | | - env=env, |
78 | | - model_name=model_name, |
79 | | - record_ids=records_to_merge, |
80 | | - target_record_id=target_record_id, |
81 | | - method="sql", |
82 | | - delete=True, |
83 | | - model_table=model_table, |
| 48 | + # Clean up orphan references (activities that don't have a matching code in new data) |
| 49 | + logger.info("Cleaning up orphan references") |
| 50 | + for table in ["account_account", "res_company"]: |
| 51 | + cr.execute( |
| 52 | + f""" |
| 53 | + UPDATE {table} |
| 54 | + SET {new_field} = NULL |
| 55 | + WHERE {new_field} IS NOT NULL |
| 56 | + AND NOT EXISTS ( |
| 57 | + SELECT 1 FROM {new_table} WHERE id = {table}.{new_field} |
84 | 58 | ) |
| 59 | + """ |
| 60 | + ) |
| 61 | + if cr.rowcount: |
85 | 62 | logger.info( |
86 | | - "Successfully merged %s duplicate records into record %s", |
87 | | - len(records_to_merge), |
88 | | - target_record_id, |
89 | | - ) |
90 | | - except Exception as e: |
91 | | - logger.error( |
92 | | - "Error merging duplicate activities with code '%s': %s", code, str(e) |
| 63 | + "Cleaned %d orphan references in table '%s'", cr.rowcount, table |
93 | 64 | ) |
94 | | - # Continue with next group even if one fails |
95 | | - continue |
96 | 65 |
|
97 | | - # Clean up any references that might have been broken after the merge |
98 | | - _cleanup_orphan_references(cr, model_table) |
| 66 | + # Drop backup table and columns |
| 67 | + logger.info("Dropping backup table %s", backup_table) |
| 68 | + cr.execute(f"DROP TABLE IF EXISTS {backup_table}") |
| 69 | + |
| 70 | + for table in ["account_account", "res_company"]: |
| 71 | + logger.info("Dropping backup column %s from %s", backup_field, table) |
| 72 | + cr.execute(f"ALTER TABLE {table} DROP COLUMN IF EXISTS {backup_field}") |
| 73 | + |
| 74 | + logger.info("Post-migration completed successfully") |
0 commit comments