mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-22 10:56:30 +00:00
feat: option to recreate Stock Ledger Entries against stock transactions
(cherry picked from commit 218dbd6911)
# Conflicts:
# erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
This commit is contained in:
committed by
Mergify
parent
37adb9187f
commit
64fdcb752d
@@ -4077,6 +4077,54 @@ class TestPurchaseReceipt(FrappeTestCase):
|
|||||||
pr.reload()
|
pr.reload()
|
||||||
self.assertEqual(pr.status, "To Bill")
|
self.assertEqual(pr.status, "To Bill")
|
||||||
|
|
||||||
|
def test_recreate_stock_ledgers(self):
|
||||||
|
item_code = "Test Item for Recreate Stock Ledgers"
|
||||||
|
create_item(item_code)
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(item_code=item_code, qty=10, rate=100)
|
||||||
|
pr.submit()
|
||||||
|
|
||||||
|
sles = frappe.get_all(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
filters={"voucher_type": pr.doctype, "voucher_no": pr.name},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(sles)
|
||||||
|
|
||||||
|
for row in sles:
|
||||||
|
doc = frappe.get_doc("Stock Ledger Entry", row)
|
||||||
|
doc.delete()
|
||||||
|
|
||||||
|
sles = frappe.get_all(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
filters={"voucher_type": pr.doctype, "voucher_no": pr.name},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertFalse(sles)
|
||||||
|
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Repost Item Valuation",
|
||||||
|
"based_on": "Transaction",
|
||||||
|
"voucher_type": pr.doctype,
|
||||||
|
"voucher_no": pr.name,
|
||||||
|
"posting_date": pr.posting_date,
|
||||||
|
"posting_time": pr.posting_time,
|
||||||
|
"company": pr.company,
|
||||||
|
"recreate_stock_ledgers": 1,
|
||||||
|
}
|
||||||
|
).submit()
|
||||||
|
|
||||||
|
sles = frappe.get_all(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
filters={"voucher_type": pr.doctype, "voucher_no": pr.name},
|
||||||
|
pluck="name",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(sles)
|
||||||
|
|
||||||
|
|
||||||
def prepare_data_for_internal_transfer():
|
def prepare_data_for_internal_transfer():
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"allow_negative_stock",
|
"allow_negative_stock",
|
||||||
"via_landed_cost_voucher",
|
"via_landed_cost_voucher",
|
||||||
"allow_zero_rate",
|
"allow_zero_rate",
|
||||||
|
"recreate_stock_ledgers",
|
||||||
"amended_from",
|
"amended_from",
|
||||||
"error_section",
|
"error_section",
|
||||||
"error_log",
|
"error_log",
|
||||||
@@ -220,12 +221,20 @@
|
|||||||
"label": "Reposting Data File",
|
"label": "Reposting Data File",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.based_on == \"Transaction\"",
|
||||||
|
"fieldname": "recreate_stock_ledgers",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Recreate Stock Ledgers"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"grid_page_length": 50,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-06-27 16:55:23.150146",
|
"modified": "2025-03-31 12:38:20.566196",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Repost Item Valuation",
|
"name": "Repost Item Valuation",
|
||||||
@@ -274,7 +283,12 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
<<<<<<< HEAD
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
|
=======
|
||||||
|
"row_format": "Dynamic",
|
||||||
|
"sort_field": "creation",
|
||||||
|
>>>>>>> 218dbd6911 (feat: option to recreate Stock Ledger Entries against stock transactions)
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": []
|
"states": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class RepostItemValuation(Document):
|
|||||||
items_to_be_repost: DF.Code | None
|
items_to_be_repost: DF.Code | None
|
||||||
posting_date: DF.Date
|
posting_date: DF.Date
|
||||||
posting_time: DF.Time | None
|
posting_time: DF.Time | None
|
||||||
|
recreate_stock_ledgers: DF.Check
|
||||||
reposting_data_file: DF.Attach | None
|
reposting_data_file: DF.Attach | None
|
||||||
status: DF.Literal["Queued", "In Progress", "Completed", "Skipped", "Failed"]
|
status: DF.Literal["Queued", "In Progress", "Completed", "Skipped", "Failed"]
|
||||||
total_reposting_count: DF.Int
|
total_reposting_count: DF.Int
|
||||||
@@ -74,6 +75,7 @@ class RepostItemValuation(Document):
|
|||||||
self.reset_field_values()
|
self.reset_field_values()
|
||||||
self.set_company()
|
self.set_company()
|
||||||
self.validate_accounts_freeze()
|
self.validate_accounts_freeze()
|
||||||
|
self.reset_recreate_stock_ledgers()
|
||||||
|
|
||||||
def validate_period_closing_voucher(self):
|
def validate_period_closing_voucher(self):
|
||||||
# Period Closing Voucher
|
# Period Closing Voucher
|
||||||
@@ -105,6 +107,10 @@ class RepostItemValuation(Document):
|
|||||||
msg = f"Due to closing stock balance {name}, you cannot repost item valuation before {to_date}"
|
msg = f"Due to closing stock balance {name}, you cannot repost item valuation before {to_date}"
|
||||||
frappe.throw(_(msg))
|
frappe.throw(_(msg))
|
||||||
|
|
||||||
|
def reset_recreate_stock_ledgers(self):
|
||||||
|
if self.recreate_stock_ledgers and self.based_on != "Transaction":
|
||||||
|
self.recreate_stock_ledgers = 0
|
||||||
|
|
||||||
def get_closing_stock_balance(self):
|
def get_closing_stock_balance(self):
|
||||||
filters = {
|
filters = {
|
||||||
"company": self.company,
|
"company": self.company,
|
||||||
@@ -250,6 +256,16 @@ class RepostItemValuation(Document):
|
|||||||
filters,
|
filters,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def recreate_stock_ledger_entries(self):
|
||||||
|
"""Recreate Stock Ledger Entries for the transaction."""
|
||||||
|
if self.based_on == "Transaction" and self.recreate_stock_ledgers:
|
||||||
|
doc = frappe.get_doc(self.voucher_type, self.voucher_no)
|
||||||
|
doc.docstatus = 2
|
||||||
|
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
|
||||||
|
|
||||||
|
doc.docstatus = 1
|
||||||
|
doc.update_stock_ledger(allow_negative_stock=True)
|
||||||
|
|
||||||
|
|
||||||
def on_doctype_update():
|
def on_doctype_update():
|
||||||
frappe.db.add_index("Repost Item Valuation", ["warehouse", "item_code"], "item_warehouse")
|
frappe.db.add_index("Repost Item Valuation", ["warehouse", "item_code"], "item_warehouse")
|
||||||
@@ -268,6 +284,9 @@ def repost(doc):
|
|||||||
if not frappe.flags.in_test:
|
if not frappe.flags.in_test:
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
|
if doc.recreate_stock_ledgers:
|
||||||
|
doc.recreate_stock_ledger_entries()
|
||||||
|
|
||||||
repost_sl_entries(doc)
|
repost_sl_entries(doc)
|
||||||
repost_gl_entries(doc)
|
repost_gl_entries(doc)
|
||||||
|
|
||||||
|
|||||||
@@ -184,11 +184,16 @@ def validate_serial_no(sle):
|
|||||||
frappe.throw(_(msg), title=_(title), exc=SerialNoExistsInFutureTransaction)
|
frappe.throw(_(msg), title=_(title), exc=SerialNoExistsInFutureTransaction)
|
||||||
|
|
||||||
|
|
||||||
def validate_cancellation(args):
|
def validate_cancellation(kargs):
|
||||||
if args[0].get("is_cancelled"):
|
if kargs[0].get("is_cancelled"):
|
||||||
repost_entry = frappe.db.get_value(
|
repost_entry = frappe.db.get_value(
|
||||||
"Repost Item Valuation",
|
"Repost Item Valuation",
|
||||||
{"voucher_type": args[0].voucher_type, "voucher_no": args[0].voucher_no, "docstatus": 1},
|
{
|
||||||
|
"voucher_type": kargs[0].voucher_type,
|
||||||
|
"voucher_no": kargs[0].voucher_no,
|
||||||
|
"docstatus": 1,
|
||||||
|
"recreate_stock_ledgers": 0,
|
||||||
|
},
|
||||||
["name", "status"],
|
["name", "status"],
|
||||||
as_dict=1,
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user