mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-19 06:45:11 +00:00
Merge pull request #47327 from frappe/version-14-hotfix
chore: release v14
This commit is contained in:
@@ -635,38 +635,44 @@ class Asset(AccountsController):
|
||||
return add_days(self.available_for_use_date, -1)
|
||||
|
||||
# if it returns True, depreciation_amount will not be equal for the first and last rows
|
||||
def check_is_pro_rata(self, row, wdv_or_dd_non_yearly=False):
|
||||
def check_is_pro_rata(asset_doc, row, wdv_or_dd_non_yearly=False):
|
||||
has_pro_rata = False
|
||||
|
||||
# if not existing asset, from_date = available_for_use_date
|
||||
# otherwise, if number_of_depreciations_booked = 2, available_for_use_date = 01/01/2020 and frequency_of_depreciation = 12
|
||||
# from_date = 01/01/2022
|
||||
from_date = self.get_modified_available_for_use_date(row, wdv_or_dd_non_yearly)
|
||||
days = date_diff(row.depreciation_start_date, from_date) + 1
|
||||
|
||||
if wdv_or_dd_non_yearly:
|
||||
total_days = get_total_days(row.depreciation_start_date, 12)
|
||||
if row.depreciation_method in ("Straight Line", "Manual"):
|
||||
prev_depreciation_start_date = get_last_day(
|
||||
add_months(
|
||||
row.depreciation_start_date,
|
||||
(row.frequency_of_depreciation * -1) * asset_doc.number_of_depreciations_booked,
|
||||
)
|
||||
)
|
||||
from_date = asset_doc.available_for_use_date
|
||||
days = date_diff(prev_depreciation_start_date, from_date) + 1
|
||||
total_days = get_total_days(prev_depreciation_start_date, row.frequency_of_depreciation)
|
||||
else:
|
||||
# if frequency_of_depreciation is 12 months, total_days = 365
|
||||
from_date = _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False)
|
||||
days = date_diff(row.depreciation_start_date, from_date) + 1
|
||||
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
|
||||
|
||||
if days <= 0:
|
||||
frappe.throw(
|
||||
_(
|
||||
"""Error: This asset already has {0} depreciation periods booked.
|
||||
The `depreciation start` date must be at least {1} periods after the `available for use` date.
|
||||
Please correct the dates accordingly."""
|
||||
).format(
|
||||
asset_doc.number_of_depreciations_booked,
|
||||
asset_doc.number_of_depreciations_booked,
|
||||
)
|
||||
)
|
||||
|
||||
if days < total_days:
|
||||
has_pro_rata = True
|
||||
|
||||
return has_pro_rata
|
||||
|
||||
def get_modified_available_for_use_date(self, row, wdv_or_dd_non_yearly=False):
|
||||
if wdv_or_dd_non_yearly:
|
||||
return add_months(
|
||||
self.available_for_use_date,
|
||||
(self.number_of_depreciations_booked * 12),
|
||||
)
|
||||
else:
|
||||
return add_months(
|
||||
self.available_for_use_date,
|
||||
(self.number_of_depreciations_booked * row.frequency_of_depreciation),
|
||||
)
|
||||
|
||||
def validate_asset_finance_books(self, row):
|
||||
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
|
||||
frappe.throw(
|
||||
@@ -1290,6 +1296,28 @@ def get_item_details(item_code, asset_category, gross_purchase_amount):
|
||||
return books
|
||||
|
||||
|
||||
def _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False):
|
||||
"""
|
||||
if Asset has opening booked depreciations = 9,
|
||||
available for use date = 17-07-2023,
|
||||
depreciation start date = 30-04-2024
|
||||
then from date should be 01-04-2024
|
||||
"""
|
||||
if asset_doc.number_of_depreciations_booked > 0:
|
||||
from_date = add_months(
|
||||
asset_doc.available_for_use_date,
|
||||
(asset_doc.number_of_depreciations_booked * row.frequency_of_depreciation) - 1,
|
||||
)
|
||||
if is_last_day_of_the_month(row.depreciation_start_date):
|
||||
return add_days(get_last_day(from_date), 1)
|
||||
|
||||
# get from date when depreciation start date is not last day of the month
|
||||
months_difference = month_diff(row.depreciation_start_date, from_date) - 1
|
||||
return add_days(add_months(row.depreciation_start_date, -1 * months_difference), 1)
|
||||
else:
|
||||
return asset_doc.available_for_use_date
|
||||
|
||||
|
||||
def get_asset_account(account_name, asset=None, asset_category=None, company=None):
|
||||
account = None
|
||||
if asset:
|
||||
|
||||
@@ -1451,7 +1451,7 @@ class TestDepreciationBasics(AssetSetup):
|
||||
affects `value_after_depreciation`
|
||||
"""
|
||||
|
||||
asset = create_asset(calculate_depreciation=1)
|
||||
asset = create_asset(calculate_depreciation=1, depreciation_start_date="2021-12-31")
|
||||
asset.opening_accumulated_depreciation = 2000
|
||||
asset.number_of_depreciations_booked = 1
|
||||
|
||||
|
||||
@@ -241,8 +241,6 @@ def install(country=None):
|
||||
{"doctype": "Issue Priority", "name": _("Low")},
|
||||
{"doctype": "Issue Priority", "name": _("Medium")},
|
||||
{"doctype": "Issue Priority", "name": _("High")},
|
||||
{"doctype": "Email Account", "email_id": "sales@example.com", "append_to": "Opportunity"},
|
||||
{"doctype": "Email Account", "email_id": "support@example.com", "append_to": "Issue"},
|
||||
{"doctype": "Party Type", "party_type": "Customer", "account_type": "Receivable"},
|
||||
{"doctype": "Party Type", "party_type": "Supplier", "account_type": "Payable"},
|
||||
{"doctype": "Party Type", "party_type": "Employee", "account_type": "Payable"},
|
||||
|
||||
@@ -916,6 +916,11 @@ class Item(Document):
|
||||
changed_fields = [
|
||||
field for field in restricted_fields if cstr(self.get(field)) != cstr(values.get(field))
|
||||
]
|
||||
|
||||
# Allow to change valuation method from FIFO to Moving Average not vice versa
|
||||
if self.valuation_method == "Moving Average" and "valuation_method" in changed_fields:
|
||||
changed_fields.remove("valuation_method")
|
||||
|
||||
if not changed_fields:
|
||||
return
|
||||
|
||||
|
||||
@@ -1194,16 +1194,16 @@ class update_entries_after:
|
||||
) in frappe.local.flags.currently_saving:
|
||||
msg = _("{0} units of {1} needed in {2} to complete this transaction.").format(
|
||||
abs(deficiency),
|
||||
frappe.get_desk_link("Item", exceptions[0]["item_code"]),
|
||||
frappe.get_desk_link("Warehouse", warehouse),
|
||||
frappe.get_desk_link("Item", exceptions[0]["item_code"], show_title_with_name=True),
|
||||
frappe.get_desk_link("Warehouse", warehouse, show_title_with_name=True),
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
"{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
|
||||
).format(
|
||||
abs(deficiency),
|
||||
frappe.get_desk_link("Item", exceptions[0]["item_code"]),
|
||||
frappe.get_desk_link("Warehouse", warehouse),
|
||||
frappe.get_desk_link("Item", exceptions[0]["item_code"], show_title_with_name=True),
|
||||
frappe.get_desk_link("Warehouse", warehouse, show_title_with_name=True),
|
||||
exceptions[0]["posting_date"],
|
||||
exceptions[0]["posting_time"],
|
||||
frappe.get_desk_link(exceptions[0]["voucher_type"], exceptions[0]["voucher_no"]),
|
||||
@@ -1664,8 +1664,8 @@ def validate_negative_qty_in_future_sle(args, allow_negative_stock=False):
|
||||
if is_negative_with_precision(neg_sle):
|
||||
message = _("{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction.").format(
|
||||
abs(neg_sle[0]["qty_after_transaction"]),
|
||||
frappe.get_desk_link("Item", args.item_code),
|
||||
frappe.get_desk_link("Warehouse", args.warehouse),
|
||||
frappe.get_desk_link("Item", args.item_code, show_title_with_name=True),
|
||||
frappe.get_desk_link("Warehouse", args.warehouse, show_title_with_name=True),
|
||||
neg_sle[0]["posting_date"],
|
||||
neg_sle[0]["posting_time"],
|
||||
frappe.get_desk_link(neg_sle[0]["voucher_type"], neg_sle[0]["voucher_no"]),
|
||||
|
||||
Reference in New Issue
Block a user