fix: dependent GLE reposting
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
index 6148e16..156f77f 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
@@ -23,6 +23,7 @@
"error_section",
"error_log",
"items_to_be_repost",
+ "affected_transactions",
"distinct_item_and_warehouse",
"current_index"
],
@@ -172,12 +173,20 @@
"no_copy": 1,
"print_hide": 1,
"read_only": 1
+ },
+ {
+ "fieldname": "affected_transactions",
+ "fieldtype": "Code",
+ "hidden": 1,
+ "label": "Affected Transactions",
+ "no_copy": 1,
+ "read_only": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2022-03-30 07:22:48.520266",
+ "modified": "2022-04-18 14:08:08.821602",
"modified_by": "Administrator",
"module": "Stock",
"name": "Repost Item Valuation",
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index 49aa0ff..eb0be46 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -8,8 +8,12 @@
from frappe.utils.user import get_users_with_role
import erpnext
-from erpnext.accounts.utils import update_gl_entries_after
-from erpnext.stock.stock_ledger import get_items_to_be_repost, repost_future_sle
+from erpnext.accounts.utils import get_future_stock_vouchers, repost_gle_for_stock_vouchers
+from erpnext.stock.stock_ledger import (
+ get_affected_transactions,
+ get_items_to_be_repost,
+ repost_future_sle,
+)
class RepostItemValuation(Document):
@@ -169,6 +173,7 @@
],
allow_negative_stock=doc.allow_negative_stock,
via_landed_cost_voucher=doc.via_landed_cost_voucher,
+ doc=doc,
)
@@ -176,27 +181,46 @@
if not cint(erpnext.is_perpetual_inventory_enabled(doc.company)):
return
+ # directly modified transactions
+ directly_dependent_transactions = _get_directly_dependent_vouchers(doc)
+ repost_affected_transaction = get_affected_transactions(doc)
+ repost_gle_for_stock_vouchers(
+ directly_dependent_transactions + list(repost_affected_transaction),
+ doc.posting_date,
+ doc.company,
+ )
+
+
+def _get_directly_dependent_vouchers(doc):
+ """Get stock vouchers that are directly affected by reposting
+ i.e. any one item-warehouse is present in the stock transaction"""
+
+ items = set()
+ warehouses = set()
+
if doc.based_on == "Transaction":
ref_doc = frappe.get_doc(doc.voucher_type, doc.voucher_no)
doc_items, doc_warehouses = ref_doc.get_items_and_warehouses()
+ items.update(doc_items)
+ warehouses.update(doc_warehouses)
sles = get_items_to_be_repost(doc.voucher_type, doc.voucher_no)
- sle_items = [sle.item_code for sle in sles]
- sle_warehouse = [sle.warehouse for sle in sles]
-
- items = list(set(doc_items).union(set(sle_items)))
- warehouses = list(set(doc_warehouses).union(set(sle_warehouse)))
+ sle_items = {sle.item_code for sle in sles}
+ sle_warehouses = {sle.warehouse for sle in sles}
+ items.update(sle_items)
+ warehouses.update(sle_warehouses)
else:
- items = [doc.item_code]
- warehouses = [doc.warehouse]
+ items.add(doc.item_code)
+ warehouses.add(doc.warehouse)
- update_gl_entries_after(
- doc.posting_date,
- doc.posting_time,
- for_warehouses=warehouses,
- for_items=items,
+ affected_vouchers = get_future_stock_vouchers(
+ posting_date=doc.posting_date,
+ posting_time=doc.posting_time,
+ for_warehouses=list(warehouses),
+ for_items=list(items),
company=doc.company,
)
+ return affected_vouchers
def notify_error_to_stock_managers(doc, traceback):
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index b7fd65b..f46332b 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -3,7 +3,7 @@
import copy
import json
-from typing import Optional
+from typing import Optional, Set, Tuple
import frappe
from frappe import _
@@ -214,6 +214,7 @@
args = get_items_to_be_repost(voucher_type, voucher_no, doc)
distinct_item_warehouses = get_distinct_item_warehouse(args, doc)
+ affected_transactions = get_affected_transactions(doc)
i = get_current_index(doc) or 0
while i < len(args):
@@ -231,6 +232,7 @@
allow_negative_stock=allow_negative_stock,
via_landed_cost_voucher=via_landed_cost_voucher,
)
+ affected_transactions.update(obj.affected_transactions)
distinct_item_warehouses[
(args[i].get("item_code"), args[i].get("warehouse"))
@@ -250,10 +252,14 @@
i += 1
if doc and i % 2 == 0:
- update_args_in_repost_item_valuation(doc, i, args, distinct_item_warehouses)
+ update_args_in_repost_item_valuation(
+ doc, i, args, distinct_item_warehouses, affected_transactions
+ )
if doc and args:
- update_args_in_repost_item_valuation(doc, i, args, distinct_item_warehouses)
+ update_args_in_repost_item_valuation(
+ doc, i, args, distinct_item_warehouses, affected_transactions
+ )
def validate_item_warehouse(args):
@@ -263,20 +269,24 @@
frappe.throw(_(validation_msg))
-def update_args_in_repost_item_valuation(doc, index, args, distinct_item_warehouses):
- frappe.db.set_value(
- doc.doctype,
- doc.name,
+def update_args_in_repost_item_valuation(
+ doc, index, args, distinct_item_warehouses, affected_transactions
+):
+ affected_transactions_list = [list(transaction) for transaction in affected_transactions]
+
+ doc.db_set(
{
"items_to_be_repost": json.dumps(args, default=str),
"distinct_item_and_warehouse": json.dumps(
{str(k): v for k, v in distinct_item_warehouses.items()}, default=str
),
"current_index": index,
- },
+ "affected_transactions": json.dumps(affected_transactions_list),
+ }
)
- frappe.db.commit()
+ if not frappe.flags.in_test:
+ frappe.db.commit()
frappe.publish_realtime(
"item_reposting_progress",
@@ -313,6 +323,14 @@
return distinct_item_warehouses
+def get_affected_transactions(doc) -> Set[Tuple[str, str]]:
+ if not doc.affected_transactions:
+ return set()
+
+ transactions = frappe.parse_json(doc.affected_transactions)
+ return {tuple(transaction) for transaction in transactions}
+
+
def get_current_index(doc=None):
if doc and doc.current_index:
return doc.current_index
@@ -360,6 +378,7 @@
self.new_items_found = False
self.distinct_item_warehouses = args.get("distinct_item_warehouses", frappe._dict())
+ self.affected_transactions: Set[Tuple[str, str]] = set()
self.data = frappe._dict()
self.initialize_previous_data(self.args)
@@ -518,6 +537,7 @@
# previous sle data for this warehouse
self.wh_data = self.data[sle.warehouse]
+ self.affected_transactions.add((sle.voucher_type, sle.voucher_no))
if (sle.serial_no and not self.via_landed_cost_voucher) or not cint(self.allow_negative_stock):
# validate negative stock for serialized items, fifo valuation