diff --git a/invoice_az/invoice_az/doctype/e_taxes_settings/e_taxes_settings.js b/invoice_az/invoice_az/doctype/e_taxes_settings/e_taxes_settings.js index 62691b5..eda8522 100644 --- a/invoice_az/invoice_az/doctype/e_taxes_settings/e_taxes_settings.js +++ b/invoice_az/invoice_az/doctype/e_taxes_settings/e_taxes_settings.js @@ -12,6 +12,31 @@ frappe.ui.form.on('E-Taxes Settings', { }, refresh: function(frm) { + frm.add_custom_button(__('Restore from old data'), function() { + frappe.confirm( + __('This will restore all settings and mappings from the pre-migration database record. Continue?'), + function() { + frappe.call({ + method: 'invoice_az.migrate_utils.restore_etaxes_settings_from_old_table', + freeze: true, + freeze_message: __('Restoring...'), + callback: function(r) { + if (r.message && r.message.success) { + frappe.show_alert({ message: __(r.message.message), indicator: 'green' }, 5); + frm.reload_doc(); + } else { + frappe.msgprint({ + title: __('Restore Failed'), + indicator: 'red', + message: r.message ? r.message.message : __('Unknown error') + }); + } + } + }); + } + ); + }, __('Data Loading')); + // Main Load All Data button frm.add_custom_button(__('Load All Data'), function() { show_load_all_data_dialog(frm); diff --git a/invoice_az/migrate_utils.py b/invoice_az/migrate_utils.py index a0cf997..0b37a62 100644 --- a/invoice_az/migrate_utils.py +++ b/invoice_az/migrate_utils.py @@ -24,6 +24,93 @@ CHILD_TABLES = [ ] +@frappe.whitelist() +def restore_etaxes_settings_from_old_table(): + """ + Called from the E-Taxes Settings form button. + Reads data from the old tabE-Taxes Settings (still exists after migration) + and populates the current Single doctype. + """ + if not frappe.db.table_exists("tabE-Taxes Settings"): + return {"success": False, "message": "Old table not found"} + + # Get the old record + old_row = None + for query in [ + "SELECT * FROM `tabE-Taxes Settings` WHERE name != 'E-Taxes Settings' LIMIT 1", + "SELECT * FROM `tabE-Taxes Settings` LIMIT 1", + ]: + try: + rows = frappe.db.sql(query, as_dict=True) + if rows: + old_row = rows[0] + break + except Exception: + pass + + if not old_row: + return {"success": False, "message": "No old settings record found in database"} + + old_name = old_row.get("name") + + # Write scalar fields to tabSingles + for field in SCALAR_FIELDS: + value = old_row.get(field) + if value is None: + continue + frappe.db.sql( + """ + INSERT INTO `tabSingles` (doctype, field, value) + VALUES ('E-Taxes Settings', %s, %s) + ON DUPLICATE KEY UPDATE value = VALUES(value) + """, + (field, str(value)), + ) + + # Restore child table rows + restored_children = {} + for table in CHILD_TABLES: + if not frappe.db.table_exists(table): + continue + try: + child_rows = frappe.db.sql( + f"SELECT * FROM `{table}` WHERE parent = %s ORDER BY idx", + (old_name,), + as_dict=True, + ) + except Exception: + continue + + if not child_rows: + continue + + frappe.db.sql(f"DELETE FROM `{table}` WHERE parent = 'E-Taxes Settings'") + + for row in child_rows: + row["parent"] = "E-Taxes Settings" + row["parenttype"] = "E-Taxes Settings" + columns = ", ".join(f"`{col}`" for col in row) + placeholders = ", ".join(["%s"] * len(row)) + try: + frappe.db.sql( + f"INSERT INTO `{table}` ({columns}) VALUES ({placeholders})", + list(row.values()), + ) + except Exception: + pass + + restored_children[table] = len(child_rows) + + frappe.db.commit() + frappe.clear_cache(doctype="E-Taxes Settings") + + return { + "success": True, + "message": f"Restored from record '{old_name}'", + "children": restored_children, + } + + def migrate_etaxes_settings_to_single(): """ Called from after_migrate hook.