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,90 +1,92 @@
""" """
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
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 = [
"tabE-Taxes Item Mapping",
"tabE-Taxes Customer Mappings",
"tabE-Taxes Supplier Mappings",
"tabE-Taxes Unit Mapping",
"tabE-Taxes VAT Account Mapping",
]
def execute(): def execute():
# Nothing to do if the old table doesn't exist (fresh install)
if not frappe.db.table_exists("tabE-Taxes Settings"): if not frappe.db.table_exists("tabE-Taxes Settings"):
return return
# Find the best old record: prefer is_default=1, then is_active=1, then any # Find the best old record via raw SQL.
old_name = ( # Frappe ORM treats the doctype as Single by now, so we must bypass it.
frappe.db.get_value("E-Taxes Settings", {"is_default": 1}, "name", ignore=True) # Prefer is_default=1, then is_active=1, then any record with a non-standard name.
or frappe.db.get_value("E-Taxes Settings", {"is_active": 1}, "name", ignore=True) # Wrap each attempt in try/except in case old columns were already dropped.
or frappe.db.get_value("E-Taxes Settings", {}, "name", ignore=True) old_row = None
)
if not old_name or old_name == "E-Taxes Settings": for query in [
# Already migrated or nothing to migrate "SELECT * FROM `tabE-Taxes Settings` WHERE `is_default` = 1 LIMIT 1",
_migrate_child_tables(old_name) "SELECT * FROM `tabE-Taxes Settings` WHERE `is_active` = 1 LIMIT 1",
return "SELECT * FROM `tabE-Taxes Settings` WHERE `name` != 'E-Taxes Settings' LIMIT 1",
]:
# Read the old record as raw dict try:
old_row = frappe.db.get_value( old_row = _raw_get(query)
"E-Taxes Settings", except Exception:
old_name, pass
[ if old_row:
"similarity_threshold", break
"consider_azeri_chars",
"default_item_group",
"default_uom",
"default_item_tax_template",
"default_supplier_group",
"default_customer_group",
"default_payment_terms",
],
as_dict=True,
ignore=True,
)
if not old_row: if not old_row:
return return # Fresh install or already migrated
# Write scalar fields into the Single record old_name = old_row.get("name")
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" # Write scalar fields into tabSingles via raw SQL
_migrate_child_tables(old_name) 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)),
)
# Save the single record (scalar fields only — child rows are already re-parented) # Re-parent child table rows from old name → "E-Taxes Settings"
settings.flags.ignore_validate = True for table in CHILD_TABLES:
settings.save(ignore_permissions=True) if not frappe.db.table_exists(table):
continue
frappe.db.sql(
f"""
UPDATE `{table}`
SET parent = 'E-Taxes Settings',
parenttype = 'E-Taxes Settings'
WHERE parent = %s
""",
(old_name,),
)
frappe.db.commit() frappe.db.commit()
frappe.clear_cache(doctype="E-Taxes Settings")
def _migrate_child_tables(old_name): def _raw_get(query):
"""Re-parent child table rows from the old record name to 'E-Taxes Settings'.""" rows = frappe.db.sql(query, as_dict=True)
if not old_name or old_name == "E-Taxes Settings": return rows[0] if rows else None
return
child_tables = [
"tabE-Taxes Item Mapping",
"tabE-Taxes Customer Mappings",
"tabE-Taxes Supplier Mappings",
"tabE-Taxes Unit Mapping",
"tabE-Taxes VAT Account Mapping",
]
for table in child_tables:
if frappe.db.table_exists(table):
frappe.db.sql(
f"""
UPDATE `{table}`
SET parent = 'E-Taxes Settings',
parenttype = 'E-Taxes Settings'
WHERE parent = %s
AND parenttype = 'E-Taxes Settings'
""",
(old_name,),
)