Hide & exclude inactive e-taxes rows; drop Status column
Inactive rows (objects/cash registers/POS with status != A; bank accounts with status = C) are no longer counted, previewed, or kept in the DB. - Single active-status source of truth: _extract_items / _is_active / _active_items, mirroring _purge_inactive_etaxes_records. - fetch_all_etaxes summary counts active rows only (drop _count_items). - _preview_* filter inactive and remove the Status column (4 lists). - Presented certificates (audit records) left untouched. DB side was already covered by the post-load purge; this makes the wizard list/counter consistent with what survives finalize. Bump version 0.1.28 -> 0.1.29. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
68ea3dce38
commit
e1ea661855
|
|
@ -1 +1 @@
|
||||||
__version__ = "0.1.28"
|
__version__ = "0.1.29"
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,8 @@ def fetch_all_etaxes():
|
||||||
try:
|
try:
|
||||||
data = _fetch_endpoint(method, url, payload, paginated)
|
data = _fetch_endpoint(method, url, payload, paginated)
|
||||||
cache.set(field, json.dumps(data, ensure_ascii=False))
|
cache.set(field, json.dumps(data, ensure_ascii=False))
|
||||||
summary[field] = _count_items(data, paginated)
|
# Count only active rows so the digit matches the (filtered) preview.
|
||||||
|
summary[field] = len(_active_items(field, data))
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
errors[field] = str(exc)
|
errors[field] = str(exc)
|
||||||
frappe.log_error(
|
frappe.log_error(
|
||||||
|
|
@ -260,45 +261,81 @@ def _flatten_pages(data, list_key):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
# Active-status semantics — single source of truth for counts AND preview.
|
||||||
|
# Mirrors _purge_inactive_etaxes_records on the materialize side, so what the
|
||||||
|
# user sees in the wizard list matches what actually survives into the
|
||||||
|
# E-Taxes doctypes after finalize. Inactive rows are never counted or shown.
|
||||||
|
_ACTIVE_STATUS = {"A", "ACTIVE"}
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_items(field, data):
|
||||||
|
"""Pull the raw item list out of a cached endpoint payload, handling the
|
||||||
|
paginated list-of-pages vs single-dict shapes."""
|
||||||
|
if field == "objects_json":
|
||||||
|
return (data.get("objectInfoShortList") or data.get("objects") or []) if isinstance(data, dict) else []
|
||||||
|
if field == "cash_registers_json":
|
||||||
|
return _flatten_pages(data, "cashRegisters")
|
||||||
|
if field == "pos_terminals_json":
|
||||||
|
return _flatten_pages(data, "posTerminals")
|
||||||
|
if field == "bank_accounts_json":
|
||||||
|
if isinstance(data, dict):
|
||||||
|
return data.get("bankAccounts") or []
|
||||||
|
if isinstance(data, list):
|
||||||
|
return data
|
||||||
|
return []
|
||||||
|
if field == "presented_certs_json":
|
||||||
|
return (data.get("certificateList") or []) if isinstance(data, dict) else []
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def _is_active(field, item):
|
||||||
|
"""Active-row predicate per endpoint. Presented certificates are audit
|
||||||
|
records with no active/inactive notion — always kept."""
|
||||||
|
if not isinstance(item, dict):
|
||||||
|
return False
|
||||||
|
if field == "bank_accounts_json":
|
||||||
|
# 'C' = closed; anything else (incl. blank) counts as open.
|
||||||
|
return (item.get("status") or "").strip().upper() != "C"
|
||||||
|
if field in ("objects_json", "cash_registers_json", "pos_terminals_json"):
|
||||||
|
return (item.get("status") or "").strip().upper() in _ACTIVE_STATUS
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _active_items(field, data):
|
||||||
|
"""Extracted items minus the inactive ones — the list the wizard counts,
|
||||||
|
previews, and (indirectly) loads."""
|
||||||
|
return [it for it in _extract_items(field, data) if _is_active(field, it)]
|
||||||
|
|
||||||
|
|
||||||
def _empty_preview(headers):
|
def _empty_preview(headers):
|
||||||
return {"headers": headers, "rows": []}
|
return {"headers": headers, "rows": []}
|
||||||
|
|
||||||
|
|
||||||
def _preview_objects(raw):
|
def _preview_objects(raw):
|
||||||
headers = [_("Code"), _("Name"), _("Status"), _("Address")]
|
headers = [_("Code"), _("Name"), _("Address")]
|
||||||
data = _safe_parse(raw)
|
data = _safe_parse(raw)
|
||||||
if data is None:
|
if data is None:
|
||||||
return _empty_preview(headers)
|
return _empty_preview(headers)
|
||||||
items = []
|
|
||||||
if isinstance(data, dict):
|
|
||||||
items = data.get("objectInfoShortList") or data.get("objects") or []
|
|
||||||
rows = []
|
rows = []
|
||||||
for obj in items[:PREVIEW_ROW_LIMIT]:
|
for obj in _active_items("objects_json", data)[:PREVIEW_ROW_LIMIT]:
|
||||||
if not isinstance(obj, dict):
|
|
||||||
continue
|
|
||||||
rows.append([
|
rows.append([
|
||||||
obj.get("objectCode") or "",
|
obj.get("objectCode") or "",
|
||||||
(obj.get("objectName") or "").strip(),
|
(obj.get("objectName") or "").strip(),
|
||||||
obj.get("status") or "",
|
|
||||||
obj.get("address") or "",
|
obj.get("address") or "",
|
||||||
])
|
])
|
||||||
return {"headers": headers, "rows": rows}
|
return {"headers": headers, "rows": rows}
|
||||||
|
|
||||||
|
|
||||||
def _preview_cash_registers(raw):
|
def _preview_cash_registers(raw):
|
||||||
headers = [_("Number"), _("Model"), _("Status"), _("Object"), _("Operator")]
|
headers = [_("Number"), _("Model"), _("Object"), _("Operator")]
|
||||||
data = _safe_parse(raw)
|
data = _safe_parse(raw)
|
||||||
if data is None:
|
if data is None:
|
||||||
return _empty_preview(headers)
|
return _empty_preview(headers)
|
||||||
items = _flatten_pages(data, "cashRegisters")
|
|
||||||
rows = []
|
rows = []
|
||||||
for reg in items[:PREVIEW_ROW_LIMIT]:
|
for reg in _active_items("cash_registers_json", data)[:PREVIEW_ROW_LIMIT]:
|
||||||
if not isinstance(reg, dict):
|
|
||||||
continue
|
|
||||||
rows.append([
|
rows.append([
|
||||||
reg.get("number") or "",
|
reg.get("number") or "",
|
||||||
reg.get("model") or "",
|
reg.get("model") or "",
|
||||||
reg.get("status") or "",
|
|
||||||
reg.get("object") or "",
|
reg.get("object") or "",
|
||||||
reg.get("operatorName") or "",
|
reg.get("operatorName") or "",
|
||||||
])
|
])
|
||||||
|
|
@ -306,18 +343,14 @@ def _preview_cash_registers(raw):
|
||||||
|
|
||||||
|
|
||||||
def _preview_pos_terminals(raw):
|
def _preview_pos_terminals(raw):
|
||||||
headers = [_("Serial number"), _("Status"), _("Registration date"), _("Bank")]
|
headers = [_("Serial number"), _("Registration date"), _("Bank")]
|
||||||
data = _safe_parse(raw)
|
data = _safe_parse(raw)
|
||||||
if data is None:
|
if data is None:
|
||||||
return _empty_preview(headers)
|
return _empty_preview(headers)
|
||||||
items = _flatten_pages(data, "posTerminals")
|
|
||||||
rows = []
|
rows = []
|
||||||
for term in items[:PREVIEW_ROW_LIMIT]:
|
for term in _active_items("pos_terminals_json", data)[:PREVIEW_ROW_LIMIT]:
|
||||||
if not isinstance(term, dict):
|
|
||||||
continue
|
|
||||||
rows.append([
|
rows.append([
|
||||||
term.get("serialNumber") or "",
|
term.get("serialNumber") or "",
|
||||||
term.get("status") or "",
|
|
||||||
(term.get("registrationDate") or "")[:10],
|
(term.get("registrationDate") or "")[:10],
|
||||||
term.get("bankName") or "",
|
term.get("bankName") or "",
|
||||||
])
|
])
|
||||||
|
|
@ -325,23 +358,15 @@ def _preview_pos_terminals(raw):
|
||||||
|
|
||||||
|
|
||||||
def _preview_bank_accounts(raw):
|
def _preview_bank_accounts(raw):
|
||||||
headers = [_("IBAN"), _("Currency"), _("Status"), _("Bank")]
|
headers = [_("IBAN"), _("Currency"), _("Bank")]
|
||||||
data = _safe_parse(raw)
|
data = _safe_parse(raw)
|
||||||
if data is None:
|
if data is None:
|
||||||
return _empty_preview(headers)
|
return _empty_preview(headers)
|
||||||
items = []
|
|
||||||
if isinstance(data, dict):
|
|
||||||
items = data.get("bankAccounts") or []
|
|
||||||
elif isinstance(data, list):
|
|
||||||
items = data
|
|
||||||
rows = []
|
rows = []
|
||||||
for acc in items[:PREVIEW_ROW_LIMIT]:
|
for acc in _active_items("bank_accounts_json", data)[:PREVIEW_ROW_LIMIT]:
|
||||||
if not isinstance(acc, dict):
|
|
||||||
continue
|
|
||||||
rows.append([
|
rows.append([
|
||||||
acc.get("number") or "",
|
acc.get("number") or "",
|
||||||
acc.get("currency") or "",
|
acc.get("currency") or "",
|
||||||
acc.get("status") or "",
|
|
||||||
acc.get("bankName") or "",
|
acc.get("bankName") or "",
|
||||||
])
|
])
|
||||||
return {"headers": headers, "rows": rows}
|
return {"headers": headers, "rows": rows}
|
||||||
|
|
@ -1364,27 +1389,6 @@ def _auth_headers():
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
|
|
||||||
def _count_items(data, paginated):
|
|
||||||
"""Lightweight count for UI summary. Digs one level deep to find the list."""
|
|
||||||
if paginated and isinstance(data, list):
|
|
||||||
total = 0
|
|
||||||
for page in data:
|
|
||||||
if not isinstance(page, dict):
|
|
||||||
continue
|
|
||||||
for value in page.values():
|
|
||||||
if isinstance(value, list):
|
|
||||||
total += len(value)
|
|
||||||
break
|
|
||||||
return total
|
|
||||||
if isinstance(data, dict):
|
|
||||||
for value in data.values():
|
|
||||||
if isinstance(value, list):
|
|
||||||
return len(value)
|
|
||||||
if isinstance(data, list):
|
|
||||||
return len(data)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def _find_default_warehouse(company):
|
def _find_default_warehouse(company):
|
||||||
"""Pick a sensible default warehouse for Stock Settings. ERPNext creates
|
"""Pick a sensible default warehouse for Stock Settings. ERPNext creates
|
||||||
'Stores' for every new company (is_group=0); under language=az the
|
'Stores' for every new company (is_group=0); under language=az the
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ frappe.provide("jey_wizard");
|
||||||
// Bump this string in every commit that changes wizard code. Displayed in the badge so
|
// Bump this string in every commit that changes wizard code. Displayed in the badge so
|
||||||
// we can tell at a glance which version is actually running on a given machine. Kept in
|
// we can tell at a glance which version is actually running on a given machine. Kept in
|
||||||
// sync with __version__ in jey_wizard/__init__.py.
|
// sync with __version__ in jey_wizard/__init__.py.
|
||||||
const JEY_WIZARD_VERSION = "0.1.28";
|
const JEY_WIZARD_VERSION = "0.1.29";
|
||||||
|
|
||||||
// Wipe Frappe + ERPNext default slides so their `before_load`/`after_load` listeners
|
// Wipe Frappe + ERPNext default slides so their `before_load`/`after_load` listeners
|
||||||
// don't try to mutate a wizard that isn't slide-based anymore.
|
// don't try to mutate a wizard that isn't slide-based anymore.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue