diff --git a/erpnext/accounts/doctype/budget/test_budget.py b/erpnext/accounts/doctype/budget/test_budget.py index 6d9a6f51468..6d256382042 100644 --- a/erpnext/accounts/doctype/budget/test_budget.py +++ b/erpnext/accounts/doctype/budget/test_budget.py @@ -6,7 +6,11 @@ import unittest import frappe from frappe.utils import now_datetime, nowdate -from erpnext.accounts.doctype.budget.budget import BudgetError, get_actual_expense +from erpnext.accounts.doctype.budget.budget import ( + BudgetError, + get_accumulated_monthly_budget, + get_actual_expense, +) from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry from erpnext.accounts.utils import get_fiscal_year from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order @@ -96,6 +100,10 @@ class TestBudget(unittest.TestCase): frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop") frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year) + accumulated_limit = get_accumulated_monthly_budget( + budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount + ) + mr = frappe.get_doc( { "doctype": "Material Request", @@ -109,7 +117,7 @@ class TestBudget(unittest.TestCase): "uom": "_Test UOM", "warehouse": "_Test Warehouse - _TC", "schedule_date": nowdate(), - "rate": 100000, + "rate": accumulated_limit + 1, "expense_account": "_Test Account Cost for Goods Sold - _TC", "cost_center": "_Test Cost Center - _TC", } diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 31d575358ae..71c753c0adc 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -1126,9 +1126,6 @@ class PurchaseInvoice(BuyingController): elif self.is_return and self.update_stock and (self.is_internal_supplier or not self.return_against): net_rate = item.base_net_amount - if item.sales_incoming_rate: # for internal transfer - net_rate = item.qty * item.sales_incoming_rate - stock_amount = net_rate + item.item_tax_amount + flt(item.landed_cost_voucher_amount) if flt(stock_amount, net_amt_precision) != flt(warehouse_debit_amount, net_amt_precision): diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py index 3649a41963f..b380959a3a8 100644 --- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py +++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py @@ -121,7 +121,7 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_ ) out.append(row) - out.sort(key=lambda x: x["section_code"]) + out.sort(key=lambda x: (x["section_code"], x["transaction_date"])) return out diff --git a/erpnext/accounts/report/tds_payable_monthly/test_tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/test_tds_payable_monthly.py index 91461e517dc..63492b6c19c 100644 --- a/erpnext/accounts/report/tds_payable_monthly/test_tds_payable_monthly.py +++ b/erpnext/accounts/report/tds_payable_monthly/test_tds_payable_monthly.py @@ -67,11 +67,12 @@ class TestTdsPayableMonthly(AccountsTestMixin, FrappeTestCase): mid_year = add_to_date(fiscal_year[1], months=6) tds_doc = frappe.get_doc("Tax Withholding Category", "TDS - 3") tds_doc.rates[0].to_date = mid_year + from_date = add_to_date(mid_year, days=1) tds_doc.append( "rates", { "tax_withholding_rate": 20, - "from_date": add_to_date(mid_year, days=1), + "from_date": from_date, "to_date": fiscal_year[2], "single_threshold": 1, "cumulative_threshold": 1, @@ -80,18 +81,19 @@ class TestTdsPayableMonthly(AccountsTestMixin, FrappeTestCase): tds_doc.save() - inv_1 = make_purchase_invoice(rate=1000, do_not_submit=True) + inv_1 = make_purchase_invoice( + rate=1000, posting_date=add_to_date(fiscal_year[1], days=1), do_not_save=True, do_not_submit=True + ) + inv_1.set_posting_time = 1 inv_1.apply_tds = 1 - inv_1.tax_withholding_category = "TDS - 3" + inv_1.tax_withholding_category = tds_doc.name + inv_1.save() inv_1.submit() - inv_2 = make_purchase_invoice( - rate=1000, do_not_submit=True, posting_date=add_to_date(mid_year, days=1), do_not_save=True - ) + inv_2 = make_purchase_invoice(rate=1000, posting_date=from_date, do_not_save=True, do_not_submit=True) inv_2.set_posting_time = 1 - - inv_1.apply_tds = 1 - inv_2.tax_withholding_category = "TDS - 3" + inv_2.apply_tds = 1 + inv_2.tax_withholding_category = tds_doc.name inv_2.save() inv_2.submit() diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js index 7337fd477e7..6d131d089cc 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.js +++ b/erpnext/accounts/report/trial_balance/trial_balance.js @@ -79,8 +79,14 @@ frappe.require("assets/erpnext/js/financial_statements.js", function () { options: erpnext.get_presentation_currency_list(), }, { - fieldname: "with_period_closing_entry", - label: __("Period Closing Entry"), + fieldname: "with_period_closing_entry_for_opening", + label: __("With Period Closing Entry For Opening Balances"), + fieldtype: "Check", + default: 1, + }, + { + fieldname: "with_period_closing_entry_for_current_period", + label: __("Period Closing Entry For Current Period"), fieldtype: "Check", default: 1, }, diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index 4ae314bdff7..f0075332256 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -120,7 +120,7 @@ def get_data(filters): max_rgt, filters, gl_entries_by_account, - ignore_closing_entries=not flt(filters.with_period_closing_entry), + ignore_closing_entries=not flt(filters.with_period_closing_entry_for_current_period), ignore_opening_entries=True, ) @@ -274,7 +274,7 @@ def get_opening_balance( ): opening_balance = opening_balance.where(closing_balance.posting_date >= filters.year_start_date) - if not flt(filters.with_period_closing_entry): + if not flt(filters.with_period_closing_entry_for_opening): if doctype == "Account Closing Balance": opening_balance = opening_balance.where(closing_balance.is_period_closing_voucher_entry == 0) else: diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py index f78d95f4160..5d606f648fa 100644 --- a/erpnext/accounts/report/utils.py +++ b/erpnext/accounts/report/utils.py @@ -107,11 +107,7 @@ def convert_to_presentation_currency(gl_entries, currency_info): credit_in_account_currency = flt(entry["credit_in_account_currency"]) account_currency = entry["account_currency"] - if ( - len(account_currencies) == 1 - and account_currency == presentation_currency - and (debit_in_account_currency or credit_in_account_currency) - ): + if len(account_currencies) == 1 and account_currency == presentation_currency: entry["debit"] = debit_in_account_currency entry["credit"] = credit_in_account_currency else: diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 2f4c154cb00..38e2d99f8c7 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1027,12 +1027,7 @@ def is_reposting_pending(): ) -def future_sle_exists(args, sl_entries=None, allow_force_reposting=True): - if allow_force_reposting and frappe.db.get_single_value( - "Stock Reposting Settings", "do_reposting_for_each_stock_transaction" - ): - return True - +def future_sle_exists(args, sl_entries=None): key = (args.voucher_type, args.voucher_no) if not hasattr(frappe.local, "future_sle"): frappe.local.future_sle = {} diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index c7b36b6aa3f..75753c8b0f5 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -202,7 +202,7 @@ def update_qty(bin_name, args): sle = frappe.qb.DocType("Stock Ledger Entry") # actual qty is not up to date in case of backdated transaction - if future_sle_exists(args, allow_force_reposting=False): + if future_sle_exists(args): last_sle_qty = ( frappe.qb.from_(sle) .select(sle.qty_after_transaction) diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js index c819d17b1e7..1b5f4a5743f 100644 --- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js +++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.js @@ -75,7 +75,9 @@ frappe.ui.form.on("Inventory Dimension", { set_parent_fields(frm) { if (frm.doc.apply_to_all_doctypes) { - frm.set_df_property("fetch_from_parent", "options", frm.doc.reference_document); + let options = ["\n", frm.doc.reference_document]; + + frm.set_df_property("fetch_from_parent", "options", options); } else if (frm.doc.document_type && frm.doc.istable) { frappe.call({ method: "erpnext.stock.doctype.inventory_dimension.inventory_dimension.get_parent_fields", @@ -85,7 +87,7 @@ frappe.ui.form.on("Inventory Dimension", { }, callback: (r) => { if (r.message && r.message.length) { - frm.set_df_property("fetch_from_parent", "options", [""].concat(r.message)); + frm.set_df_property("fetch_from_parent", "options", ["\n"].concat(r.message)); } else { frm.set_df_property("fetch_from_parent", "hidden", 1); } diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json index 0e4055251f0..45f570bbdc0 100644 --- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json +++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.json @@ -143,7 +143,6 @@ "fieldtype": "Column Break" }, { - "depends_on": "eval:!doc.apply_to_all_doctypes", "description": "Set fieldname from which you want to fetch the data from the parent form.", "fieldname": "fetch_from_parent", "fieldtype": "Select", @@ -189,7 +188,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2023-10-05 12:52:18.705431", + "modified": "2025-07-07 15:51:29.329064", "modified_by": "Administrator", "module": "Stock", "name": "Inventory Dimension", @@ -236,4 +235,4 @@ "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} diff --git a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py index ecc726fd86c..7770ffed321 100644 --- a/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py +++ b/erpnext/stock/doctype/inventory_dimension/inventory_dimension.py @@ -40,16 +40,11 @@ class InventoryDimension(Document): self.reset_value() self.set_source_and_target_fieldname() self.set_type_of_transaction() - self.set_fetch_value_from() def set_type_of_transaction(self): if self.apply_to_all_doctypes: self.type_of_transaction = "Both" - def set_fetch_value_from(self): - if self.apply_to_all_doctypes: - self.fetch_from_parent = self.reference_document - def do_not_update_document(self): if self.is_new() or not self.has_stock_ledger(): return diff --git a/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py b/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py index 57b37801cb5..835ea51d74d 100644 --- a/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py +++ b/erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py @@ -154,6 +154,8 @@ class TestInventoryDimension(FrappeTestCase): reference_document="Rack", dimension_name="Rack", apply_to_all_doctypes=1 ) + inv_dimension.db_set("fetch_from_parent", "Rack") + self.assertEqual(inv_dimension.type_of_transaction, "Both") self.assertEqual(inv_dimension.fetch_from_parent, "Rack") diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 79bbf0b502c..d1b81aa2ebe 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -489,10 +489,6 @@ class StockReconciliation(StockController): self.update_inventory_dimensions(row, data) - if self.docstatus == 1 and has_dimensions and not row.batch_no: - data.qty_after_transaction = data.actual_qty - data.actual_qty = 0.0 - return data def make_sle_on_cancel(self): diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json index cbbb0ce0990..3137bedfee4 100644 --- a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json +++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json @@ -13,7 +13,6 @@ "end_time", "limits_dont_apply_on", "item_based_reposting", - "do_reposting_for_each_stock_transaction", "errors_notification_section", "notify_reposting_error_to_role" ], @@ -66,18 +65,12 @@ "fieldname": "errors_notification_section", "fieldtype": "Section Break", "label": "Errors Notification" - }, - { - "default": "0", - "fieldname": "do_reposting_for_each_stock_transaction", - "fieldtype": "Check", - "label": "Do reposting for each Stock Transaction" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-04-24 12:19:40.204888", + "modified": "2025-07-08 11:27:46.659056", "modified_by": "Administrator", "module": "Stock", "name": "Stock Reposting Settings", diff --git a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py index 10104fb9a60..51fb5ac4c40 100644 --- a/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py +++ b/erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py @@ -11,10 +11,6 @@ class StockRepostingSettings(Document): def validate(self): self.set_minimum_reposting_time_slot() - def before_save(self): - if self.do_reposting_for_each_stock_transaction: - self.item_based_reposting = 1 - def set_minimum_reposting_time_slot(self): """Ensure that timeslot for reposting is at least 12 hours.""" if not self.limit_reposting_timeslot: diff --git a/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py b/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py index e53659c1735..a6dc72d7a42 100644 --- a/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py +++ b/erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py @@ -38,51 +38,3 @@ class TestStockRepostingSettings(unittest.TestCase): users = get_recipients() self.assertTrue(user in users) - - def test_do_reposting_for_each_stock_transaction(self): - from erpnext.stock.doctype.item.test_item import make_item - from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry - - frappe.db.set_single_value("Stock Reposting Settings", "do_reposting_for_each_stock_transaction", 1) - if frappe.db.get_single_value("Stock Reposting Settings", "item_based_reposting"): - frappe.db.set_single_value("Stock Reposting Settings", "item_based_reposting", 0) - - item = make_item( - "_Test item for reposting check for each transaction", properties={"is_stock_item": 1} - ).name - - stock_entry = make_stock_entry( - item_code=item, - qty=1, - rate=100, - stock_entry_type="Material Receipt", - target="_Test Warehouse - _TC", - ) - - riv = frappe.get_all("Repost Item Valuation", filters={"voucher_no": stock_entry.name}, pluck="name") - self.assertTrue(riv) - - frappe.db.set_single_value("Stock Reposting Settings", "do_reposting_for_each_stock_transaction", 0) - - def test_do_not_reposting_for_each_stock_transaction(self): - from erpnext.stock.doctype.item.test_item import make_item - from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry - - frappe.db.set_single_value("Stock Reposting Settings", "do_reposting_for_each_stock_transaction", 0) - if frappe.db.get_single_value("Stock Reposting Settings", "item_based_reposting"): - frappe.db.set_single_value("Stock Reposting Settings", "item_based_reposting", 0) - - item = make_item( - "_Test item for do not reposting check for each transaction", properties={"is_stock_item": 1} - ).name - - stock_entry = make_stock_entry( - item_code=item, - qty=1, - rate=100, - stock_entry_type="Material Receipt", - target="_Test Warehouse - _TC", - ) - - riv = frappe.get_all("Repost Item Valuation", filters={"voucher_no": stock_entry.name}, pluck="name") - self.assertFalse(riv)