add salary component export button and default setup from JSON
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
116efda4f2
commit
7cd7b5d887
|
|
@ -0,0 +1,23 @@
|
|||
import frappe
|
||||
|
||||
SKIP_FIELDS = {"name", "creation", "modified", "modified_by", "owner", "docstatus", "idx"}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def export_salary_components():
|
||||
components = frappe.get_all("Salary Component", fields=["name"])
|
||||
result = []
|
||||
|
||||
for c in components:
|
||||
doc = frappe.get_doc("Salary Component", c.name)
|
||||
data = doc.as_dict()
|
||||
|
||||
for field in SKIP_FIELDS:
|
||||
data.pop(field, None)
|
||||
|
||||
# accounts — company-specific, не экспортируем
|
||||
data.pop("accounts", None)
|
||||
|
||||
result.append(data)
|
||||
|
||||
return result
|
||||
|
|
@ -31,6 +31,7 @@ doctype_js = {
|
|||
|
||||
doctype_list_js = {
|
||||
"Currency Exchange": "public/js/currency_exchange_list.js",
|
||||
"Salary Component": "public/js/salary_component_list.js",
|
||||
}
|
||||
|
||||
extend_doctype_class = {
|
||||
|
|
@ -80,7 +81,7 @@ doc_events = {
|
|||
# Asset categories are now created automatically via Company.on_update event
|
||||
# setup_wizard_complete = "jey_erp.setup.setup_wizard_handler.setup_wizard_complete_handler"
|
||||
|
||||
setup_wizard_complete = "jey_erp.setup.setup_wizard_handler.create_test_salary_component"
|
||||
setup_wizard_complete = "jey_erp.setup.setup_wizard_handler.create_default_salary_components"
|
||||
|
||||
after_migrate = "jey_erp.hooks.after_migrate_combined"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
frappe.listview_settings["Salary Component"] = {
|
||||
onload: function (listview) {
|
||||
listview.page.add_inner_button(__("Export Defaults"), function () {
|
||||
frappe.call({
|
||||
method: "jey_erp.custom.salary_component_export.export_salary_components",
|
||||
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 = "salary_components.json";
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
@ -1,25 +1,34 @@
|
|||
import json
|
||||
import os
|
||||
|
||||
import frappe
|
||||
|
||||
SALARY_COMPONENTS_JSON = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
"default_data",
|
||||
"salary_components.json",
|
||||
)
|
||||
|
||||
def create_test_salary_component(args):
|
||||
if frappe.db.exists("Salary Component", "TEST COMP"):
|
||||
|
||||
def create_default_salary_components(args):
|
||||
if not os.path.exists(SALARY_COMPONENTS_JSON):
|
||||
return
|
||||
|
||||
company = args.get("company_name") or frappe.db.get_single_value("Global Defaults", "default_company")
|
||||
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Salary Component",
|
||||
"salary_component": "TEST COMP",
|
||||
"salary_component_abbr": "TC",
|
||||
"type": "Earning",
|
||||
"accounts": [
|
||||
{
|
||||
"company": company,
|
||||
"account": None, # можно указать конкретный счёт
|
||||
}
|
||||
] if company else [],
|
||||
})
|
||||
doc.insert(ignore_permissions=True)
|
||||
with open(SALARY_COMPONENTS_JSON, encoding="utf-8") as f:
|
||||
components = json.load(f)
|
||||
|
||||
for data in components:
|
||||
name = data.get("salary_component")
|
||||
if not name or frappe.db.exists("Salary Component", name):
|
||||
continue
|
||||
|
||||
data["doctype"] = "Salary Component"
|
||||
data["accounts"] = [{"company": company, "account": None}] if company else []
|
||||
|
||||
frappe.get_doc(data).insert(ignore_permissions=True)
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue