# [15.10.0](https://github.com/frappe/erpnext/compare/v15.9.1...v15.10.0) (2024-01-10) ### Bug Fixes * add expected_start_date in sort by ([b064944](b064944753
)) * Add name to Hungary - Chart of Accounts for Microenterprises json ([0784488](0784488eec
)) * add read permission to Buying Settings ([e62dd0d](e62dd0d7cb
)) * bank transction status upon reconciliation ([277aa7b](277aa7bc2b
)) * BOM replace tool does not update exploded items of root (backport [#39244](https://github.com/frappe/erpnext/issues/39244)) ([#39250](https://github.com/frappe/erpnext/issues/39250)) ([0898ea5](0898ea5d92
)) * Creating Asset Activity while Importing Asset ([#39113](https://github.com/frappe/erpnext/issues/39113)) ([5e46937](5e4693763a
)) * don't set rate for non-stock item in Internal Transfer (backport [#39140](https://github.com/frappe/erpnext/issues/39140)) ([#39169](https://github.com/frappe/erpnext/issues/39169)) ([f3882a8](f3882a854f
)) * Duplicate Closing Stock Balance (backport [#39262](https://github.com/frappe/erpnext/issues/39262)) ([#39264](https://github.com/frappe/erpnext/issues/39264)) ([78c65f2](78c65f27b0
)) * duplicate entry for serial / batch creation (backport [#39188](https://github.com/frappe/erpnext/issues/39188)) ([#39192](https://github.com/frappe/erpnext/issues/39192)) ([672e6d6](672e6d6d06
)) * **Employee:** treeview ([#39126](https://github.com/frappe/erpnext/issues/39126)) ([6020c8e](6020c8e8f7
)) * FG Item incorrect qty in the work order (backport [#39200](https://github.com/frappe/erpnext/issues/39200)) ([#39211](https://github.com/frappe/erpnext/issues/39211)) ([abc99f8](abc99f84e9
)) * flaky demo test case (backport [#39135](https://github.com/frappe/erpnext/issues/39135)) ([#39198](https://github.com/frappe/erpnext/issues/39198)) ([3caf462](3caf462c6b
)) * Ignore asset qty and status validation while cancelling LCV ([87d1b0f](87d1b0f476
)) * ignore cancelled payments in Sales/Purchase Register ([9e1b443](9e1b443857
)) * Ignore UP on "allowed to transact with" ([#39103](https://github.com/frappe/erpnext/issues/39103)) ([aad39cf](aad39cf686
)) * improved validation message ([e89dce7](e89dce726b
)) * incorrect indicator title for portal sales order (backport [#39247](https://github.com/frappe/erpnext/issues/39247)) ([#39255](https://github.com/frappe/erpnext/issues/39255)) ([9f793b9](9f793b9b28
)) * incorrect outstanding amt validation on advance as liability ([51d8a7a](51d8a7a0c1
)) * Introduced company field to show amounts in company currency ([1d2e831](1d2e831846
)) * inventory dimension negative stock validation (backport [#39149](https://github.com/frappe/erpnext/issues/39149)) ([#39151](https://github.com/frappe/erpnext/issues/39151)) ([82b96d3](82b96d3688
)) * possible key error on Financial ratios report ([16269b0](16269b0730
)) * possible typeerror on transaction.js ([fec892c](fec892c211
)) * projects website list visible for guests and all logged in customers (backport [#39164](https://github.com/frappe/erpnext/issues/39164)) ([#39273](https://github.com/frappe/erpnext/issues/39273)) ([5d6bc96](5d6bc96375
)), closes [#39009](https://github.com/frappe/erpnext/issues/39009) * Purchase date and amount is not mandatory for composite asset creation ([d6d54ed](d6d54ed220
)) * Resolved conflict ([afefae0](afefae08af
)) * serial / batch barcode scanner (backport [#39114](https://github.com/frappe/erpnext/issues/39114)) ([#39143](https://github.com/frappe/erpnext/issues/39143)) ([2db1e1a](2db1e1a737
)) * Set asset purchase amount based on qty and valuation_rate ([f0070b4](f0070b4046
)) * set parent doctype on chart (backport [#39286](https://github.com/frappe/erpnext/issues/39286)) ([#39288](https://github.com/frappe/erpnext/issues/39288)) ([fe973a4](fe973a4b53
)) * Show maintain-stock and is-fixed-asset checkbox in item quick entry dialog ([50300b9](50300b9be6
)) * Show timesheet table after fetching data from timesheet (backport [#39275](https://github.com/frappe/erpnext/issues/39275)) ([#39281](https://github.com/frappe/erpnext/issues/39281)) ([2598f8e](2598f8e7ec
)) * skip rate validation for return `DN Items` with `Moving Average` valuation (backport [#39242](https://github.com/frappe/erpnext/issues/39242)) ([#39266](https://github.com/frappe/erpnext/issues/39266)) ([f00a6f6](f00a6f6c59
)) * Subscription update patch ([7640fea](7640feaaa7
)) * total allocated percentage for sales team issue ([756c062](756c062733
)) * TypeError is pricing rules (backport [#39252](https://github.com/frappe/erpnext/issues/39252)) ([#39260](https://github.com/frappe/erpnext/issues/39260)) ([bb6025c](bb6025ca26
)) * typerror on multi select dialog ([54a0df5](54a0df5164
)) * update Maintenance Schedule status on Maintenance Visit submit (backport [#39167](https://github.com/frappe/erpnext/issues/39167)) ([#39186](https://github.com/frappe/erpnext/issues/39186)) ([926850d](926850d1f6
)) * update status on manual allocation ([a147e29](a147e2954f
)) * **UX:** dont override framework's permission check messages (backport [#39118](https://github.com/frappe/erpnext/issues/39118)) ([#39120](https://github.com/frappe/erpnext/issues/39120)) ([40ec5ff](40ec5ff90f
)) ### Features * provision to close SCO (backport [#39127](https://github.com/frappe/erpnext/issues/39127)) ([#39144](https://github.com/frappe/erpnext/issues/39144)) ([b192ddd](b192ddd13b
))
154 lines
4.2 KiB
Python
154 lines
4.2 KiB
Python
import functools
|
|
import inspect
|
|
|
|
import frappe
|
|
|
|
__version__ = "15.10.0"
|
|
|
|
|
|
def get_default_company(user=None):
|
|
"""Get default company for user"""
|
|
from frappe.defaults import get_user_default_as_list
|
|
|
|
if not user:
|
|
user = frappe.session.user
|
|
|
|
companies = get_user_default_as_list(user, "company")
|
|
if companies:
|
|
default_company = companies[0]
|
|
else:
|
|
default_company = frappe.db.get_single_value("Global Defaults", "default_company")
|
|
|
|
return default_company
|
|
|
|
|
|
def get_default_currency():
|
|
"""Returns the currency of the default company"""
|
|
company = get_default_company()
|
|
if company:
|
|
return frappe.get_cached_value("Company", company, "default_currency")
|
|
|
|
|
|
def get_default_cost_center(company):
|
|
"""Returns the default cost center of the company"""
|
|
if not company:
|
|
return None
|
|
|
|
if not frappe.flags.company_cost_center:
|
|
frappe.flags.company_cost_center = {}
|
|
if not company in frappe.flags.company_cost_center:
|
|
frappe.flags.company_cost_center[company] = frappe.get_cached_value(
|
|
"Company", company, "cost_center"
|
|
)
|
|
return frappe.flags.company_cost_center[company]
|
|
|
|
|
|
def get_company_currency(company):
|
|
"""Returns the default company currency"""
|
|
if not frappe.flags.company_currency:
|
|
frappe.flags.company_currency = {}
|
|
if not company in frappe.flags.company_currency:
|
|
frappe.flags.company_currency[company] = frappe.db.get_value(
|
|
"Company", company, "default_currency", cache=True
|
|
)
|
|
return frappe.flags.company_currency[company]
|
|
|
|
|
|
def set_perpetual_inventory(enable=1, company=None):
|
|
if not company:
|
|
company = "_Test Company" if frappe.flags.in_test else get_default_company()
|
|
|
|
company = frappe.get_doc("Company", company)
|
|
company.enable_perpetual_inventory = enable
|
|
company.save()
|
|
|
|
|
|
def encode_company_abbr(name, company=None, abbr=None):
|
|
"""Returns name encoded with company abbreviation"""
|
|
company_abbr = abbr or frappe.get_cached_value("Company", company, "abbr")
|
|
parts = name.rsplit(" - ", 1)
|
|
|
|
if parts[-1].lower() != company_abbr.lower():
|
|
parts.append(company_abbr)
|
|
|
|
return " - ".join(parts)
|
|
|
|
|
|
def is_perpetual_inventory_enabled(company):
|
|
if not company:
|
|
company = "_Test Company" if frappe.flags.in_test else get_default_company()
|
|
|
|
if not hasattr(frappe.local, "enable_perpetual_inventory"):
|
|
frappe.local.enable_perpetual_inventory = {}
|
|
|
|
if not company in frappe.local.enable_perpetual_inventory:
|
|
frappe.local.enable_perpetual_inventory[company] = (
|
|
frappe.get_cached_value("Company", company, "enable_perpetual_inventory") or 0
|
|
)
|
|
|
|
return frappe.local.enable_perpetual_inventory[company]
|
|
|
|
|
|
def get_default_finance_book(company=None):
|
|
if not company:
|
|
company = get_default_company()
|
|
|
|
if not hasattr(frappe.local, "default_finance_book"):
|
|
frappe.local.default_finance_book = {}
|
|
|
|
if not company in frappe.local.default_finance_book:
|
|
frappe.local.default_finance_book[company] = frappe.get_cached_value(
|
|
"Company", company, "default_finance_book"
|
|
)
|
|
|
|
return frappe.local.default_finance_book[company]
|
|
|
|
|
|
def get_party_account_type(party_type):
|
|
if not hasattr(frappe.local, "party_account_types"):
|
|
frappe.local.party_account_types = {}
|
|
|
|
if not party_type in frappe.local.party_account_types:
|
|
frappe.local.party_account_types[party_type] = (
|
|
frappe.db.get_value("Party Type", party_type, "account_type") or ""
|
|
)
|
|
|
|
return frappe.local.party_account_types[party_type]
|
|
|
|
|
|
def get_region(company=None):
|
|
"""Return the default country based on flag, company or global settings
|
|
|
|
You can also set global company flag in `frappe.flags.company`
|
|
"""
|
|
|
|
if not company:
|
|
company = frappe.local.flags.company
|
|
|
|
if company:
|
|
return frappe.get_cached_value("Company", company, "country")
|
|
|
|
return frappe.flags.country or frappe.get_system_settings("country")
|
|
|
|
|
|
def allow_regional(fn):
|
|
"""Decorator to make a function regionally overridable
|
|
|
|
Example:
|
|
@erpnext.allow_regional
|
|
def myfunction():
|
|
pass"""
|
|
|
|
@functools.wraps(fn)
|
|
def caller(*args, **kwargs):
|
|
overrides = frappe.get_hooks("regional_overrides", {}).get(get_region())
|
|
function_path = f"{inspect.getmodule(fn).__name__}.{fn.__name__}"
|
|
|
|
if not overrides or function_path not in overrides:
|
|
return fn(*args, **kwargs)
|
|
|
|
# Priority given to last installed app
|
|
return frappe.get_attr(overrides[function_path][-1])(*args, **kwargs)
|
|
|
|
return caller
|