feat: subcontracting inward (#47728)

* feat: subcontracting inward

* feat: stock reservation

* feat: subcontracting delivery

* feat: all remaining stuff

* fix: linter errors

* fix: patch

* fix: modify stock entry type validation

* fix: customer provided item cost field mandatory validation

* fix: failing tests

* fix: failing tests

* fix: subcontracting controlller

* refactor: semi final

* refactor: final

* chore: resolve conflicts

* refactor: changes requested

* fix: reservation transfer of extra qty

* fix: consider add cost for customer provided rate field

* test: create test data

* test: subcontracted sales order (partial)

* test: fin

* fix: do not add self RM in DN created from SI

* fix: failing test case

* fix: conflicting function name

* refactor: final changes

* fix: more bugs

* perf: various and major performance improvements

* fix: consider warehouse as well in all queries

* fix: same item code with diff warehouse in manufacture entry

* refactor: readability

* fix: frontend validations

* perf: replace query inside loop with single query

* fix: set additional item flag to true when extra customer provided item is received

* fix: bugs found by coderabbit

* fix: more coderabbit bugs

* fix: add validation to disallow cancellation of manufacturing entry

* perf: use cached values wherever it makes sense

* test: fix redundant insert to child tables

* fix: consider SI return of billed self RM

* fix: bug found by coderabbit

---------

Co-authored-by: Mihir Kandoi <mihirkandoi@Mihirs-MacBook-Air.local>
This commit is contained in:
Mihir Kandoi
2025-10-14 15:00:49 +05:30
committed by GitHub
parent 9772ca75c4
commit f2b948a483
76 changed files with 4970 additions and 229 deletions

View File

@@ -95,9 +95,11 @@ class StockController(AccountsController):
"Stock Reconciliation",
]:
for item in self.get("items"):
if (item.get("valuation_rate") == 0 or item.get("incoming_rate") == 0) and item.get(
"allow_zero_valuation_rate"
) == 0:
if (
(item.get("valuation_rate") == 0 or item.get("incoming_rate") == 0)
and item.get("allow_zero_valuation_rate") == 0
and frappe.get_cached_value("Item", item.item_code, "is_stock_item")
):
frappe.toast(
_(
"Row #{0}: Item {1} has zero rate but 'Allow Zero Valuation Rate' is not enabled."
@@ -544,10 +546,14 @@ class StockController(AccountsController):
break
elif row.batch_no:
batches = frappe.get_all(
"Serial and Batch Entry", fields=["batch_no"], filters={"parent": row.serial_and_batch_bundle}
batches = sorted(
frappe.get_all(
"Serial and Batch Entry",
filters={"parent": row.serial_and_batch_bundle, "batch_no": ("is", "set")},
pluck="batch_no",
distinct=True,
)
)
batches = sorted([d.batch_no for d in batches])
if batches != [row.batch_no]:
throw_error = True