fix: dependent GLE reposting
This commit is contained in:
parent
a2af2daca7
commit
ecdb49314f
@ -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",
|
||||
|
@ -8,8 +8,12 @@ from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime
|
||||
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 @@ def repost_sl_entries(doc):
|
||||
],
|
||||
allow_negative_stock=doc.allow_negative_stock,
|
||||
via_landed_cost_voucher=doc.via_landed_cost_voucher,
|
||||
doc=doc,
|
||||
)
|
||||
|
||||
|
||||
@ -176,27 +181,46 @@ def repost_gl_entries(doc):
|
||||
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):
|
||||
|
@ -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 @@ def repost_future_sle(
|
||||
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 @@ def repost_future_sle(
|
||||
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 @@ def repost_future_sle(
|
||||
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 @@ def validate_item_warehouse(args):
|
||||
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 @@ def get_distinct_item_warehouse(args=None, doc=None):
|
||||
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 @@ class update_entries_after(object):
|
||||
|
||||
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 @@ class update_entries_after(object):
|
||||
|
||||
# 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
|
||||
|
Loading…
Reference in New Issue
Block a user