mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-28 22:28:24 +00:00
Merge branch 'develop' of https://github.com/frappe/erpnext into internal_transfer_precision_fixes
This commit is contained in:
@@ -38,7 +38,6 @@ from erpnext.accounts.party import (
|
||||
validate_party_frozen_disabled,
|
||||
)
|
||||
from erpnext.accounts.utils import get_account_currency, get_fiscal_years, validate_fiscal_year
|
||||
from erpnext.assets.doctype.asset.depreciation import make_depreciation_entry
|
||||
from erpnext.buying.utils import update_last_purchase_rate
|
||||
from erpnext.controllers.print_settings import (
|
||||
set_print_templates_for_item_table,
|
||||
@@ -1891,88 +1890,6 @@ class AccountsController(TransactionBase):
|
||||
_("Select finance book for the item {0} at row {1}").format(item.item_code, item.idx)
|
||||
)
|
||||
|
||||
def depreciate_asset(self, asset):
|
||||
asset.flags.ignore_validate_update_after_submit = True
|
||||
asset.prepare_depreciation_data(date_of_disposal=self.posting_date)
|
||||
asset.save()
|
||||
|
||||
make_depreciation_entry(asset.name, self.posting_date)
|
||||
|
||||
def reset_depreciation_schedule(self, asset):
|
||||
asset.flags.ignore_validate_update_after_submit = True
|
||||
|
||||
# recreate original depreciation schedule of the asset
|
||||
asset.prepare_depreciation_data(date_of_return=self.posting_date)
|
||||
|
||||
self.modify_depreciation_schedule_for_asset_repairs(asset)
|
||||
asset.save()
|
||||
|
||||
def modify_depreciation_schedule_for_asset_repairs(self, asset):
|
||||
asset_repairs = frappe.get_all(
|
||||
"Asset Repair", filters={"asset": asset.name}, fields=["name", "increase_in_asset_life"]
|
||||
)
|
||||
|
||||
for repair in asset_repairs:
|
||||
if repair.increase_in_asset_life:
|
||||
asset_repair = frappe.get_doc("Asset Repair", repair.name)
|
||||
asset_repair.modify_depreciation_schedule()
|
||||
asset.prepare_depreciation_data()
|
||||
|
||||
def reverse_depreciation_entry_made_after_disposal(self, asset):
|
||||
from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
|
||||
|
||||
posting_date_of_original_disposal = self.get_posting_date_of_disposal_entry()
|
||||
|
||||
row = -1
|
||||
finance_book = asset.get("schedules")[0].get("finance_book")
|
||||
for schedule in asset.get("schedules"):
|
||||
if schedule.finance_book != finance_book:
|
||||
row = 0
|
||||
finance_book = schedule.finance_book
|
||||
else:
|
||||
row += 1
|
||||
|
||||
if schedule.schedule_date == posting_date_of_original_disposal:
|
||||
if not self.disposal_was_made_on_original_schedule_date(
|
||||
asset, schedule, row, posting_date_of_original_disposal
|
||||
) or self.disposal_happens_in_the_future(posting_date_of_original_disposal):
|
||||
|
||||
reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry)
|
||||
reverse_journal_entry.posting_date = nowdate()
|
||||
frappe.flags.is_reverse_depr_entry = True
|
||||
reverse_journal_entry.submit()
|
||||
|
||||
frappe.flags.is_reverse_depr_entry = False
|
||||
asset.flags.ignore_validate_update_after_submit = True
|
||||
schedule.journal_entry = None
|
||||
asset.save()
|
||||
|
||||
def get_posting_date_of_disposal_entry(self):
|
||||
if self.doctype == "Sales Invoice" and self.return_against:
|
||||
return frappe.db.get_value("Sales Invoice", self.return_against, "posting_date")
|
||||
else:
|
||||
return self.posting_date
|
||||
|
||||
# if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone
|
||||
def disposal_was_made_on_original_schedule_date(
|
||||
self, asset, schedule, row, posting_date_of_disposal
|
||||
):
|
||||
for finance_book in asset.get("finance_books"):
|
||||
if schedule.finance_book == finance_book.finance_book:
|
||||
orginal_schedule_date = add_months(
|
||||
finance_book.depreciation_start_date, row * cint(finance_book.frequency_of_depreciation)
|
||||
)
|
||||
|
||||
if orginal_schedule_date == posting_date_of_disposal:
|
||||
return True
|
||||
return False
|
||||
|
||||
def disposal_happens_in_the_future(self, posting_date_of_disposal):
|
||||
if posting_date_of_disposal > getdate():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_tax_rate(account_head):
|
||||
|
||||
@@ -212,21 +212,15 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
||||
meta = frappe.get_meta(doctype, cached=True)
|
||||
searchfields = meta.get_search_fields()
|
||||
|
||||
# these are handled separately
|
||||
ignored_search_fields = ("item_name", "description")
|
||||
for ignored_field in ignored_search_fields:
|
||||
if ignored_field in searchfields:
|
||||
searchfields.remove(ignored_field)
|
||||
|
||||
columns = ""
|
||||
extra_searchfields = [
|
||||
field
|
||||
for field in searchfields
|
||||
if not field in ["name", "item_group", "description", "item_name"]
|
||||
]
|
||||
extra_searchfields = [field for field in searchfields if not field in ["name", "description"]]
|
||||
|
||||
if extra_searchfields:
|
||||
columns = ", " + ", ".join(extra_searchfields)
|
||||
columns += ", " + ", ".join(extra_searchfields)
|
||||
|
||||
if "description" in searchfields:
|
||||
columns += """, if(length(tabItem.description) > 40, \
|
||||
concat(substr(tabItem.description, 1, 40), "..."), description) as description"""
|
||||
|
||||
searchfields = searchfields + [
|
||||
field
|
||||
@@ -266,12 +260,10 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
|
||||
if frappe.db.count(doctype, cache=True) < 50000:
|
||||
# scan description only if items are less than 50000
|
||||
description_cond = "or tabItem.description LIKE %(txt)s"
|
||||
|
||||
return frappe.db.sql(
|
||||
"""select
|
||||
tabItem.name, tabItem.item_name, tabItem.item_group,
|
||||
if(length(tabItem.description) > 40, \
|
||||
concat(substr(tabItem.description, 1, 40), "..."), description) as description
|
||||
{columns}
|
||||
tabItem.name {columns}
|
||||
from tabItem
|
||||
where tabItem.docstatus < 2
|
||||
and tabItem.disabled=0
|
||||
|
||||
@@ -69,9 +69,18 @@ class SubcontractingController(StockController):
|
||||
|
||||
def validate_items(self):
|
||||
for item in self.items:
|
||||
if not frappe.get_value("Item", item.item_code, "is_sub_contracted_item"):
|
||||
is_stock_item, is_sub_contracted_item = frappe.get_value(
|
||||
"Item", item.item_code, ["is_stock_item", "is_sub_contracted_item"]
|
||||
)
|
||||
|
||||
if not is_stock_item:
|
||||
msg = f"Item {item.item_name} must be a stock item."
|
||||
frappe.throw(_(msg))
|
||||
|
||||
if not is_sub_contracted_item:
|
||||
msg = f"Item {item.item_name} must be a subcontracted item."
|
||||
frappe.throw(_(msg))
|
||||
|
||||
if item.bom:
|
||||
bom = frappe.get_doc("BOM", item.bom)
|
||||
if not bom.is_active:
|
||||
@@ -841,7 +850,7 @@ def make_rm_stock_entry(
|
||||
for fg_item_code in fg_item_code_list:
|
||||
for rm_item in rm_items:
|
||||
|
||||
if rm_item.get("main_item_code") or rm_item.get("item_code") == fg_item_code:
|
||||
if rm_item.get("main_item_code") == fg_item_code or rm_item.get("item_code") == fg_item_code:
|
||||
rm_item_code = rm_item.get("rm_item_code")
|
||||
|
||||
items_dict = {
|
||||
|
||||
Reference in New Issue
Block a user