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:
parent
ea5847b353
commit
ee421cf613
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue