refactor(stock): drop 7 in-repo-only StockController delegators

Remove the delegators whose only callers were in-repo StockController subclasses,
repointing every caller to the owning service / free function:

- validate_warehouse_of_sabb, validate_duplicate_serial_and_batch_bundle,
  validate_serialized_batch, clean_serial_nos -> SerialBatchBundleService
- update_inventory_dimensions -> StockLedgerService
- validate_putaway_capacity -> putaway_rule.validate_putaway_capacity (free fn)
- set_landed_cost_voucher_amount -> landed_cost_voucher.set_landed_cost_voucher_amount

Callers repointed: StockController.validate() (base), StockEntry.validate(),
StockReconciliation (validate + reconciliation SLE build), BuyingController.validate(),
and the Landed Cost Voucher submit (doc.set_landed_cost_voucher_amount on the receipt).

Verified green: ledger snapshots, stock_entry (91), stock_reconciliation (34),
landed_cost_voucher (15), subcontracting_receipt (32), delivery_note (71).
This commit is contained in:
Nabin Hait
2026-06-05 13:32:04 +05:30
parent 6a064765d1
commit 8db05fc4da
5 changed files with 37 additions and 53 deletions

View File

@@ -35,6 +35,10 @@ class BuyingController(SubcontractingController):
self.flags.ignore_permlevel_for_fields = ["buying_price_list", "price_list_currency"]
def validate(self):
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
set_landed_cost_voucher_amount,
)
self.set_rate_for_standalone_debit_note()
super().validate()
@@ -59,7 +63,7 @@ class BuyingController(SubcontractingController):
self.validate_rejected_warehouse()
self.validate_accepted_rejected_qty()
validate_for_items(self)
self.set_landed_cost_voucher_amount()
set_landed_cost_voucher_amount(self)
if self.doctype in ("Purchase Receipt", "Purchase Invoice"):
self.update_valuation_rate()

View File

@@ -37,33 +37,33 @@ from erpnext.stock.stock_ledger import get_items_to_be_repost
class StockController(AccountsController):
def validate(self):
from erpnext.stock.doctype.putaway_rule.putaway_rule import validate_putaway_capacity
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
sbb = SerialBatchBundleService(self)
super().validate()
if self.docstatus == 0:
for table_name in ["items", "packed_items", "supplied_items"]:
self.validate_duplicate_serial_and_batch_bundle(table_name)
sbb.validate_duplicate_serial_and_batch_bundle(table_name)
if not self.get("is_return"):
self.validate_inspection()
self.validate_warehouse_of_sabb()
self.validate_serialized_batch()
self.clean_serial_nos()
sbb.validate_warehouse_of_sabb()
sbb.validate_serialized_batch()
sbb.clean_serial_nos()
self.validate_customer_provided_item()
self.set_rate_of_stock_uom()
StockInternalTransferService(self).validate_internal_transfer()
self.validate_putaway_capacity()
validate_putaway_capacity(self)
self.reset_conversion_factor()
def on_update(self):
super().on_update()
self.check_zero_rate()
def validate_warehouse_of_sabb(self):
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
return SerialBatchBundleService(self).validate_warehouse_of_sabb()
def reset_conversion_factor(self):
for row in self.get("items"):
if row.uom != row.stock_uom:
@@ -118,11 +118,6 @@ class StockController(AccountsController):
if non_exists_items:
frappe.throw(_("Items {0} do not exist in the Item master.").format(", ".join(non_exists_items)))
def validate_duplicate_serial_and_batch_bundle(self, table_name):
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
return SerialBatchBundleService(self).validate_duplicate_serial_and_batch_bundle(table_name)
def get_item_wise_inventory_account_map(self):
inventory_account_map = frappe._dict()
for table in ["items", "packed_items", "supplied_items"]:
@@ -207,16 +202,6 @@ class StockController(AccountsController):
)
make_gl_entries(gl_entries, from_repost=from_repost)
def validate_serialized_batch(self):
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
return SerialBatchBundleService(self).validate_serialized_batch()
def clean_serial_nos(self):
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
return SerialBatchBundleService(self).clean_serial_nos()
def make_bundle_using_old_serial_batch_fields(self, table_name=None, via_landed_cost_voucher=False):
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
@@ -277,13 +262,6 @@ class StockController(AccountsController):
return StockLedgerService(self).get_sl_entries(d, args)
def set_landed_cost_voucher_amount(self):
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
set_landed_cost_voucher_amount,
)
return set_landed_cost_voucher_amount(self)
def get_item_account_wise_lcv_entries(self):
from erpnext.stock.doctype.landed_cost_voucher.landed_cost_voucher import (
get_item_account_wise_lcv_entries,
@@ -291,11 +269,6 @@ class StockController(AccountsController):
return get_item_account_wise_lcv_entries(self)
def update_inventory_dimensions(self, row, sl_dict) -> None:
from erpnext.stock.services.stock_ledger import StockLedgerService
return StockLedgerService(self).update_inventory_dimensions(row, sl_dict)
def make_sl_entries(self, sl_entries, allow_negative_stock=False, via_landed_cost_voucher=False):
from erpnext.stock.services.stock_ledger import StockLedgerService
@@ -386,11 +359,6 @@ class StockController(AccountsController):
for d in self.get("items"):
d.stock_uom_rate = d.rate / (d.conversion_factor or 1)
def validate_putaway_capacity(self):
from erpnext.stock.doctype.putaway_rule.putaway_rule import validate_putaway_capacity
return validate_putaway_capacity(self)
def repost_future_sle_and_gle(self, force=False, via_landed_cost_voucher=False):
from erpnext.stock.services.stock_ledger import StockLedgerService

View File

@@ -315,7 +315,7 @@ class LandedCostVoucher(Document):
self.validate_asset_qty_and_status(d.receipt_document_type, doc)
# set landed cost voucher amount in pr item
doc.set_landed_cost_voucher_amount()
set_landed_cost_voucher_amount(doc)
if d.receipt_document_type == "Subcontracting Receipt":
doc.calculate_items_qty_and_amount()

View File

@@ -265,17 +265,22 @@ class StockEntry(StockController, SubcontractingInwardController):
)
def validate(self):
from erpnext.stock.doctype.putaway_rule.putaway_rule import validate_putaway_capacity
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
sbb = SerialBatchBundleService(self)
if self.purpose_cls:
self.purpose_cls(self).validate()
self.validate_duplicate_serial_and_batch_bundle("items")
sbb.validate_duplicate_serial_and_batch_bundle("items")
self.validate_posting_time()
self.validate_item()
self.validate_customer_provided_item()
self.set_transfer_qty()
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", "transfer_qty")
self.validate_warehouse_of_sabb()
sbb.validate_warehouse_of_sabb()
self.validate_source_stock_entry()
self.validate_bom()
self.set_process_loss_qty()
@@ -294,11 +299,11 @@ class StockEntry(StockController, SubcontractingInwardController):
self.validate_difference_account()
self.validate_job_card_item()
self.set_purpose_for_stock_entry()
self.clean_serial_nos()
sbb.clean_serial_nos()
self.remove_fg_completed_qty()
self.validate_serialized_batch()
sbb.validate_serialized_batch()
self.calculate_rate_and_amount()
self.validate_putaway_capacity()
validate_putaway_capacity(self)
self.validate_closed_subcontracting_order()
super().validate_subcontracting_inward()

View File

@@ -65,6 +65,11 @@ class StockReconciliation(StockController):
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
def validate(self):
from erpnext.stock.doctype.putaway_rule.putaway_rule import validate_putaway_capacity
from erpnext.stock.services.serial_batch_bundle import SerialBatchBundleService
sbb = SerialBatchBundleService(self)
self.validate_items_exist()
if not self.expense_account:
self.expense_account = frappe.get_cached_value(
@@ -75,16 +80,16 @@ class StockReconciliation(StockController):
self.validate_posting_time()
self.set_current_serial_and_batch_bundle()
self.set_new_serial_and_batch_bundle()
self.validate_duplicate_serial_and_batch_bundle("items")
sbb.validate_duplicate_serial_and_batch_bundle("items")
self.remove_items_with_no_change()
self.validate_data()
self.change_row_indexes()
self.validate_expense_account()
self.validate_customer_provided_item()
self.set_zero_value_for_customer_provided_items()
self.clean_serial_nos()
sbb.clean_serial_nos()
self.set_total_qty_and_amount()
self.validate_putaway_capacity()
validate_putaway_capacity(self)
self.validate_inventory_dimension()
self.validate_uom_is_integer("stock_uom", "qty")
@@ -925,7 +930,9 @@ class StockReconciliation(StockController):
data.qty_after_transaction = 0.0
data.incoming_rate = flt(row.valuation_rate)
self.update_inventory_dimensions(row, data)
from erpnext.stock.services.stock_ledger import StockLedgerService
StockLedgerService(self).update_inventory_dimensions(row, data)
return data