Commit Graph

420 Commits

Author SHA1 Message Date
Mihir Kandoi
432b4f7f86 refactor: parse native JSON request args in controllers/stock_controller.py
Use frappe.parse_json instead of json.loads so the whitelisted endpoints
accept native JSON types (list/dict/bool) in addition to JSON strings.
2026-06-24 20:37:32 +05:30
Mihir Kandoi
8138f5aecd refactor(controllers): convert StockController future-SLE/GL checks to qb/ORM
- make_gl_entries_on_cancel: raw GL Entry existence select -> frappe.db.exists.
- future_sle_exists: raw GROUP BY count -> frappe.qb Count with Criterion.any,
  and get_conditions_to_validate_future_sle builds qb Criterion objects
  (warehouse == x & item_code.isin(...)) instead of escaped SQL strings.

Parity-preserving and valid on Postgres. Surgical re-apply: develop's
check_item_quality_inspection fix (`return items if doctype == "Stock Entry"
else []`) is preserved (the staging branch predated and would have reverted
it).

Adds a test asserting future_sle_exists detects a later SLE for the same
item/warehouse on both engines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 05:40:30 +05:30
Mihir Kandoi
465446bb79 refactor(controllers): convert sales/purchase return lookups to qb/ORM
validate_returned_items used a raw frappe.db.sql with a string-built column
list (and a separate Packed Item select); get_already_returned_items used a
raw GROUP BY sum. Convert both to frappe.get_all / frappe.qb (Sum(Abs(...))
with an explicit groupby). The qb GROUP BY mirrors the original
`group by item_code, <field>`, so it is parity-preserving (not a behaviour
change) and valid on Postgres.

Surgical re-apply: develop's `is_debit_note = 0` credit-note fix in
make_return_doc is preserved (the staging branch predated and would have
reverted it).

Adds a test (Delivery Note -> sales return) exercising validate_returned_items
and get_already_returned_items on both engines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 05:40:30 +05:30
Sudharsanan11
dceb9a3c6c fix(stock): enable quality inspection for all Stock Entry purposes
- Remove `depends_on` restriction from `inspection_required` field so it
  is visible for all Stock Entry purposes, not just Manufacture
- Fix `check_item_quality_inspection` to return items for Stock Entry
  (was returning [] for unknown doctypes, blocking QI creation flow)
- Fix `inspection_type` in transaction.js to be purpose-aware: Manufacture
  and Material Receipt → "Incoming"; all other purposes → "Outgoing"
2026-06-16 12:34:55 +05:30
Nabin Hait
7d72d21bbe refactor(stock): add _service suffix to serial_batch_bundle and quality_inspection modules
Consistent service-module naming: serial_batch_bundle_service.py /
quality_inspection_service.py (matching stock_ledger_service.py). Importers updated;
engine-module imports (stock.serial_batch_bundle) untouched.
2026-06-05 15:16:41 +05:30
Nabin Hait
b41eb6876a refactor(stock): rename stock_ledger service module to stock_ledger_service
Avoids basename collision with the core SLE engine erpnext/stock/stock_ledger.py
(the service even imports make_sl_entries from it). File now maps 1:1 to its class,
StockLedgerService.
2026-06-05 14:59:41 +05:30
Nabin Hait
c5ff1009b2 refactor: relocate ledger_preview to controllers (cross-cutting, not stock-only)
The preview feature serves both accounts and stock vouchers (SI/PI/PE + DN/PR/SE)
and its show_*_preview entry points live in controllers/stock_controller, so the
cohesive GL+SLE preview module belongs in controllers/, not stock/services/. Pure
move + import-path update; GL and stock previews stay together (shared get_columns/
get_data formatters; read-side, kept out of the write-path services).

Verified: ledger snapshots green; module resolves at new path.
2026-06-05 14:41:58 +05:30
Nabin Hait
b82b2c2ebd refactor(stock): use central erpnext/exceptions.py for stock exceptions
Merge the stock exceptions into the existing app-wide erpnext/exceptions.py (under a
'# stock' section) instead of a separate erpnext/stock/exceptions.py, matching the
established convention. stock_controller still re-exports them for backward
compatibility; services import from erpnext.exceptions.

Verified: ledger snapshots, quality inspection suite, stock_entry batch-expiry stay green.
2026-06-05 14:34:27 +05:30
Nabin Hait
8db05fc4da 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).
2026-06-05 13:32:04 +05:30
Nabin Hait
6a064765d1 refactor(stock): drop zero-caller StockController delegators
Re-audited the kept delegators for true external callers. Two had none:
- has_landed_cost_amount: no caller anywhere (the landed_cost_voucher.py free
  function is what the composers use) — pure dead delegator, removed.
- validate_internal_transfer: only StockController.validate() called it; inline that
  one hook to StockInternalTransferService(self).validate_internal_transfer() and
  remove the delegator.

All other kept delegators have real external/subclass/run_method callers and remain
as the stock extension contract.

Verified: ledger snapshots + DN/PR internal-transfer suites stay green.
2026-06-05 12:46:09 +05:30
Nabin Hait
78d5fbaca4 refactor(stock): address layering/robustness review findings (#8, #9, #10)
#8 ledger_preview: wrap the submit-in-memory dry run in a savepoint inside
get_accounting_ledger_preview / get_stock_ledger_preview and roll back to it in a
finally, so the preview never persists entries regardless of caller (previously
only the whitelisted show_*_preview wrappers' full rollback made it safe).

#9 exceptions: move BatchExpiredError and the QualityInspection* errors into a new
erpnext/stock/exceptions.py and re-export them from stock_controller for backward
compatibility (job_card and tests still import from the controller; identity is
preserved). Services now import from the neutral module instead of back from the
controller they were extracted out of.

#10 quality inspection: extract the duplicated doctype->inspection-field map into a
single INSPECTION_FIELDNAME_MAP constant in the service, consumed by both
validate_inspection and check_item_quality_inspection.

Verified: ledger snapshots, quality inspection suite, stock_entry batch-expiry test
stay green; preview smoke-tested to persist nothing and not roll back the caller.
2026-06-05 12:29:55 +05:30
Nabin Hait
d1fd91a542 refactor(stock): extract ledger preview helpers to ledger_preview module
Move the read-side GL/SLE preview helpers (get_accounting_ledger_preview,
get_stock_ledger_preview, get_sl_entries_for_preview, get_gl_entries_for_preview,
get_columns, get_data) into erpnext/stock/services/ledger_preview.py. The
whitelisted show_accounting_ledger_preview / show_stock_ledger_preview entry points
stay in stock_controller (client JS hardcodes their dotted path) and call the
relocated helpers.

Behaviour-preserving: ledger characterization snapshots stay green.
2026-06-04 16:51:17 +05:30
Nabin Hait
8e41e75d89 refactor(stock): relocate landed-cost and putaway logic to owning doctypes
These clusters are really other doctypes' logic parked on StockController, so they
move next to the doctype that owns them rather than into a stock service:

- set_landed_cost_voucher_amount / get_item_account_wise_lcv_entries /
  has_landed_cost_amount -> landed_cost_voucher.py (free functions). Controller keeps
  thin delegators (called as doc.X from 4 GL composers, buying_controller and the LCV
  doctype).
- validate_putaway_capacity -> putaway_rule.py (free function, next to
  get_available_putaway_capacity it already used). Controller keeps a delegator
  (validate hook + Stock Entry/Reconciliation); prepare_over_receipt_message becomes a
  private helper there.

Drops now-unused Sum/defaultdict imports from stock_controller.

Behaviour-preserving: ledger snapshots, putaway and landed-cost suites stay green.
2026-06-04 16:22:38 +05:30
Nabin Hait
7c2406077a refactor(stock): extract StockInternalTransferService from StockController
Move internal-transfer warehouse/currency/packed-item/over-receipt-qty validation
into erpnext/stock/services/internal_transfer.py as a delegating service. This is
the stock-side counterpart to accounts/services/internal_transfer.py (party/rate/
pricing). validate_internal_transfer keeps a controller delegator (validate hook);
the other 7 methods are internal-only. The is_internal_transfer() predicate is
already consolidated on AccountsController.

Behaviour-preserving: ledger snapshots + DN/PR internal-transfer suites stay green.
2026-06-04 16:05:42 +05:30
Nabin Hait
926bdf5a20 refactor(stock): extract QualityInspectionService from StockController
Move quality-inspection validation (validate_inspection + validate_qi_presence/
submission/rejection) into erpnext/stock/services/quality_inspection.py as a
delegating service. validate_inspection keeps a controller delegator (called from
validate() and 3 other doctypes); the three row-level helpers are internal-only.
The whitelisted module fns check_item_quality_inspection / make_quality_inspections
stay in stock_controller (stable endpoint paths).

Behaviour-preserving: ledger snapshots + quality inspection suite stay green.
2026-06-04 15:54:34 +05:30
Nabin Hait
b447cbc3c1 refactor(stock): move GL-building helpers onto BaseStockGLComposer
Relocate get_voucher_details, check_expense_account and get_debit_field_precision
from StockController to BaseStockGLComposer, where they are only used (by compose()
and AssetCapitalizationGLComposer). Call sites flipped from doc.X to self.X.

Inventory-account resolution (get_inventory_account_map/_dict, etc.) stays on the
controller: it is a doc-contract method called as doc.X from non-stock-composer code
(PI controller/composer, accounts/utils, repost_accounting_ledger), so it cannot fold
into BaseStockGLComposer. make_gl_entries / make_gl_entries_on_cancel / add_gl_entry
likewise stay (contract entry points).

Behaviour-preserving: ledger snapshots, subcontracting receipt and asset
capitalization suites stay green.
2026-06-04 15:50:32 +05:30
Nabin Hait
4affdd51f6 refactor(stock): extract StockLedgerService from StockController
Move SLE building and reposting (get_sl_entries, update_inventory_dimensions,
get_stock_ledger_details, get_items_and_warehouses, make_sl_entries,
repost_future_sle_and_gle) into erpnext/stock/services/stock_ledger.py as a
delegating service. All six keep thin controller delegators (each has external
callers). The repost helper *functions* stay module-level in stock_controller
(imported widely); the service calls them. Also drop import orphaned by this and
the prior bundle extraction.

Behaviour-preserving: ledger characterization snapshots and the repost item
valuation suite stay green.
2026-06-04 15:35:04 +05:30
Nabin Hait
a26d8d448c refactor(stock): extract SerialBatchBundleService from StockController
Move serial & batch bundle handling (creation, validation, return bundles,
teardown) out of StockController into erpnext/stock/services/serial_batch_bundle.py
as a delegating service. The controller keeps thin delegators for the 10 methods
reached from other doctypes or run_method; the 12 internal-only helpers live in
the service. make_bundle_for_material_transfer stays a module fn in stock_controller
(imported by stock/serial_batch_bundle.py).

Behaviour-preserving: ledger characterization snapshots and the full Serial and
Batch Bundle test suite stay green.
2026-06-04 15:00:44 +05:30
Nabin Hait
dfe3280737 Merge remote-tracking branch 'upstream/develop' into erpnext-refactoring
# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.py
#	erpnext/buying/doctype/purchase_order/purchase_order.py
#	erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
#	erpnext/controllers/accounts_controller.py
#	erpnext/selling/doctype/sales_order/sales_order.py
#	erpnext/selling/doctype/sales_order/test_sales_order.py
#	erpnext/stock/doctype/delivery_note/delivery_note.py
#	erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
2026-06-03 13:23:03 +05:30
Shubh Doshi
5074597d00 perf: batch status check for on-hold/closed documents, remove N+1 queries (#54798) 2026-06-03 11:50:49 +05:30
Nabin Hait
04443ae29e Merge upstream/develop into erpnext-refactoring
Resolve 4 conflicts from Phase 7 service/mapper extraction vs upstream:
- asset.py: take extraction; repoint dangling make_asset_movement JS to mapper
- job_card: port upstream field_no_map(naming_series) into mapper.make_subcontracting_po
- sales_order: port upstream rows-index fix into mapper.make_delivery_note
- sales_invoice (Phase 7): take service delegations; port upstream SQL->QB/ORM
  changes for get_warehouse, get_all_mode_of_payments, get_discounting_status,
  clear_unallocated_mode_of_payments, and set_pos_fields(POS DN skip) into services
2026-06-03 11:05:01 +05:30
rohitwaghchaure
ba477412ea Merge pull request #55415 from aerele/fix/support-#68706
fix(stock): allow to create quality inspection after purchase/delivery
2026-06-01 21:43:24 +05:30
Mihir Kandoi
dbcfac839c chore: rename type field to secondary_item_type (#55469) 2026-06-01 05:54:59 +00:00
Sudharsanan11
c6a88ab1d2 fix(stock): allow to create quality inspection after purchase/delivery 2026-06-01 10:37:25 +05:30
Nabin Hait
983d80f7c5 refactor(accounts): merge gl_entry_builder.py into base_gl_composer.py
The free functions (get_gl_dict, add_gl_entry, get_voucher_subtype, etc.) live
in the same module as BaseGLComposer — they are all about building GL entries,
so there is no reason to split them across two files. Removes gl_entry_builder.py
and updates all import references to base_gl_composer.
2026-05-27 22:32:06 +05:30
Nabin Hait
cba6a31497 refactor(accounts): extract get_gl_dict and add_gl_entry into gl_entry_builder.py
Move the get_gl_dict/add_gl_entry logic from AccountsController/StockController
into free functions in accounts/services/gl_entry_builder.py with doc as first arg.
BaseGLComposer gains get_gl_dict and add_gl_entry methods that delegate to the free
functions — GL composers now call self.get_gl_dict/self.add_gl_entry directly
without going through the doc. AccountsController and StockController keep thin
shims for backward compatibility with unrefactored callers.

Also move update_gl_dict_with_regional_fields and update_gl_dict_with_app_based_fields
to gl_entry_builder.py, re-exporting them from accounts_controller.py to avoid a
circular import.
2026-05-27 21:46:16 +05:30
Nabin Hait
b68daea365 refactor: introduce BaseStockGLComposer, slim StockController.get_gl_entries
Moves the StockController.get_gl_entries body into
erpnext/stock/services/base_stock_gl_composer.py → BaseStockGLComposer(BaseGLComposer).
compose(inventory_account_map, default_expense_account, default_cost_center) contains
all warehouse↔expense-account GL pair building and the internal-transfer rounding-diff
block; all helpers (get_inventory_account_dict, get_stock_ledger_details, etc.) remain
on self.doc and are called via doc.<method>.

StockController.get_gl_entries becomes a 3-line shim.  Delivery Note, Stock Entry, and
Stock Reconciliation continue to work unchanged — DN inherits the shim directly; SE and
SR override and call super(), which now delegates to the composer.

Verified: 22 GL snapshots byte-identical on test-erpnext-v17.
2026-05-27 14:47:19 +05:30
Pugazhendhi Velu
3364ee9274 feat(stock): add Stock Delivered But Not Billed GL entries on Delivery Note and Sales Invoice 2026-05-22 01:13:12 +05:30
rohitwaghchaure
d22cd7b856 Merge pull request #54403 from aerele/fix/support-#64052
fix(stock): ignore fetching warehouse account for asset items
2026-05-15 13:15:11 +05:30
Sudharsanan11
6fe08428c1 fix(stock): ignore fetching warehouse account for asset items 2026-04-27 18:02:06 +05:30
Mihir Kandoi
3ef6c24f07 fix: zero valuation rate popup on SI (#54376) 2026-04-18 11:44:49 +00:00
Mihir Kandoi
f1ac0376fb feat: co product by product support (#52979) 2026-03-11 14:46:36 +05:30
Mihir Kandoi
9f62ec5192 fix: allow user to make QI after submission not working 2026-03-10 13:55:49 +05:30
Mihir Kandoi
c76be620a8 Merge pull request #53037 from aerele/fix/qi-naming-rule-issue 2026-03-03 20:38:54 +05:30
Rohit Waghchaure
9b8f685c82 fix: validate warehouse of SABB for draft entry 2026-03-02 13:41:20 +05:30
kavin-114
74def423ed fix(stock): pass company to avoid document naming rule issue in QI
When a Document Naming Rule is configured in QI with a condition based on the company,
the system was not passing the company value properly. As a result, the naming rule
condition was skipped and the document name was generated using the default series.

This fix ensures that the company is passed correctly so that the configured
Document Naming Rule is evaluated and applied as expected.
2026-02-28 13:10:30 +05:30
khushi8112
021aa63e24 fix: incorrect type hint 2026-02-23 12:49:46 +05:30
khushi8112
7100d61f3c refactor: add type hints to controller functions 2026-02-23 12:49:46 +05:30
Navin-S-R
5c8cb1e7ec feat: show formatted currency symbol on ledger preview 2026-02-11 17:29:20 +05:30
Mihir Kandoi
838d245215 fix: add precision to rejected batch no qty calculation 2026-01-30 10:19:35 +05:30
Mihir Kandoi
343ee9695b fix: rejected qty in PR doesn't consider conversion factor 2026-01-21 22:33:24 +05:30
Rohit Waghchaure
8d4a179a8f refactor: single table for better performance 2026-01-11 13:43:09 +05:30
Mihir Kandoi
7deb407206 fix: incorrect putaway rule validation on stock reco 2025-12-02 10:42:28 +05:30
Rohit Waghchaure
ca47ae6fd8 fix: stock reservation validation 2025-11-25 12:01:51 +05:30
Akhil Narang
1cf9f903e5 fix: adapt to query builder
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2025-11-19 21:36:37 +05:30
Rohit Waghchaure
ae0d9d1134 fix: validate reserved batches 2025-11-19 15:12:12 +05:30
Lakshit Jain
91f3c82bdf feat!: Item Wise Tax Details Table (#48692)
* fix: Add `Item Wise Tax Detail` Table and update related doctypes

* fix: remove setting item_wise_tax_details in client side

* fix: Remove redundant code for updating item_wise_tax_details after rename

* fix: Add 'dont_recompute_tax' field to Item Wise Tax Detail

* fix: update item_wise_tax_details after validations

* chore: remove redundant code from payment_entry.js

* fix: changes in POS for item_wise_tax_details

* fix: handle merge taxes

* fix: update test case and fix precision issue

* chore: remove debugging statement

* chore: remove redundant import

* chore: linters

* chore: remove redundant code and minor refactor

* fix: correct function args

* fix: fix test cases

* fix: item wise sales register report

* fix: remove dont recompute from item wise tax details and calculation for deduct

* fix: do not retain old rows

* fix: added validation for item wise tax details

* fix: tax merging for pos

* fix: vat audit report(regional report)

* fix: query issue in item-wise sales register

* fix: set other_charges using temp object

* fix: precision issue in validation

* fix: changes as per failing test cases

* fix: tax merging

* fix: set no_copy for item wise tax detail

* fix: correct select field in query and other charged in item_wise_purchase_register

* fix: do not include rows with missing item or tax in merge_taxes

* fix: respect row wise rounding

* chore: remove unused import

* chore: incorrect tuple creation

* fix: handle rounding adjustment

* fix: currency option in item wise tax detail doctype

* fix: patch to migrate item_wise tax_details to table

* chore: remove item_wise_tax_detail from taxes table

* fix: use base_tax_withholding_net_total instead of tax_withholding_net_total

* fix: implemet item_wise_tax_detail for e-invoice (italy)

* fix: fetch document by doctypes in migration patch

* fix: fix multiple syntax errors and inconsistent variable usage

* fix: remove deprecated settings and update item wise tax details flag

* fix: enhance validation for item wise tax details and handle discrepancies

* fix: increase chunk size for migration and improve item-wise tax detail calculations

* fix: delete existing item-wise tax details to prevent duplicates during migration

* fix: remove unnecessary docstatus filter from tax details query

* fix: streamline validation checks in item wise tax details adjustment

* fix: update additional fields to reference item and invoice attributes in tax detail queries

* fix: Restrict tax query to the selected invoices in vat audit report

* fix: use `base_tax_withholding_net_total` for calculation in patch

* fix: set tax row_id and idx to None instead of empty strings

* fix: remove unused precision parameter from rounding differences handler

* fix: update docstatus in item_wise_tax_details as per doc

* fix: remove empty on_update method from SalesOrder class

* fix: remove empty on_update method from PurchaseOrder class

* fix: incorporate zero cutoff in tax calculation logic

* fix: increase threshold for rounding diff
2025-11-17 19:02:31 +05:30
Mihir Kandoi
9b303a2272 Merge pull request #50235 from mihir-kandoi/sre-sco
feat: stock reservation for subcontracting order
2025-11-16 13:06:21 +05:30
Rohit Waghchaure
f2ad27eb06 perf: DN submission with SABB 2025-11-10 14:01:02 +05:30
Rohit Waghchaure
076407ad70 test: test cases for item wise inventory account 2025-10-24 10:08:44 +05:30