add Company default accounts export/import

- Export: company_export.py exports all Link-to-Account fields as account_name
- Import: create_default_company_accounts() resolves account names to full accounts in new company, applied via setup_wizard_complete
- JS: Export Defaults button in Company list view downloads company_defaults.json
- default_data/company_defaults.json: initial defaults

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ali 2026-03-26 17:10:46 +04:00
parent ea5847b353
commit ee421cf613
5 changed files with 122 additions and 0 deletions

View File

@ -0,0 +1,58 @@
import frappe
ACCOUNT_FIELDS = [
"default_bank_account",
"default_cash_account",
"default_receivable_account",
"round_off_account",
"write_off_account",
"exchange_gain_loss_account",
"unrealized_exchange_gain_loss_account",
"default_payable_account",
"default_expense_account",
"default_income_account",
"default_deferred_revenue_account",
"default_deferred_expense_account",
"default_inventory_account",
"stock_adjustment_account",
"stock_received_but_not_billed",
"accumulated_depreciation_account",
"depreciation_expense_account",
"disposal_account",
"capital_work_in_progress_account",
"asset_received_but_not_billed",
"unrealized_profit_loss_account",
"default_discount_account",
"default_provisional_account",
"default_advance_received_account",
"default_advance_paid_account",
"default_operating_cost_account",
"round_off_for_opening",
"purchase_expense_account",
"purchase_expense_contra_account",
"service_expense_account",
]
@frappe.whitelist()
def export_company_defaults():
company = frappe.db.get_single_value("Global Defaults", "default_company")
if not company:
companies = frappe.get_all("Company", limit=1)
if companies:
company = companies[0].name
if not company:
frappe.throw("No company found")
doc = frappe.get_doc("Company", company)
result = {}
for fieldname in ACCOUNT_FIELDS:
full_account = doc.get(fieldname)
if full_account:
account_name = frappe.db.get_value("Account", full_account, "account_name")
if account_name:
result[fieldname] = account_name
return result

View File

@ -0,0 +1,9 @@
{
"default_bank_account": "Depozit hesablar",
"default_cash_account": "Pul vəsaitlərinin ekvivalentləri",
"default_receivable_account": "Verilmiş qısamüddətli borclar",
"default_payable_account": "Digər qısamüddətli kreditor borcları",
"default_expense_account": "Satışın digər maya dəyəri xərcləri",
"default_income_account": "Satış",
"default_inventory_account": "Digər ehtiyatlar"
}

View File

@ -34,6 +34,7 @@ doctype_list_js = {
"Salary Component": "public/js/salary_component_list.js",
"Account": "public/js/account_list.js",
"Leave Type": "public/js/leave_type_list.js",
"Company": "public/js/company_list.js",
}
extend_doctype_class = {
@ -86,6 +87,7 @@ doc_events = {
setup_wizard_complete = [
"jey_erp.setup.setup_wizard_handler.create_default_salary_components",
"jey_erp.setup.setup_wizard_handler.create_default_leave_types",
"jey_erp.setup.setup_wizard_handler.create_default_company_accounts",
]
after_migrate = "jey_erp.hooks.after_migrate_combined"

View File

@ -0,0 +1,20 @@
frappe.listview_settings["Company"] = {
onload: function (listview) {
listview.page.add_inner_button(__("Export Defaults"), function () {
frappe.call({
method: "jey_erp.custom.company_export.export_company_defaults",
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 = "company_defaults.json";
a.click();
URL.revokeObjectURL(url);
},
});
});
},
};

View File

@ -15,6 +15,12 @@ LEAVE_TYPES_JSON = os.path.join(
"leave_types.json",
)
COMPANY_DEFAULTS_JSON = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
"default_data",
"company_defaults.json",
)
HRMS_DEFAULT_COMPONENTS = ["Basic", "Arrear", "Leave Encashment", "Income Tax"]
@ -82,6 +88,33 @@ def create_default_leave_types(args):
frappe.db.commit()
def create_default_company_accounts(args):
if not os.path.exists(COMPANY_DEFAULTS_JSON):
return
company = args.get("company_name") or frappe.db.get_single_value("Global Defaults", "default_company")
if not company:
return
with open(COMPANY_DEFAULTS_JSON, encoding="utf-8") as f:
defaults = json.load(f)
doc = frappe.get_doc("Company", company)
updated = False
for fieldname, account_name in defaults.items():
full_account = frappe.db.get_value(
"Account", {"account_name": account_name, "company": company}, "name"
)
if full_account:
doc.set(fieldname, full_account)
updated = True
if updated:
doc.save(ignore_permissions=True)
frappe.db.commit()
def setup_wizard_complete_handler(args):
"""
Вызывается после завершения ERPNext setup wizard.