fix(master-data): import shipped Items ourselves, resolving the Item Group root by name
fixtures/item.json was imported blindly by Frappe's import_fixtures on every migrate and hard-failed (skipping the whole file) on sites whose Item Group tree root is not literally "All Item Groups" — e.g. the Azerbaijani-localized "Bütün Element Qrupları" — so the fuel Items never got created and the reports relying on them came up empty. Move the file to master_data/ and import it via a new sync_items() in after_migrate (after sync_item_groups). It resolves the root Item Group by either known name (falling back to the structural root), remaps the shipped root reference to whatever this site calls its root, and inserts only missing items — existing items and their report data are never touched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5c96fe7836
commit
9b1f2b79e0
|
|
@ -21,6 +21,7 @@ fixtures = [
|
|||
after_migrate = [
|
||||
"taxes_az.master_data.sync.sync_main_type_of_activity",
|
||||
"taxes_az.master_data.sync.sync_item_groups",
|
||||
"taxes_az.master_data.sync.sync_items",
|
||||
"taxes_az.setup_accounts.check_and_create_accounts"
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -205,6 +205,88 @@ def sync_main_type_of_activity() -> dict:
|
|||
return sync_master_data("Main type of activity", path, key_field="name")
|
||||
|
||||
|
||||
# Item Group names that all mean "the tree root". The shipped item.json refers
|
||||
# to the root by ERPNext's English name, but localized installs rename it.
|
||||
_ROOT_ALIASES = ("All Item Groups", "Bütün Element Qrupları")
|
||||
|
||||
|
||||
def _resolve_item_group_root() -> str | None:
|
||||
"""Find this site's Item Group tree root by any of its known names.
|
||||
|
||||
ERPNext ships the root as "All Item Groups", but localized installs rename
|
||||
it (e.g. the Azerbaijani "Bütün Element Qrupları"). Try the known names in
|
||||
order, then fall back to the structural root (a group with no parent).
|
||||
"""
|
||||
for candidate in _ROOT_ALIASES:
|
||||
if frappe.db.exists("Item Group", candidate):
|
||||
return candidate
|
||||
roots = frappe.get_all(
|
||||
"Item Group",
|
||||
filters={"is_group": 1, "parent_item_group": ("in", ("", None))},
|
||||
pluck="name",
|
||||
limit=1,
|
||||
)
|
||||
return roots[0] if roots else None
|
||||
|
||||
|
||||
def sync_items() -> dict:
|
||||
"""Create the fuel Items the app ships, resolving the Item Group root name.
|
||||
|
||||
These records used to live in ``fixtures/item.json``, which Frappe's
|
||||
``import_fixtures`` imports blindly on every migrate. That import hard-fails
|
||||
and skips the *whole* file on sites whose Item Group root is not literally
|
||||
named "All Item Groups" (e.g. the localized "Bütün Element Qrupları"), so the
|
||||
items never get created and the reports that rely on them come up empty.
|
||||
|
||||
We import the same records ourselves instead: the root reference is remapped
|
||||
to whatever this site actually calls its root, and only *missing* items are
|
||||
inserted — existing items (and any report data on them) are never touched.
|
||||
|
||||
Must run after :func:`sync_item_groups` so the "Yanacaq növləri" group exists.
|
||||
"""
|
||||
path = frappe.get_app_path("taxes_az", "master_data", "item.json")
|
||||
if not os.path.exists(path):
|
||||
frappe.logger().warning(f"[taxes_az] master data file not found: {path}")
|
||||
return {"skipped": True}
|
||||
|
||||
with open(path, encoding="utf-8") as f:
|
||||
records = json.load(f)
|
||||
|
||||
root = _resolve_item_group_root()
|
||||
inserted = skipped = 0
|
||||
|
||||
for rec in records:
|
||||
name = rec.get("name") or rec.get("item_code")
|
||||
if not name or frappe.db.exists("Item", name):
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
group = rec.get("item_group")
|
||||
# Remap the ERPNext root name to whatever this site calls its root.
|
||||
if group in _ROOT_ALIASES and root:
|
||||
group = root
|
||||
if not group or not frappe.db.exists("Item Group", group):
|
||||
frappe.logger().warning(
|
||||
f"[taxes_az] Item '{name}': Item Group '{group}' not found — skipped"
|
||||
)
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
doc = frappe.new_doc("Item")
|
||||
doc.update(rec)
|
||||
doc.item_group = group
|
||||
doc.name = name
|
||||
doc.flags.name_set = True
|
||||
doc.flags.ignore_permissions = True
|
||||
doc.insert(ignore_if_duplicate=True)
|
||||
inserted += 1
|
||||
|
||||
if inserted:
|
||||
frappe.db.commit()
|
||||
print(f"[taxes_az] Item: +{inserted} (skipped {skipped})")
|
||||
return {"doctype": "Item", "inserted": inserted, "skipped": skipped}
|
||||
|
||||
|
||||
def sync_item_groups() -> dict:
|
||||
"""Sync the Azerbaijan tax-specific Item Groups.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue