mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-13 09:10:36 +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.
|
"""Read-side GL / Stock Ledger preview helpers.
|
||||||
|
|
||||||
A dry-run consumer of the posting path, shared across accounts and stock vouchers
|
A dry-run consumer of the posting path, shared across accounts and stock vouchers
|
||||||
(Sales/Purchase Invoice, Payment Entry, Delivery Note, Purchase Receipt, Stock
|
(Sales/Purchase Invoice, Payment Entry, Delivery Note, Purchase Receipt,
|
||||||
Entry): it submits-in-memory, reads the resulting GL/SLE entries and formats them
|
Subcontracting Receipt, Stock Entry): it submits-in-memory, reads the resulting
|
||||||
for the datatable preview, then rolls back. Lives separately from the posting
|
GL/SLE entries and formats them for the datatable preview, then rolls back. Lives
|
||||||
services it orchestrates. The whitelisted ``show_*_preview`` entry points stay on
|
separately from the posting services it orchestrates. The whitelisted
|
||||||
``stock_controller`` (their dotted path is referenced from client JS).
|
``show_*_preview`` entry points stay on ``stock_controller`` (their dotted path is
|
||||||
|
referenced from client JS).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
from erpnext import get_company_currency
|
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):
|
def get_accounting_ledger_preview(doc, filters):
|
||||||
from erpnext.accounts.report.general_ledger.general_ledger import get_columns as get_gl_columns
|
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:
|
try:
|
||||||
doc.docstatus = 1
|
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.update_stock_ledger()
|
||||||
|
|
||||||
doc.make_gl_entries()
|
doc.make_gl_entries()
|
||||||
@@ -82,13 +88,13 @@ def get_stock_ledger_preview(doc, filters):
|
|||||||
"stock_value_difference",
|
"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
|
# 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.
|
# the savepoint so the preview never persists anything, regardless of caller.
|
||||||
frappe.db.savepoint("ledger_preview")
|
frappe.db.savepoint("ledger_preview")
|
||||||
try:
|
try:
|
||||||
doc.docstatus = 1
|
doc.docstatus = 1
|
||||||
doc.make_bundle_using_old_serial_batch_fields()
|
make_serial_and_batch_bundles_for_preview(doc)
|
||||||
doc.update_stock_ledger()
|
doc.update_stock_ledger()
|
||||||
|
|
||||||
columns = get_sl_columns(filters)
|
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)
|
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):
|
def get_columns(raw_columns, fields, currency):
|
||||||
columns = []
|
columns = []
|
||||||
for source_column in raw_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" };
|
frappe.dynamic_link = { doc: frm.doc, fieldname: "supplier", doctype: "Supplier" };
|
||||||
|
|
||||||
erpnext.toggle_serial_batch_fields(frm);
|
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) {
|
if (frm.doc.docstatus === 1) {
|
||||||
frm.add_custom_button(
|
frm.add_custom_button(
|
||||||
__("Stock Ledger"),
|
__("Stock Ledger"),
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ from frappe.utils import add_days, cint, flt, nowtime, today
|
|||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
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.sales_and_purchase_return import make_return_doc
|
||||||
from erpnext.controllers.tests.test_subcontracting_controller import (
|
from erpnext.controllers.tests.test_subcontracting_controller import (
|
||||||
get_rm_items,
|
get_rm_items,
|
||||||
@@ -374,6 +378,38 @@ class TestSubcontractingReceipt(ERPNextTestSuite):
|
|||||||
self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name))
|
self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name))
|
||||||
frappe.db.set_single_value("Stock Settings", "use_serial_batch_fields", 1)
|
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):
|
def test_subcontracting_receipt_gl_entry_with_different_rm_expense_accounts(self):
|
||||||
service_items = [
|
service_items = [
|
||||||
{
|
{
|
||||||
@@ -1732,6 +1768,10 @@ class TestSubcontractingReceipt(ERPNextTestSuite):
|
|||||||
scr.items[0].batch_no = batch_no
|
scr.items[0].batch_no = batch_no
|
||||||
|
|
||||||
scr.save()
|
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.submit()
|
||||||
scr.reload()
|
scr.reload()
|
||||||
self.assertTrue(scr.items[0].serial_and_batch_bundle)
|
self.assertTrue(scr.items[0].serial_and_batch_bundle)
|
||||||
|
|||||||
Reference in New Issue
Block a user