diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js index c3531420ce1..40f0938ee1c 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -19,7 +19,7 @@ frappe.ui.form.on("Currency Exchange Settings", { to: "{to_currency}", }; add_param(frm, r.message, params, result); - } else if (frm.doc.service_provider == "frankfurter.dev") { + } else if (["frankfurter.app", "frankfurter.dev"].includes(frm.doc.service_provider)) { let result = ["rates", "{to_currency}"]; let params = { base: "{from_currency}", diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py index b36952ab4ff..d10c2947f2d 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -35,7 +35,7 @@ class CurrencyExchangeSettings(Document): self.append("req_params", {"key": "date", "value": "{transaction_date}"}) self.append("req_params", {"key": "from", "value": "{from_currency}"}) self.append("req_params", {"key": "to", "value": "{to_currency}"}) - elif self.service_provider == "frankfurter.dev": + elif self.service_provider in ("frankfurter.dev", "frankfurter.app"): self.set("result_key", []) self.set("req_params", []) @@ -80,9 +80,11 @@ class CurrencyExchangeSettings(Document): @frappe.whitelist() def get_api_endpoint(service_provider: str | None = None, use_http: bool = False): - if service_provider and service_provider in ["exchangerate.host", "frankfurter.dev"]: + if service_provider and service_provider in ["exchangerate.host", "frankfurter.dev", "frankfurter.app"]: if service_provider == "exchangerate.host": api = "api.exchangerate.host/convert" + elif service_provider == "frankfurter.app": + api = "api.frankfurter.app/{transaction_date}" elif service_provider == "frankfurter.dev": api = "api.frankfurter.dev/v1/{transaction_date}" diff --git a/erpnext/accounts/doctype/share_balance/share_balance.json b/erpnext/accounts/doctype/share_balance/share_balance.json index 04d7bb75bf8..4cbe2deffe5 100644 --- a/erpnext/accounts/doctype/share_balance/share_balance.json +++ b/erpnext/accounts/doctype/share_balance/share_balance.json @@ -80,7 +80,7 @@ "collapsible": 0, "columns": 0, "fieldname": "rate", - "fieldtype": "Int", + "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -102,7 +102,7 @@ "search_index": 0, "set_only_once": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -199,7 +199,7 @@ "collapsible": 0, "columns": 0, "fieldname": "amount", - "fieldtype": "Int", + "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -221,7 +221,7 @@ "search_index": 0, "set_only_once": 0, "unique": 0 - }, + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -324,7 +324,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-01-10 18:32:36.201124", + "modified": "2025-12-10 08:06:40.611761", "modified_by": "Administrator", "module": "Accounts", "name": "Share Balance", @@ -339,4 +339,4 @@ "sort_order": "DESC", "track_changes": 1, "track_seen": 0 -} \ No newline at end of file +} diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 6185eeb9547..eb19ff1c43d 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -1532,11 +1532,7 @@ def get_straight_line_or_manual_depr_amount(asset, row, schedule_idx, number_of_ # if the Depreciation Schedule is being prepared for the first time else: if row.daily_prorata_based: - amount = ( - flt(asset.gross_purchase_amount) - - flt(asset.opening_accumulated_depreciation) - - flt(row.expected_value_after_useful_life) - ) + amount = flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life) total_days = ( date_diff( get_last_day( @@ -1548,7 +1544,11 @@ def get_straight_line_or_manual_depr_amount(asset, row, schedule_idx, number_of_ ), add_days( get_last_day( - add_months(row.depreciation_start_date, -1 * row.frequency_of_depreciation) + add_months( + row.depreciation_start_date, + (row.frequency_of_depreciation * (asset.number_of_depreciations_booked + 1)) + * -1, + ), ), 1, ), @@ -1571,11 +1571,9 @@ def get_straight_line_or_manual_depr_amount(asset, row, schedule_idx, number_of_ return daily_depr_amount * (date_diff(to_date, from_date) + 1) else: - return ( - flt(asset.gross_purchase_amount) - - flt(asset.opening_accumulated_depreciation) - - flt(row.expected_value_after_useful_life) - ) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked) + return (flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life)) / flt( + row.total_number_of_depreciations + ) def get_shift_depr_amount(asset, row, schedule_idx): diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index b89027578c5..7700aed69c4 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -660,7 +660,7 @@ class TestDepreciationMethods(AssetSetup): available_for_use_date="2030-06-06", is_existing_asset=1, number_of_depreciations_booked=2, - opening_accumulated_depreciation=47095.89, + opening_accumulated_depreciation=47178.08, expected_value_after_useful_life=10000, depreciation_start_date="2032-12-31", total_number_of_depreciations=3, @@ -668,7 +668,7 @@ class TestDepreciationMethods(AssetSetup): ) self.assertEqual(asset.status, "Draft") - expected_schedules = [["2032-12-31", 42904.11, 90000.0]] + expected_schedules = [["2032-12-31", 30000.0, 77178.08], ["2033-06-06", 12821.92, 90000.0]] schedules = [ [cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount] for d in asset.get("schedules") diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 484133b7b25..429f9da99df 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -377,4 +377,4 @@ execute:frappe.db.set_single_value("Accounts Settings", "receivable_payable_fetc erpnext.patches.v14_0.set_update_price_list_based_on erpnext.patches.v14_0.rename_group_by_to_categorize_by_in_custom_reports erpnext.patches.v14_0.update_full_name_in_contract -erpnext.patches.v16_0.update_currency_exchange_settings_for_frankfurter +erpnext.patches.v16_0.update_currency_exchange_settings_for_frankfurter #2025-12-11 diff --git a/erpnext/patches/v16_0/update_currency_exchange_settings_for_frankfurter.py b/erpnext/patches/v16_0/update_currency_exchange_settings_for_frankfurter.py index 68157b1a4ad..9d3f78cc09b 100644 --- a/erpnext/patches/v16_0/update_currency_exchange_settings_for_frankfurter.py +++ b/erpnext/patches/v16_0/update_currency_exchange_settings_for_frankfurter.py @@ -2,8 +2,13 @@ import frappe def execute(): + settings_meta = frappe.get_meta("Currency Exchange Settings") settings = frappe.get_doc("Currency Exchange Settings") - if settings.service_provider != "frankfurter.app": + + if ( + "frankfurter.dev" not in settings_meta.get_options("service_provider").split("\n") + or settings.service_provider != "frankfurter.app" + ): return settings.service_provider = "frankfurter.dev" diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py index 5919c21fcbf..44a63579a8e 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py @@ -309,8 +309,9 @@ class TransactionDeletionRecord(Document): self.db_set("error_log", None) def get_doctypes_to_be_ignored_list(self): - singles = frappe.get_all("DocType", filters={"issingle": 1}, pluck="name") - doctypes_to_be_ignored_list = singles + doctypes_to_be_ignored_list = frappe.get_all( + "DocType", or_filters=[["issingle", "=", 1], ["is_virtual", "=", 1]], pluck="name" + ) for doctype in self.doctypes_to_be_ignored: doctypes_to_be_ignored_list.append(doctype.doctype_name) diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index 0cb56e6375c..3ecf2fdacca 100644 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -158,7 +158,7 @@ def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, ord customer = contact_doc.get_link_for("Customer") ignore_permissions = False - if is_website_user(): + if is_website_user() and user != "Guest": if not filters: filters = {}