mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-09 15:29:30 +00:00
feat: add subcontracting receipt ledger previews (#58698)
This commit is contained in:
@@ -4,17 +4,22 @@
|
||||
"""Read-side GL / Stock Ledger preview helpers.
|
||||
|
||||
A dry-run consumer of the posting path, shared across accounts and stock vouchers
|
||||
(Sales/Purchase Invoice, Payment Entry, Delivery Note, Purchase Receipt, Stock
|
||||
Entry): it submits-in-memory, reads the resulting GL/SLE entries and formats them
|
||||
for the datatable preview, then rolls back. Lives separately from the posting
|
||||
services it orchestrates. The whitelisted ``show_*_preview`` entry points stay on
|
||||
``stock_controller`` (their dotted path is referenced from client JS).
|
||||
(Sales/Purchase Invoice, Payment Entry, Delivery Note, Purchase Receipt,
|
||||
Subcontracting Receipt, Stock Entry): it submits-in-memory, reads the resulting
|
||||
GL/SLE entries and formats them for the datatable preview, then rolls back. Lives
|
||||
separately from the posting services it orchestrates. The whitelisted
|
||||
``show_*_preview`` entry points stay on ``stock_controller`` (their dotted path is
|
||||
referenced from client JS).
|
||||
"""
|
||||
|
||||
import frappe
|
||||
|
||||
from erpnext import get_company_currency
|
||||
|
||||
STOCK_LEDGER_PREVIEW_DOCTYPES = frozenset(
|
||||
("Delivery Note", "Purchase Receipt", "Stock Entry", "Subcontracting Receipt")
|
||||
)
|
||||
|
||||
|
||||
def get_accounting_ledger_preview(doc, filters):
|
||||
from erpnext.accounts.report.general_ledger.general_ledger import get_columns as get_gl_columns
|
||||
@@ -39,7 +44,8 @@ def get_accounting_ledger_preview(doc, filters):
|
||||
try:
|
||||
doc.docstatus = 1
|
||||
|
||||
if doc.get("update_stock") or doc.doctype in ("Purchase Receipt", "Delivery Note", "Stock Entry"):
|
||||
if doc.get("update_stock") or doc.doctype in STOCK_LEDGER_PREVIEW_DOCTYPES:
|
||||
make_serial_and_batch_bundles_for_preview(doc)
|
||||
doc.update_stock_ledger()
|
||||
|
||||
doc.make_gl_entries()
|
||||
@@ -82,13 +88,13 @@ def get_stock_ledger_preview(doc, filters):
|
||||
"stock_value_difference",
|
||||
]
|
||||
|
||||
if doc.get("update_stock") or doc.doctype in ("Purchase Receipt", "Delivery Note", "Stock Entry"):
|
||||
if doc.get("update_stock") or doc.doctype in STOCK_LEDGER_PREVIEW_DOCTYPES:
|
||||
# Dry run: submit in memory to materialise SLEs, read them, then roll back to
|
||||
# the savepoint so the preview never persists anything, regardless of caller.
|
||||
frappe.db.savepoint("ledger_preview")
|
||||
try:
|
||||
doc.docstatus = 1
|
||||
doc.make_bundle_using_old_serial_batch_fields()
|
||||
make_serial_and_batch_bundles_for_preview(doc)
|
||||
doc.update_stock_ledger()
|
||||
|
||||
columns = get_sl_columns(filters)
|
||||
@@ -125,6 +131,12 @@ def get_gl_entries_for_preview(doctype, docname, fields):
|
||||
return frappe.get_all("GL Entry", filters={"voucher_type": doctype, "voucher_no": docname}, fields=fields)
|
||||
|
||||
|
||||
def make_serial_and_batch_bundles_for_preview(doc):
|
||||
table_names = ("items", "supplied_items") if doc.doctype == "Subcontracting Receipt" else ("items",)
|
||||
for table_name in table_names:
|
||||
doc.make_bundle_using_old_serial_batch_fields(table_name)
|
||||
|
||||
|
||||
def get_columns(raw_columns, fields, currency):
|
||||
columns = []
|
||||
for source_column in raw_columns:
|
||||
|
||||
@@ -31,6 +31,9 @@ frappe.ui.form.on("Subcontracting Receipt", {
|
||||
frappe.dynamic_link = { doc: frm.doc, fieldname: "supplier", doctype: "Supplier" };
|
||||
|
||||
erpnext.toggle_serial_batch_fields(frm);
|
||||
erpnext.accounts.ledger_preview.show_accounting_ledger_preview(frm);
|
||||
erpnext.accounts.ledger_preview.show_stock_ledger_preview(frm);
|
||||
|
||||
if (frm.doc.docstatus === 1) {
|
||||
frm.add_custom_button(
|
||||
__("Stock Ledger"),
|
||||
|
||||
@@ -9,6 +9,10 @@ from frappe.utils import add_days, cint, flt, nowtime, today
|
||||
|
||||
import erpnext
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||
from erpnext.controllers.ledger_preview import (
|
||||
get_accounting_ledger_preview,
|
||||
get_stock_ledger_preview,
|
||||
)
|
||||
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||
from erpnext.controllers.tests.test_subcontracting_controller import (
|
||||
get_rm_items,
|
||||
@@ -374,6 +378,38 @@ class TestSubcontractingReceipt(ERPNextTestSuite):
|
||||
self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name))
|
||||
frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1)
|
||||
|
||||
def test_ledger_preview(self):
|
||||
sco = get_subcontracting_order(
|
||||
company="_Test Company with perpetual inventory",
|
||||
warehouse="Stores - TCP1",
|
||||
supplier_warehouse="Work In Progress - TCP1",
|
||||
)
|
||||
rm_items = get_rm_items(sco.supplied_items)
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
make_stock_transfer_entry(
|
||||
sco_no=sco.name,
|
||||
rm_items=rm_items,
|
||||
itemwise_details=copy.deepcopy(itemwise_details),
|
||||
)
|
||||
|
||||
scr = make_subcontracting_receipt(sco.name)
|
||||
scr.save()
|
||||
|
||||
gl_columns, gl_data = get_accounting_ledger_preview(
|
||||
scr, frappe._dict(company=scr.company, include_dimensions=1)
|
||||
)
|
||||
scr.reload()
|
||||
sl_columns, sl_data = get_stock_ledger_preview(scr, frappe._dict(company=scr.company))
|
||||
|
||||
self.assertTrue(gl_columns)
|
||||
self.assertTrue(gl_data)
|
||||
self.assertTrue(sl_columns)
|
||||
self.assertTrue(sl_data)
|
||||
self.assertFalse(frappe.db.exists("GL Entry", {"voucher_type": scr.doctype, "voucher_no": scr.name}))
|
||||
self.assertFalse(
|
||||
frappe.db.exists("Stock Ledger Entry", {"voucher_type": scr.doctype, "voucher_no": scr.name})
|
||||
)
|
||||
|
||||
def test_subcontracting_receipt_gl_entry_with_different_rm_expense_accounts(self):
|
||||
service_items = [
|
||||
{
|
||||
@@ -1732,6 +1768,10 @@ class TestSubcontractingReceipt(ERPNextTestSuite):
|
||||
scr.items[0].batch_no = batch_no
|
||||
|
||||
scr.save()
|
||||
get_accounting_ledger_preview(scr, frappe._dict(company=scr.company, include_dimensions=1))
|
||||
scr.reload()
|
||||
self.assertFalse(scr.items[0].serial_and_batch_bundle)
|
||||
|
||||
scr.submit()
|
||||
scr.reload()
|
||||
self.assertTrue(scr.items[0].serial_and_batch_bundle)
|
||||
|
||||
Reference in New Issue
Block a user