Skip to content

refactor: stock_entry file to improve readability and maintainability#54466

Draft
rohitwaghchaure wants to merge 5 commits intofrappe:developfrom
rohitwaghchaure:revamp-stock-entry
Draft

refactor: stock_entry file to improve readability and maintainability#54466
rohitwaghchaure wants to merge 5 commits intofrappe:developfrom
rohitwaghchaure:revamp-stock-entry

Conversation

@rohitwaghchaure
Copy link
Copy Markdown
Collaborator

@rohitwaghchaure rohitwaghchaure commented Apr 22, 2026

The stock_entry.py file has grown to over 4,000 lines of code, making it difficult to read, understand, and maintain.

Screenshot 2026-04-23 at 6 13 10 PM

Redundant code

Screenshot 2026-04-24 at 3 09 22 PM image

@github-actions github-actions Bot added skip-release-notes This PR should not be mentioned in the release notes needs-tests This PR needs automated unit-tests. labels Apr 22, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

This pull request refactors manufacturing and disassembly-related logic in Stock Entry by extracting it into a new dedicated handler module. A new file erpnext/stock/doctype/stock_entry/manufacturing_handler.py is introduced containing handler classes (ManufactureHandler, MaterialTransferHandler, DisassembleHandler, BaseManufacturingHandler, StockEntrySABB) that encapsulate manufacturing, material transfer, and disassembly workflows. Approximately 1,670 lines of logic are relocated from stock_entry.py to this new module. The stock_entry.py file is updated to delegate manufacturing operations to the appropriate handlers via a purpose-to-handler mapping. UI method calls in purchase_receipt.js and job_card.py are updated to invoke handlers from the new module. The BOM DocType's backflush_based_on field is enhanced with a documentation URL, and get_backflush_based_on() is made to accept an optional bom_no parameter. Stock Entry form layout is adjusted with field reorganization and styling updates.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Key observations

The refactoring consolidates ~1,712 lines of new code into manufacturing_handler.py with multiple interdependent handler classes, exception types, and utility functions that orchestrate complex manufacturing workflows including serial/batch bundle creation, secondary item computation, job-card-based allocations, and disassembly reversals. Concurrent removal of ~1,670 lines from stock_entry.py requires careful verification that all moved logic integrates correctly via handler delegation and that no functionality is lost. Changes span 8 files with heterogeneous modifications including handler delegation patterns, UI method targeting, form field reorganization, and function signature updates, demanding contextual verification across integration points.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided by the author, making it impossible to assess whether any description exists or relate to the changeset. Add a description explaining the refactoring rationale, what was moved to manufacturing_handler, and why this improves maintainability.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main refactoring objective—moving manufacturing/disassembly logic from stock_entry.py into a new manufacturing_handler module to improve code organization and maintainability.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
erpnext/stock/doctype/stock_entry/stock_entry.py (1)

296-338: ⚠️ Potential issue | 🔴 Critical

validate_work_order() call on line 249 will raise AttributeError on every Stock Entry save.

validate() calls self.validate_work_order() (line 249), but this method is no longer defined in StockEntry or its parent StockController; it was moved to ManufactureHandler in manufacturing_handler.py. The instance method resolution will fail because StockEntry does not inherit from ManufactureHandler. Move validate_work_order() back to the StockEntry class, or route the call through the appropriate handler based on the entry's purpose.

Additionally, get_completed_job_card_qty() (line 2286) and the import of get_batch_nos (line 59) appear to have no callers and can be removed as cleanup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@erpnext/stock/doctype/stock_entry/stock_entry.py` around lines 296 - 338, The
call to self.validate_work_order() from StockEntry.validate is failing because
validate_work_order() was moved out of StockEntry/StockController into
ManufactureHandler; restore behavior by either reintroducing a
validate_work_order(self) instance method on the StockEntry class that delegates
to ManufactureHandler (e.g., ManufactureHandler(self).validate_work_order())
when purpose indicates manufacturing/repack disassemble, or change the call site
in validate() to route through ManufactureHandler based on self.purpose; also
remove the dead helpers get_completed_job_card_qty() and the unused import
get_batch_nos to clean up unused code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@erpnext/stock/doctype/stock_entry/manufacturing_handler.py`:
- Around line 346-362: The backflush_based_on property currently treats falsy
cached values as "not cached" because it checks `if not getattr(self,
"_backflush_based_on", None)`, causing repeated calls to get_backflush_based_on;
change the caching to use a sentinel (e.g., define a module/class-level _MISSING
= object()) and initialize `_backflush_based_on = _MISSING`, then in
backflush_based_on check `if self._backflush_based_on is _MISSING` and set it
from get_backflush_based_on(self.se_doc.bom_no); adjust reset to restore
`_backflush_based_on = _MISSING` so legitimate falsy returns (None/''/0) are
preserved in the cache.

In `@erpnext/stock/doctype/stock_entry/stock_entry.py`:
- Around line 2020-2037: The fallback branch that instantiates
ManufactureHandler(self) when PURPOSE_HANDLER_MAP.get(self.purpose) is falsy
currently skips handler.validate(), which bypasses
validate_posting_date_and_time(); update the logic so that any instantiated
handler (both from handler_class and the fallback ManufactureHandler created in
the elif self.bom_no: branch) has handler.validate() called before
handler.set_items() to ensure posting date/time validation runs, and as a minor
refactor move PURPOSE_HANDLER_MAP out of the get_items()/local scope into
module/class scope to avoid reconstructing it on each call.

---

Outside diff comments:
In `@erpnext/stock/doctype/stock_entry/stock_entry.py`:
- Around line 296-338: The call to self.validate_work_order() from
StockEntry.validate is failing because validate_work_order() was moved out of
StockEntry/StockController into ManufactureHandler; restore behavior by either
reintroducing a validate_work_order(self) instance method on the StockEntry
class that delegates to ManufactureHandler (e.g.,
ManufactureHandler(self).validate_work_order()) when purpose indicates
manufacturing/repack disassemble, or change the call site in validate() to route
through ManufactureHandler based on self.purpose; also remove the dead helpers
get_completed_job_card_qty() and the unused import get_batch_nos to clean up
unused code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: a937262b-c173-4581-bad1-81ecc4e590fb

📥 Commits

Reviewing files that changed from the base of the PR and between 0d2da6d and b133d7a.

📒 Files selected for processing (9)
  • erpnext/manufacturing/doctype/bom/bom.json
  • erpnext/manufacturing/doctype/bom/bom.py
  • erpnext/manufacturing/doctype/job_card/job_card.py
  • erpnext/manufacturing/doctype/work_order/work_order.py
  • erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
  • erpnext/stock/doctype/stock_entry/manufacturing_handler.py
  • erpnext/stock/doctype/stock_entry/stock_entry.js
  • erpnext/stock/doctype/stock_entry/stock_entry.json
  • erpnext/stock/doctype/stock_entry/stock_entry.py
💤 Files with no reviewable changes (1)
  • erpnext/manufacturing/doctype/work_order/work_order.py

Comment thread erpnext/stock/doctype/stock_entry/manufacturing_handler.py
Comment thread erpnext/stock/doctype/stock_entry/stock_entry.py
@rohitwaghchaure rohitwaghchaure marked this pull request as draft April 22, 2026 12:47
@rohitwaghchaure rohitwaghchaure force-pushed the revamp-stock-entry branch 11 times, most recently from d4d3f28 to b9a045c Compare April 23, 2026 12:35
@rohitwaghchaure rohitwaghchaure removed the needs-tests This PR needs automated unit-tests. label Apr 24, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 84.98294% with 176 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.45%. Comparing base (877d99c) to head (adbe9bc).
⚠️ Report is 87 commits behind head on develop.

Files with missing lines Patch % Lines
...stock/doctype/stock_entry/manufacturing_handler.py 86.60% 120 Missing ⚠️
...k/doctype/stock_entry_detail/stock_entry_detail.py 78.16% 38 Missing ⚠️
erpnext/projects/doctype/project/project.py 10.00% 9 Missing ⚠️
erpnext/stock/doctype/stock_entry/stock_entry.py 88.46% 9 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #54466      +/-   ##
===========================================
+ Coverage    79.28%   79.45%   +0.17%     
===========================================
  Files         1158     1161       +3     
  Lines       125604   126266     +662     
===========================================
+ Hits         99580   100321     +741     
+ Misses       26024    25945      -79     
Files with missing lines Coverage Δ
erpnext/manufacturing/doctype/bom/bom.py 86.90% <100.00%> (ø)
erpnext/manufacturing/doctype/job_card/job_card.py 69.41% <100.00%> (ø)
...anufacturing/doctype/work_order/test_work_order.py 98.52% <100.00%> (+<0.01%) ⬆️
...ext/manufacturing/doctype/work_order/work_order.py 82.55% <100.00%> (-0.15%) ⬇️
...next/stock/doctype/stock_entry/test_stock_entry.py 99.15% <100.00%> (ø)
...stock_reservation_entry/stock_reservation_entry.py 79.44% <100.00%> (-0.13%) ⬇️
...g_inward_order/test_subcontracting_inward_order.py 100.00% <100.00%> (ø)
erpnext/projects/doctype/project/project.py 53.68% <10.00%> (-1.33%) ⬇️
erpnext/stock/doctype/stock_entry/stock_entry.py 87.39% <88.46%> (+1.91%) ⬆️
...k/doctype/stock_entry_detail/stock_entry_detail.py 78.53% <78.16%> (-21.47%) ⬇️
... and 1 more

... and 67 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rohitwaghchaure rohitwaghchaure force-pushed the revamp-stock-entry branch 4 times, most recently from c326ab0 to f196e06 Compare April 24, 2026 14:11
self._backflush_based_on = None


class ManufactureHandler(BaseManufacturingHandler):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be ManufacturingHandler ?


self.add_to_stock_entry_detail(item_dict)

def get_subcontract_order_supplied_items(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to a separate subcontracting_handler.py ?

order_by="creation",
)

def update_batches_to_be_consume(self, batches, row, qty):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

batching_handler.py?

maybe just drop the handler suffix, since they are all in the stock_entry folder?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-release-notes This PR should not be mentioned in the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants