e-taxes settings is single doctype now

This commit is contained in:
Ali 2026-03-03 16:25:39 +04:00
parent 639d580c19
commit 61ec366149
1 changed files with 70 additions and 68 deletions

View File

@ -1,36 +1,14 @@
""" """
Migrate E-Taxes Settings from multi-record to Single doctype. Migrate E-Taxes Settings from multi-record to Single doctype.
Before this patch the doctype had multiple records (with is_active/is_default flags). IMPORTANT: patches run after schema sync, so Frappe's ORM already treats
After converting to issingle=1 the data must live in tabSingles and child tables E-Taxes Settings as a Single. All reads from the old table use raw SQL.
must have parent = "E-Taxes Settings".
""" """
import frappe import frappe
def execute(): SCALAR_FIELDS = [
# Nothing to do if the old table doesn't exist (fresh install)
if not frappe.db.table_exists("tabE-Taxes Settings"):
return
# Find the best old record: prefer is_default=1, then is_active=1, then any
old_name = (
frappe.db.get_value("E-Taxes Settings", {"is_default": 1}, "name", ignore=True)
or frappe.db.get_value("E-Taxes Settings", {"is_active": 1}, "name", ignore=True)
or frappe.db.get_value("E-Taxes Settings", {}, "name", ignore=True)
)
if not old_name or old_name == "E-Taxes Settings":
# Already migrated or nothing to migrate
_migrate_child_tables(old_name)
return
# Read the old record as raw dict
old_row = frappe.db.get_value(
"E-Taxes Settings",
old_name,
[
"similarity_threshold", "similarity_threshold",
"consider_azeri_chars", "consider_azeri_chars",
"default_item_group", "default_item_group",
@ -39,36 +17,9 @@ def execute():
"default_supplier_group", "default_supplier_group",
"default_customer_group", "default_customer_group",
"default_payment_terms", "default_payment_terms",
], ]
as_dict=True,
ignore=True,
)
if not old_row: CHILD_TABLES = [
return
# Write scalar fields into the Single record
settings = frappe.get_single("E-Taxes Settings")
for field, value in old_row.items():
if value is not None:
setattr(settings, field, value)
# Migrate child tables: update parent to "E-Taxes Settings"
_migrate_child_tables(old_name)
# Save the single record (scalar fields only — child rows are already re-parented)
settings.flags.ignore_validate = True
settings.save(ignore_permissions=True)
frappe.db.commit()
def _migrate_child_tables(old_name):
"""Re-parent child table rows from the old record name to 'E-Taxes Settings'."""
if not old_name or old_name == "E-Taxes Settings":
return
child_tables = [
"tabE-Taxes Item Mapping", "tabE-Taxes Item Mapping",
"tabE-Taxes Customer Mappings", "tabE-Taxes Customer Mappings",
"tabE-Taxes Supplier Mappings", "tabE-Taxes Supplier Mappings",
@ -76,15 +27,66 @@ def _migrate_child_tables(old_name):
"tabE-Taxes VAT Account Mapping", "tabE-Taxes VAT Account Mapping",
] ]
for table in child_tables:
if frappe.db.table_exists(table): def execute():
if not frappe.db.table_exists("tabE-Taxes Settings"):
return
# Find the best old record via raw SQL.
# Frappe ORM treats the doctype as Single by now, so we must bypass it.
# Prefer is_default=1, then is_active=1, then any record with a non-standard name.
# Wrap each attempt in try/except in case old columns were already dropped.
old_row = None
for query in [
"SELECT * FROM `tabE-Taxes Settings` WHERE `is_default` = 1 LIMIT 1",
"SELECT * FROM `tabE-Taxes Settings` WHERE `is_active` = 1 LIMIT 1",
"SELECT * FROM `tabE-Taxes Settings` WHERE `name` != 'E-Taxes Settings' LIMIT 1",
]:
try:
old_row = _raw_get(query)
except Exception:
pass
if old_row:
break
if not old_row:
return # Fresh install or already migrated
old_name = old_row.get("name")
# Write scalar fields into tabSingles via raw SQL
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)),
)
# Re-parent child table rows from old name → "E-Taxes Settings"
for table in CHILD_TABLES:
if not frappe.db.table_exists(table):
continue
frappe.db.sql( frappe.db.sql(
f""" f"""
UPDATE `{table}` UPDATE `{table}`
SET parent = 'E-Taxes Settings', SET parent = 'E-Taxes Settings',
parenttype = 'E-Taxes Settings' parenttype = 'E-Taxes Settings'
WHERE parent = %s WHERE parent = %s
AND parenttype = 'E-Taxes Settings'
""", """,
(old_name,), (old_name,),
) )
frappe.db.commit()
frappe.clear_cache(doctype="E-Taxes Settings")
def _raw_get(query):
rows = frappe.db.sql(query, as_dict=True)
return rows[0] if rows else None