perf: Performance enhancement on setup wizard (#25605)

* perf: Performance enhancement on setup wizard

* fix: create departments without updating nsm
This commit is contained in:
Nabin Hait 2021-05-06 19:13:54 +05:30 committed by GitHub
parent dc6233b703
commit 134eaa5786
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 105 additions and 101 deletions

View File

@ -13,7 +13,7 @@ class BalanceMismatchError(frappe.ValidationError): pass
class Account(NestedSet): class Account(NestedSet):
nsm_parent_field = 'parent_account' nsm_parent_field = 'parent_account'
def on_update(self): def on_update(self):
if frappe.local.flags.ignore_on_update: if frappe.local.flags.ignore_update_nsm:
return return
else: else:
super(Account, self).on_update() super(Account, self).on_update()

View File

@ -57,10 +57,10 @@ def create_charts(company, chart_template=None, existing_company=None, custom_ch
# Rebuild NestedSet HSM tree for Account Doctype # Rebuild NestedSet HSM tree for Account Doctype
# after all accounts are already inserted. # after all accounts are already inserted.
frappe.local.flags.ignore_on_update = True frappe.local.flags.ignore_update_nsm = True
_import_accounts(chart, None, None, root_account=True) _import_accounts(chart, None, None, root_account=True)
rebuild_tree("Account", "parent_account") rebuild_tree("Account", "parent_account")
frappe.local.flags.ignore_on_update = False frappe.local.flags.ignore_update_nsm = False
def add_suffix_if_duplicate(account_name, account_number, accounts): def add_suffix_if_duplicate(account_name, account_number, accounts):
if account_number: if account_number:

View File

@ -30,5 +30,5 @@ class AccountsSettings(Document):
def enable_payment_schedule_in_print(self): def enable_payment_schedule_in_print(self):
show_in_print = cint(self.show_payment_schedule_in_print) show_in_print = cint(self.show_payment_schedule_in_print)
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"): for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check") make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check") make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check", validate_fields_for_doctype=False)

View File

@ -31,9 +31,9 @@ class EducationSettings(Document):
def validate(self): def validate(self):
from frappe.custom.doctype.property_setter.property_setter import make_property_setter from frappe.custom.doctype.property_setter.property_setter import make_property_setter
if self.get('instructor_created_by')=='Naming Series': if self.get('instructor_created_by')=='Naming Series':
make_property_setter('Instructor', "naming_series", "hidden", 0, "Check") make_property_setter('Instructor', "naming_series", "hidden", 0, "Check", validate_fields_for_doctype=False)
else: else:
make_property_setter('Instructor', "naming_series", "hidden", 1, "Check") make_property_setter('Instructor', "naming_series", "hidden", 1, "Check", validate_fields_for_doctype=False)
def update_website_context(context): def update_website_context(context):
context["lms_enabled"] = frappe.get_doc("Education Settings").enable_lms context["lms_enabled"] = frappe.get_doc("Education Settings").enable_lms

View File

@ -31,7 +31,8 @@ class Department(NestedSet):
return new return new
def on_update(self): def on_update(self):
NestedSet.on_update(self) if not frappe.local.flags.ignore_update_nsm:
super(Department, self).on_update()
def on_trash(self): def on_trash(self):
super(Department, self).on_trash() super(Department, self).on_trash()

View File

@ -28,5 +28,5 @@ class PayrollSettings(Document):
def toggle_rounded_total(self): def toggle_rounded_total(self):
self.disable_rounded_total = cint(self.disable_rounded_total) self.disable_rounded_total = cint(self.disable_rounded_total)
make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check") make_property_setter("Salary Slip", "rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check") make_property_setter("Salary Slip", "rounded_total", "print_hide", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)

View File

@ -30,8 +30,8 @@ class SellingSettings(Document):
# Make property setters to hide tax_id fields # Make property setters to hide tax_id fields
for doctype in ("Sales Order", "Sales Invoice", "Delivery Note"): for doctype in ("Sales Order", "Sales Invoice", "Delivery Note"):
make_property_setter(doctype, "tax_id", "hidden", self.hide_tax_id, "Check") make_property_setter(doctype, "tax_id", "hidden", self.hide_tax_id, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "tax_id", "print_hide", self.hide_tax_id, "Check") make_property_setter(doctype, "tax_id", "print_hide", self.hide_tax_id, "Check", validate_fields_for_doctype=False)
def set_default_customer_group_and_territory(self): def set_default_customer_group_and_territory(self):
if not self.customer_group: if not self.customer_group:

View File

@ -60,11 +60,11 @@ class GlobalDefaults(Document):
# Make property setters to hide rounded total fields # Make property setters to hide rounded total fields
for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note", for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
"Supplier Quotation", "Purchase Order", "Purchase Invoice"): "Supplier Quotation", "Purchase Order", "Purchase Invoice"):
make_property_setter(doctype, "base_rounded_total", "hidden", self.disable_rounded_total, "Check") make_property_setter(doctype, "base_rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "base_rounded_total", "print_hide", 1, "Check") make_property_setter(doctype, "base_rounded_total", "print_hide", 1, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "rounded_total", "hidden", self.disable_rounded_total, "Check") make_property_setter(doctype, "rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "rounded_total", "print_hide", self.disable_rounded_total, "Check") make_property_setter(doctype, "rounded_total", "print_hide", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
def toggle_in_words(self): def toggle_in_words(self):
self.disable_in_words = cint(self.disable_in_words) self.disable_in_words = cint(self.disable_in_words)
@ -72,5 +72,5 @@ class GlobalDefaults(Document):
# Make property setters to hide in words fields # Make property setters to hide in words fields
for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note", for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
"Supplier Quotation", "Purchase Order", "Purchase Invoice", "Purchase Receipt"): "Supplier Quotation", "Purchase Order", "Purchase Invoice", "Purchase Receipt"):
make_property_setter(doctype, "in_words", "hidden", self.disable_in_words, "Check") make_property_setter(doctype, "in_words", "hidden", self.disable_in_words, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "in_words", "print_hide", self.disable_in_words, "Check") make_property_setter(doctype, "in_words", "print_hide", self.disable_in_words, "Check", validate_fields_for_doctype=False)

View File

@ -183,8 +183,8 @@ class NamingSeries(Document):
def set_by_naming_series(doctype, fieldname, naming_series, hide_name_field=True): def set_by_naming_series(doctype, fieldname, naming_series, hide_name_field=True):
from frappe.custom.doctype.property_setter.property_setter import make_property_setter from frappe.custom.doctype.property_setter.property_setter import make_property_setter
if naming_series: if naming_series:
make_property_setter(doctype, "naming_series", "hidden", 0, "Check") make_property_setter(doctype, "naming_series", "hidden", 0, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "naming_series", "reqd", 1, "Check") make_property_setter(doctype, "naming_series", "reqd", 1, "Check", validate_fields_for_doctype=False)
# set values for mandatory # set values for mandatory
try: try:
@ -195,15 +195,15 @@ def set_by_naming_series(doctype, fieldname, naming_series, hide_name_field=True
pass pass
if hide_name_field: if hide_name_field:
make_property_setter(doctype, fieldname, "reqd", 0, "Check") make_property_setter(doctype, fieldname, "reqd", 0, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, fieldname, "hidden", 1, "Check") make_property_setter(doctype, fieldname, "hidden", 1, "Check", validate_fields_for_doctype=False)
else: else:
make_property_setter(doctype, "naming_series", "reqd", 0, "Check") make_property_setter(doctype, "naming_series", "reqd", 0, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, "naming_series", "hidden", 1, "Check") make_property_setter(doctype, "naming_series", "hidden", 1, "Check", validate_fields_for_doctype=False)
if hide_name_field: if hide_name_field:
make_property_setter(doctype, fieldname, "hidden", 0, "Check") make_property_setter(doctype, fieldname, "hidden", 0, "Check", validate_fields_for_doctype=False)
make_property_setter(doctype, fieldname, "reqd", 1, "Check") make_property_setter(doctype, fieldname, "reqd", 1, "Check", validate_fields_for_doctype=False)
# set values for mandatory # set values for mandatory
frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=`name` where frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=`name` where

View File

@ -12,6 +12,7 @@ from frappe.desk.doctype.global_search_settings.global_search_settings import up
from erpnext.accounts.doctype.account.account import RootNotEditable from erpnext.accounts.doctype.account.account import RootNotEditable
from erpnext.regional.address_template.setup import set_up_address_templates from erpnext.regional.address_template.setup import set_up_address_templates
from frappe.utils.nestedset import rebuild_tree
default_lead_sources = ["Existing Customer", "Reference", "Advertisement", default_lead_sources = ["Existing Customer", "Reference", "Advertisement",
"Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing", "Cold Calling", "Exhibition", "Supplier Reference", "Mass Mailing",
@ -280,13 +281,15 @@ def install(country=None):
set_more_defaults() set_more_defaults()
update_global_search_doctypes() update_global_search_doctypes()
# path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(country))
# if os.path.exists(path.encode("utf-8")):
# frappe.get_attr("erpnext.regional.{0}.setup.setup_company_independent_fixtures".format(frappe.scrub(country)))()
def set_more_defaults(): def set_more_defaults():
# Do more setup stuff that can be done here with no dependencies # Do more setup stuff that can be done here with no dependencies
update_selling_defaults()
update_buying_defaults()
update_hr_defaults()
add_uom_data()
update_item_variant_settings()
def update_selling_defaults():
selling_settings = frappe.get_doc("Selling Settings") selling_settings = frappe.get_doc("Selling Settings")
selling_settings.set_default_customer_group_and_territory() selling_settings.set_default_customer_group_and_territory()
selling_settings.cust_master_name = "Customer Name" selling_settings.cust_master_name = "Customer Name"
@ -296,13 +299,7 @@ def set_more_defaults():
selling_settings.sales_update_frequency = "Each Transaction" selling_settings.sales_update_frequency = "Each Transaction"
selling_settings.save() selling_settings.save()
add_uom_data() def update_buying_defaults():
# set no copy fields of an item doctype to item variant settings
doc = frappe.get_doc('Item Variant Settings')
doc.set_default_fields()
doc.save()
buying_settings = frappe.get_doc("Buying Settings") buying_settings = frappe.get_doc("Buying Settings")
buying_settings.supp_master_name = "Supplier Name" buying_settings.supp_master_name = "Supplier Name"
buying_settings.po_required = "No" buying_settings.po_required = "No"
@ -311,12 +308,19 @@ def set_more_defaults():
buying_settings.allow_multiple_items = 1 buying_settings.allow_multiple_items = 1
buying_settings.save() buying_settings.save()
def update_hr_defaults():
hr_settings = frappe.get_doc("HR Settings") hr_settings = frappe.get_doc("HR Settings")
hr_settings.emp_created_by = "Naming Series" hr_settings.emp_created_by = "Naming Series"
hr_settings.leave_approval_notification_template = _("Leave Approval Notification") hr_settings.leave_approval_notification_template = _("Leave Approval Notification")
hr_settings.leave_status_notification_template = _("Leave Status Notification") hr_settings.leave_status_notification_template = _("Leave Status Notification")
hr_settings.save() hr_settings.save()
def update_item_variant_settings():
# set no copy fields of an item doctype to item variant settings
doc = frappe.get_doc('Item Variant Settings')
doc.set_default_fields()
doc.save()
def add_uom_data(): def add_uom_data():
# add UOMs # add UOMs
uoms = json.loads(open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_data.json")).read()) uoms = json.loads(open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_data.json")).read())
@ -327,7 +331,7 @@ def add_uom_data():
"uom_name": _(d.get("uom_name")), "uom_name": _(d.get("uom_name")),
"name": _(d.get("uom_name")), "name": _(d.get("uom_name")),
"must_be_whole_number": d.get("must_be_whole_number") "must_be_whole_number": d.get("must_be_whole_number")
}).insert(ignore_permissions=True) }).db_insert()
# bootstrap uom conversion factors # bootstrap uom conversion factors
uom_conversions = json.loads(open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_conversion_data.json")).read()) uom_conversions = json.loads(open(frappe.get_app_path("erpnext", "setup", "setup_wizard", "data", "uom_conversion_data.json")).read())
@ -336,7 +340,7 @@ def add_uom_data():
frappe.get_doc({ frappe.get_doc({
"doctype": "UOM Category", "doctype": "UOM Category",
"category_name": _(d.get("category")) "category_name": _(d.get("category"))
}).insert(ignore_permissions=True) }).db_insert()
if not frappe.db.exists("UOM Conversion Factor", {"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))}): if not frappe.db.exists("UOM Conversion Factor", {"from_uom": _(d.get("from_uom")), "to_uom": _(d.get("to_uom"))}):
uom_conversion = frappe.get_doc({ uom_conversion = frappe.get_doc({
@ -369,8 +373,8 @@ def add_sale_stages():
{"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")}, {"doctype": "Sales Stage", "stage_name": _("Proposal/Price Quote")},
{"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")} {"doctype": "Sales Stage", "stage_name": _("Negotiation/Review")}
] ]
for sales_stage in records:
make_records(records) frappe.get_doc(sales_stage).db_insert()
def install_company(args): def install_company(args):
records = [ records = [
@ -418,7 +422,14 @@ def install_post_company_fixtures(args=None):
{'doctype': 'Department', 'department_name': _('Legal'), 'parent_department': _('All Departments'), 'company': args.company_name}, {'doctype': 'Department', 'department_name': _('Legal'), 'parent_department': _('All Departments'), 'company': args.company_name},
] ]
make_records(records) # Make root department with NSM updation
make_records(records[:1])
frappe.local.flags.ignore_update_nsm = True
make_records(records[1:])
frappe.local.flags.ignore_update_nsm = False
rebuild_tree("Department", "parent_department")
def install_defaults(args=None): def install_defaults(args=None):
@ -432,7 +443,15 @@ def install_defaults(args=None):
# enable default currency # enable default currency
frappe.db.set_value("Currency", args.get("currency"), "enabled", 1) frappe.db.set_value("Currency", args.get("currency"), "enabled", 1)
frappe.db.set_value("Stock Settings", None, "email_footer_address", args.get("company_name"))
set_global_defaults(args)
set_active_domains(args)
update_stock_settings()
update_shopping_cart_settings(args)
create_bank_account(args)
def set_global_defaults(args):
global_defaults = frappe.get_doc("Global Defaults", "Global Defaults") global_defaults = frappe.get_doc("Global Defaults", "Global Defaults")
current_fiscal_year = frappe.get_all("Fiscal Year")[0] current_fiscal_year = frappe.get_all("Fiscal Year")[0]
@ -445,13 +464,10 @@ def install_defaults(args=None):
global_defaults.save() global_defaults.save()
system_settings = frappe.get_doc("System Settings") def set_active_domains(args):
system_settings.email_footer_address = args.get("company_name") frappe.get_single('Domain Settings').set_active_domains(args.get('domains'))
system_settings.save()
domain_settings = frappe.get_single('Domain Settings')
domain_settings.set_active_domains(args.get('domains'))
def update_stock_settings():
stock_settings = frappe.get_doc("Stock Settings") stock_settings = frappe.get_doc("Stock Settings")
stock_settings.item_naming_by = "Item Code" stock_settings.item_naming_by = "Item Code"
stock_settings.valuation_method = "FIFO" stock_settings.valuation_method = "FIFO"
@ -463,7 +479,10 @@ def install_defaults(args=None):
stock_settings.set_qty_in_transactions_based_on_serial_no_input = 1 stock_settings.set_qty_in_transactions_based_on_serial_no_input = 1
stock_settings.save() stock_settings.save()
if args.bank_account: def create_bank_account(args):
if not args.bank_account:
return
company_name = args.company_name company_name = args.company_name
bank_account_group = frappe.db.get_value("Account", bank_account_group = frappe.db.get_value("Account",
{"account_type": "Bank", "is_group": 1, "root_type": "Asset", {"account_type": "Bank", "is_group": 1, "root_type": "Asset",
@ -488,23 +507,16 @@ def install_defaults(args=None):
# bank account same as a CoA entry # bank account same as a CoA entry
pass pass
# Now, with fixtures out of the way, onto concrete stuff def update_shopping_cart_settings(args):
records = [ shopping_cart = frappe.get_doc("Shopping Cart Settings")
shopping_cart.update({
# Shopping cart: needs price lists
{
"doctype": "Shopping Cart Settings",
"enabled": 1, "enabled": 1,
'company': args.company_name, 'company': args.company_name,
# uh oh
'price_list': frappe.db.get_value("Price List", {"selling": 1}), 'price_list': frappe.db.get_value("Price List", {"selling": 1}),
'default_customer_group': _("Individual"), 'default_customer_group': _("Individual"),
'quotation_series': "QTN-", 'quotation_series': "QTN-",
}, })
] shopping_cart.update_single(shopping_cart.get_valid_dict())
make_records(records)
def get_fy_details(fy_start_date, fy_end_date): def get_fy_details(fy_start_date, fy_end_date):
start_year = getdate(fy_start_date).year start_year = getdate(fy_start_date).year

View File

@ -51,11 +51,6 @@ def get_setup_stages(args=None):
'status': _('Setting defaults'), 'status': _('Setting defaults'),
'fail_msg': 'Failed to set defaults', 'fail_msg': 'Failed to set defaults',
'tasks': [ 'tasks': [
{
'fn': setup_post_company_fixtures,
'args': args,
'fail_msg': _("Failed to setup post company fixtures")
},
{ {
'fn': setup_defaults, 'fn': setup_defaults,
'args': args, 'args': args,
@ -94,9 +89,6 @@ def stage_fixtures(args):
def setup_company(args): def setup_company(args):
fixtures.install_company(args) fixtures.install_company(args)
def setup_post_company_fixtures(args):
fixtures.install_post_company_fixtures(args)
def setup_defaults(args): def setup_defaults(args):
fixtures.install_defaults(frappe._dict(args)) fixtures.install_defaults(frappe._dict(args))
@ -129,7 +121,6 @@ def login_as_first_user(args):
def setup_complete(args=None): def setup_complete(args=None):
stage_fixtures(args) stage_fixtures(args)
setup_company(args) setup_company(args)
setup_post_company_fixtures(args)
setup_defaults(args) setup_defaults(args)
stage_four(args) stage_four(args)
fin(args) fin(args)

View File

@ -30,7 +30,7 @@ class StockSettings(Document):
# show/hide barcode field # show/hide barcode field
for name in ["barcode", "barcodes", "scan_barcode"]: for name in ["barcode", "barcodes", "scan_barcode"]:
frappe.make_property_setter({'fieldname': name, 'property': 'hidden', frappe.make_property_setter({'fieldname': name, 'property': 'hidden',
'value': 0 if self.show_barcode_field else 1}) 'value': 0 if self.show_barcode_field else 1}, validate_fields_for_doctype=False)
self.validate_warehouses() self.validate_warehouses()
self.cant_change_valuation_method() self.cant_change_valuation_method()
@ -67,10 +67,10 @@ class StockSettings(Document):
self.toggle_warehouse_field_for_inter_warehouse_transfer() self.toggle_warehouse_field_for_inter_warehouse_transfer()
def toggle_warehouse_field_for_inter_warehouse_transfer(self): def toggle_warehouse_field_for_inter_warehouse_transfer(self):
make_property_setter("Sales Invoice Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check") make_property_setter("Sales Invoice Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check", validate_fields_for_doctype=False)
make_property_setter("Delivery Note Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check") make_property_setter("Delivery Note Item", "target_warehouse", "hidden", 1 - cint(self.allow_from_dn), "Check", validate_fields_for_doctype=False)
make_property_setter("Purchase Invoice Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check") make_property_setter("Purchase Invoice Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check", validate_fields_for_doctype=False)
make_property_setter("Purchase Receipt Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check") make_property_setter("Purchase Receipt Item", "from_warehouse", "hidden", 1 - cint(self.allow_from_pr), "Check", validate_fields_for_doctype=False)
def clean_all_descriptions(): def clean_all_descriptions():