removed all backup files
This commit is contained in:
parent
408e55d709
commit
c28c968710
|
|
@ -78,10 +78,8 @@ def after_install():
|
||||||
def after_migrate():
|
def after_migrate():
|
||||||
"""Run migration tasks"""
|
"""Run migration tasks"""
|
||||||
from invoice_az.auth import setup_token_renewal
|
from invoice_az.auth import setup_token_renewal
|
||||||
from invoice_az.migrate_utils import migrate_etaxes_settings_to_single
|
|
||||||
|
|
||||||
setup_token_renewal()
|
setup_token_renewal()
|
||||||
migrate_etaxes_settings_to_single()
|
|
||||||
|
|
||||||
# Fixtures for master data
|
# Fixtures for master data
|
||||||
# ------------------------
|
# ------------------------
|
||||||
|
|
|
||||||
|
|
@ -12,31 +12,6 @@ frappe.ui.form.on('E-Taxes Settings', {
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frm.add_custom_button(__('Restore from file'), function() {
|
|
||||||
frappe.confirm(
|
|
||||||
__('Restore all settings and mappings from backup file? Current data will be overwritten.'),
|
|
||||||
function() {
|
|
||||||
frappe.call({
|
|
||||||
method: 'invoice_az.migrate_utils.restore_etaxes_from_file',
|
|
||||||
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
|
// Main Load All Data button
|
||||||
frm.add_custom_button(__('Load All Data'), function() {
|
frm.add_custom_button(__('Load All Data'), function() {
|
||||||
show_load_all_data_dialog(frm);
|
show_load_all_data_dialog(frm);
|
||||||
|
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
import json
|
|
||||||
import os
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
BACKUP_FILENAME = "etaxes_settings_backup.json"
|
|
||||||
|
|
||||||
SCALAR_FIELDS = [
|
|
||||||
"similarity_threshold",
|
|
||||||
"consider_azeri_chars",
|
|
||||||
"default_item_group",
|
|
||||||
"default_uom",
|
|
||||||
"default_item_tax_template",
|
|
||||||
"default_supplier_group",
|
|
||||||
"default_customer_group",
|
|
||||||
"default_payment_terms",
|
|
||||||
]
|
|
||||||
|
|
||||||
CHILD_TABLES = {
|
|
||||||
"item_mappings": "tabE-Taxes Item Mapping",
|
|
||||||
"customer_mappings": "tabE-Taxes Customer Mappings",
|
|
||||||
"supplier_mappings": "tabE-Taxes Supplier Mappings",
|
|
||||||
"unit_mappings": "tabE-Taxes Unit Mapping",
|
|
||||||
"vat_account_mappings": "tabE-Taxes VAT Account Mapping",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _backup_path():
|
|
||||||
return frappe.get_site_path("private", BACKUP_FILENAME)
|
|
||||||
|
|
||||||
|
|
||||||
def _sql_table_exists(table_name):
|
|
||||||
"""Check if table exists via raw SQL (bypasses Frappe metadata)."""
|
|
||||||
result = frappe.db.sql(
|
|
||||||
"SHOW TABLES LIKE %s",
|
|
||||||
(table_name,),
|
|
||||||
)
|
|
||||||
return bool(result)
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def export_etaxes_to_file():
|
|
||||||
"""
|
|
||||||
Export E-Taxes Settings data to a JSON file.
|
|
||||||
Works even after git pull (when doctype JSON already says issingle=1
|
|
||||||
but the old multi-record table still exists in MySQL).
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
bench --site <site> execute invoice_az.migrate_utils.export_etaxes_to_file
|
|
||||||
"""
|
|
||||||
# Try old multi-record table first
|
|
||||||
if _sql_table_exists("tabE-Taxes Settings"):
|
|
||||||
return _export_from_table()
|
|
||||||
|
|
||||||
# Fallback: already migrated to Single — export from tabSingles
|
|
||||||
singles = frappe.db.sql(
|
|
||||||
"SELECT field, value FROM tabSingles WHERE doctype = 'E-Taxes Settings'",
|
|
||||||
as_dict=True,
|
|
||||||
)
|
|
||||||
if singles:
|
|
||||||
return _export_from_singles(singles)
|
|
||||||
|
|
||||||
print("ERROR: No data found — neither tabE-Taxes Settings table nor tabSingles entries exist")
|
|
||||||
|
|
||||||
|
|
||||||
def _export_from_table():
|
|
||||||
"""Export from the old multi-record table."""
|
|
||||||
rows = frappe.db.sql("SELECT * FROM `tabE-Taxes Settings` LIMIT 1", as_dict=True)
|
|
||||||
if not rows:
|
|
||||||
print("ERROR: tabE-Taxes Settings table exists but is empty")
|
|
||||||
return
|
|
||||||
|
|
||||||
old_row = rows[0]
|
|
||||||
old_name = old_row["name"]
|
|
||||||
|
|
||||||
backup = {
|
|
||||||
"old_name": old_name,
|
|
||||||
"scalar": {},
|
|
||||||
"children": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
for field in SCALAR_FIELDS:
|
|
||||||
backup["scalar"][field] = old_row.get(field)
|
|
||||||
|
|
||||||
for fieldname, table in CHILD_TABLES.items():
|
|
||||||
if _sql_table_exists(table):
|
|
||||||
child_rows = frappe.db.sql(
|
|
||||||
f"SELECT * FROM `{table}` WHERE parent = %s ORDER BY idx",
|
|
||||||
(old_name,),
|
|
||||||
as_dict=True,
|
|
||||||
)
|
|
||||||
backup["children"][fieldname] = [dict(r) for r in child_rows]
|
|
||||||
|
|
||||||
return _save_backup(backup, old_name)
|
|
||||||
|
|
||||||
|
|
||||||
def _export_from_singles(singles):
|
|
||||||
"""Export from tabSingles (already a Single doctype)."""
|
|
||||||
backup = {
|
|
||||||
"old_name": "E-Taxes Settings",
|
|
||||||
"scalar": {},
|
|
||||||
"children": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
singles_map = {r["field"]: r["value"] for r in singles}
|
|
||||||
for field in SCALAR_FIELDS:
|
|
||||||
backup["scalar"][field] = singles_map.get(field)
|
|
||||||
|
|
||||||
for fieldname, table in CHILD_TABLES.items():
|
|
||||||
if _sql_table_exists(table):
|
|
||||||
child_rows = frappe.db.sql(
|
|
||||||
f"SELECT * FROM `{table}` WHERE parent = 'E-Taxes Settings' ORDER BY idx",
|
|
||||||
as_dict=True,
|
|
||||||
)
|
|
||||||
backup["children"][fieldname] = [dict(r) for r in child_rows]
|
|
||||||
|
|
||||||
return _save_backup(backup, "E-Taxes Settings")
|
|
||||||
|
|
||||||
|
|
||||||
def _save_backup(backup, source_name):
|
|
||||||
"""Save backup dict to JSON file."""
|
|
||||||
path = _backup_path()
|
|
||||||
with open(path, "w", encoding="utf-8") as f:
|
|
||||||
json.dump(backup, f, default=str, ensure_ascii=False, indent=2)
|
|
||||||
|
|
||||||
total_children = sum(len(v) for v in backup["children"].values())
|
|
||||||
print(f"Saved to: {path}")
|
|
||||||
print(f"Source: '{source_name}'")
|
|
||||||
print(f"Scalar fields: {sum(1 for v in backup['scalar'].values() if v is not None)}")
|
|
||||||
print(f"Child rows: {total_children}")
|
|
||||||
for fieldname, rows in backup["children"].items():
|
|
||||||
if rows:
|
|
||||||
print(f" {fieldname}: {len(rows)}")
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def restore_etaxes_from_file():
|
|
||||||
"""
|
|
||||||
Restore E-Taxes Settings from backup JSON file.
|
|
||||||
|
|
||||||
Usage (CLI):
|
|
||||||
bench --site <site> execute invoice_az.migrate_utils.restore_etaxes_from_file
|
|
||||||
|
|
||||||
Also callable from the E-Taxes Settings form button.
|
|
||||||
"""
|
|
||||||
path = _backup_path()
|
|
||||||
|
|
||||||
if not os.path.exists(path):
|
|
||||||
msg = f"Backup file not found: {path}"
|
|
||||||
print(f"ERROR: {msg}")
|
|
||||||
return {"success": False, "message": msg}
|
|
||||||
|
|
||||||
with open(path, encoding="utf-8") as f:
|
|
||||||
backup = json.load(f)
|
|
||||||
|
|
||||||
# Scalar fields → tabSingles
|
|
||||||
restored_scalars = 0
|
|
||||||
for field, value in backup.get("scalar", {}).items():
|
|
||||||
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)),
|
|
||||||
)
|
|
||||||
restored_scalars += 1
|
|
||||||
|
|
||||||
# Child tables → update parent for existing rows + insert missing ones
|
|
||||||
restored_children = 0
|
|
||||||
old_name = backup.get("old_name", "")
|
|
||||||
for fieldname, rows in backup.get("children", {}).items():
|
|
||||||
table = CHILD_TABLES.get(fieldname)
|
|
||||||
if not table or not _sql_table_exists(table) or not rows:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# First: update parent/parenttype/parentfield for ALL rows that came from old name
|
|
||||||
if old_name and old_name != "E-Taxes Settings":
|
|
||||||
frappe.db.sql(
|
|
||||||
f"UPDATE `{table}` SET parent = 'E-Taxes Settings', "
|
|
||||||
f"parenttype = 'E-Taxes Settings', parentfield = %s "
|
|
||||||
f"WHERE parent = %s",
|
|
||||||
(fieldname, old_name),
|
|
||||||
)
|
|
||||||
updated = frappe.db.sql("SELECT ROW_COUNT() as cnt")[0][0]
|
|
||||||
if updated:
|
|
||||||
print(f" {table}: updated parent for {updated} existing rows")
|
|
||||||
restored_children += updated
|
|
||||||
|
|
||||||
# Then: insert any rows that don't exist yet
|
|
||||||
for row in rows:
|
|
||||||
row["parent"] = "E-Taxes Settings"
|
|
||||||
row["parenttype"] = "E-Taxes Settings"
|
|
||||||
row["parentfield"] = fieldname
|
|
||||||
columns = ", ".join(f"`{col}`" for col in row)
|
|
||||||
placeholders = ", ".join(["%s"] * len(row))
|
|
||||||
try:
|
|
||||||
frappe.db.sql(
|
|
||||||
f"INSERT IGNORE INTO `{table}` ({columns}) VALUES ({placeholders})",
|
|
||||||
list(row.values()),
|
|
||||||
)
|
|
||||||
if frappe.db.sql("SELECT ROW_COUNT() as cnt")[0][0]:
|
|
||||||
restored_children += 1
|
|
||||||
except Exception as e:
|
|
||||||
print(f" Warning: failed to insert row in {table}: {e}")
|
|
||||||
|
|
||||||
frappe.db.commit()
|
|
||||||
frappe.clear_cache(doctype="E-Taxes Settings")
|
|
||||||
|
|
||||||
msg = f"Restored {restored_scalars} fields, {restored_children} child rows"
|
|
||||||
print(f"OK: {msg}")
|
|
||||||
return {"success": True, "message": msg}
|
|
||||||
|
|
||||||
|
|
||||||
def migrate_etaxes_settings_to_single():
|
|
||||||
"""Called from after_migrate hook — no-op if old table is gone."""
|
|
||||||
pass
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
invoice_az.patches.v1_0.migrate_etaxes_settings_to_single
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
import frappe
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
from invoice_az.migrate_utils import migrate_etaxes_settings_to_single
|
|
||||||
|
|
||||||
migrate_etaxes_settings_to_single()
|
|
||||||
Loading…
Reference in New Issue