add Chart of Accounts export button to list and tree views
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
989cce52b4
commit
df9f72be11
|
|
@ -0,0 +1,68 @@
|
|||
import re
|
||||
|
||||
import frappe
|
||||
|
||||
# 223.1–223.5: IBAN (AZ + 2 digits + 4 uppercase letters + 20 digits = 28 chars)
|
||||
_IBAN_RE = re.compile(r"AZ\d{2}[A-Z]{4}\d{20}")
|
||||
# 223.6: card/account number — любая последовательность 10+ цифр подряд
|
||||
_DIGITS_RE = re.compile(r"\d{10,}")
|
||||
|
||||
MASK_IBAN = {"223.1", "223.2", "223.3", "223.4", "223.5"}
|
||||
MASK_CARD = {"223.6"}
|
||||
|
||||
|
||||
def _mask(account_name, account_number):
|
||||
if account_number in MASK_IBAN:
|
||||
account_name = _IBAN_RE.sub(lambda m: "X" * len(m.group()), account_name)
|
||||
if account_number in MASK_CARD:
|
||||
account_name = _DIGITS_RE.sub(lambda m: "X" * len(m.group()), account_name)
|
||||
return account_name
|
||||
|
||||
|
||||
def _build_node(account, children_of):
|
||||
node = {}
|
||||
|
||||
if account.account_number:
|
||||
node["account_number"] = account.account_number
|
||||
if account.root_type:
|
||||
node["root_type"] = account.root_type
|
||||
if account.is_group:
|
||||
node["is_group"] = 1
|
||||
if account.account_type:
|
||||
node["account_type"] = account.account_type
|
||||
|
||||
for child in children_of.get(account.name, []):
|
||||
key = _mask(child.account_name, child.account_number or "")
|
||||
node[key] = _build_node(child, children_of)
|
||||
|
||||
return node
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def export_chart_of_accounts():
|
||||
accounts = frappe.get_all(
|
||||
"Account",
|
||||
fields=["name", "account_name", "account_number", "parent_account",
|
||||
"root_type", "account_type", "is_group"],
|
||||
order_by="lft",
|
||||
)
|
||||
|
||||
children_of = {}
|
||||
roots = []
|
||||
|
||||
for a in accounts:
|
||||
if not a.parent_account:
|
||||
roots.append(a)
|
||||
else:
|
||||
children_of.setdefault(a.parent_account, []).append(a)
|
||||
|
||||
tree = {}
|
||||
for root in roots:
|
||||
key = _mask(root.account_name, root.account_number or "")
|
||||
tree[key] = _build_node(root, children_of)
|
||||
|
||||
return {
|
||||
"country_code": "az",
|
||||
"name": "Azerbaijan Republic",
|
||||
"tree": tree,
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ doctype_js = {
|
|||
doctype_list_js = {
|
||||
"Currency Exchange": "public/js/currency_exchange_list.js",
|
||||
"Salary Component": "public/js/salary_component_list.js",
|
||||
"Account": "public/js/account_list.js",
|
||||
}
|
||||
|
||||
extend_doctype_class = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
frappe.listview_settings["Account"] = {
|
||||
onload: function (listview) {
|
||||
listview.page.add_inner_button(__("Export Chart of Accounts"), function () {
|
||||
frappe.call({
|
||||
method: "jey_erp.custom.account_export.export_chart_of_accounts",
|
||||
callback: function (r) {
|
||||
if (!r.message) return;
|
||||
const json = JSON.stringify(r.message, null, 2);
|
||||
const blob = new Blob([json], { type: "application/json" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "az_chart_of_accounts.json";
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
@ -1,5 +1,29 @@
|
|||
frappe.provide("frappe.treeview_settings");
|
||||
|
||||
function _download_chart_of_accounts() {
|
||||
frappe.call({
|
||||
method: "jey_erp.custom.account_export.export_chart_of_accounts",
|
||||
callback: function (r) {
|
||||
if (!r.message) return;
|
||||
const json = JSON.stringify(r.message, null, 2);
|
||||
const blob = new Blob([json], { type: "application/json" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "az_chart_of_accounts.json";
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
frappe.treeview_settings["Account"] = frappe.treeview_settings["Account"] || {};
|
||||
frappe.treeview_settings["Account"].onload = function (treeview) {
|
||||
treeview.page.add_inner_button(__("Export Chart of Accounts"), function () {
|
||||
_download_chart_of_accounts();
|
||||
});
|
||||
};
|
||||
|
||||
// Сохраняем оригинальные поля
|
||||
var original_fields = frappe.treeview_settings["Account"].fields;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue