fix: unable to submit subcontracted job card (backport #55537) (#55540)

* fix: unable to submit subcontracted job card (#55537)

(cherry picked from commit 0a49403838)

# Conflicts:
#	erpnext/controllers/subcontracting_controller.py

* chore: resolve conflicts

---------

Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
This commit is contained in:
mergify[bot]
2026-06-02 10:47:30 +00:00
committed by GitHub
parent 072a853fad
commit ceb10422ae
5 changed files with 40 additions and 20 deletions

View File

@@ -7,6 +7,7 @@ from collections import defaultdict
import frappe import frappe
from frappe import _ from frappe import _
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from frappe.utils import cint, flt, get_link_to_form from frappe.utils import cint, flt, get_link_to_form
@@ -1568,7 +1569,13 @@ def make_return_stock_entry_for_subcontract(
@frappe.whitelist() @frappe.whitelist()
def get_materials_from_supplier(subcontract_order, rm_details, order_doctype="Subcontracting Order"): def get_materials_from_supplier(source_name: str, target_doc: Document | str | None = None):
args = frappe.flags.args or {}
subcontract_order = args.get("subcontract_order") or source_name
rm_details = args.get("rm_details")
order_doctype = args.get("order_doctype") or "Subcontracting Order"
if isinstance(rm_details, str): if isinstance(rm_details, str):
rm_details = json.loads(rm_details) rm_details = json.loads(rm_details)

View File

@@ -347,7 +347,12 @@ class TestSubcontractingController(ERPNextTestSuite):
sco.load_from_db() sco.load_from_db()
self.assertEqual(sco.supplied_items[0].consumed_qty, 5) self.assertEqual(sco.supplied_items[0].consumed_qty, 5)
doc = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items]) frappe.flags.args = frappe._dict(
subcontract_order=sco.name,
rm_details=[d.name for d in sco.supplied_items],
order_doctype=sco.doctype,
)
doc = get_materials_from_supplier(sco.name)
doc.save() doc.save()
self.assertEqual(doc.items[0].qty, 1) self.assertEqual(doc.items[0].qty, 1)
self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC") self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC")
@@ -404,7 +409,12 @@ class TestSubcontractingController(ERPNextTestSuite):
sco.load_from_db() sco.load_from_db()
self.assertEqual(sco.supplied_items[0].consumed_qty, 5) self.assertEqual(sco.supplied_items[0].consumed_qty, 5)
doc = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items]) frappe.flags.args = frappe._dict(
subcontract_order=sco.name,
rm_details=[d.name for d in sco.supplied_items],
order_doctype=sco.doctype,
)
doc = get_materials_from_supplier(sco.name)
self.assertEqual(doc.items[0].qty, 1) self.assertEqual(doc.items[0].qty, 1)
self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC") self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC")
self.assertEqual(doc.items[0].t_warehouse, "_Test Warehouse - _TC") self.assertEqual(doc.items[0].t_warehouse, "_Test Warehouse - _TC")
@@ -1133,7 +1143,12 @@ class TestSubcontractingController(ERPNextTestSuite):
sco.load_from_db() sco.load_from_db()
self.assertEqual(sco.supplied_items[0].consumed_qty, 5) self.assertEqual(sco.supplied_items[0].consumed_qty, 5)
doc = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items]) frappe.flags.args = frappe._dict(
subcontract_order=sco.name,
rm_details=[d.name for d in sco.supplied_items],
order_doctype=sco.doctype,
)
doc = get_materials_from_supplier(sco.name)
self.assertEqual(doc.items[0].qty, 1) self.assertEqual(doc.items[0].qty, 1)
self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC") self.assertEqual(doc.items[0].s_warehouse, "_Test Warehouse 1 - _TC")
self.assertEqual(doc.items[0].t_warehouse, "_Test Warehouse - _TC") self.assertEqual(doc.items[0].t_warehouse, "_Test Warehouse - _TC")

View File

@@ -176,7 +176,7 @@ class JobCard(Document):
self.validate_semi_finished_goods() self.validate_semi_finished_goods()
def validate_semi_finished_goods(self): def validate_semi_finished_goods(self):
if not self.track_semi_finished_goods: if not self.track_semi_finished_goods or self.is_subcontracted:
return return
if self.items and not self.transferred_qty and not self.skip_material_transfer: if self.items and not self.transferred_qty and not self.skip_material_transfer:
@@ -1578,9 +1578,7 @@ def make_subcontracting_po(source_name, target_doc=None):
"Job Card", "Job Card",
source_name, source_name,
{ {
"Job Card": { "Job Card": {"doctype": "Purchase Order", "field_no_map": ["naming_series"]},
"doctype": "Purchase Order",
},
}, },
target_doc, target_doc,
set_missing_values, set_missing_values,

View File

@@ -578,7 +578,7 @@ frappe.ui.form.on("Subcontracting Order", {
}, },
get_materials_from_supplier: function (frm) { get_materials_from_supplier: function (frm) {
let sco_rm_details = []; const sco_rm_details = [];
if (frm.doc.status != "Closed" && frm.doc.supplied_items) { if (frm.doc.status != "Closed" && frm.doc.supplied_items) {
frm.doc.supplied_items.forEach((d) => { frm.doc.supplied_items.forEach((d) => {
@@ -592,21 +592,16 @@ frappe.ui.form.on("Subcontracting Order", {
frm.add_custom_button( frm.add_custom_button(
__("Return of Components"), __("Return of Components"),
() => { () => {
frm.call({ frappe.model.open_mapped_doc({
method: "erpnext.controllers.subcontracting_controller.get_materials_from_supplier", method: "erpnext.controllers.subcontracting_controller.get_materials_from_supplier",
freeze: true, frm: frm,
freeze_message: __("Creating Stock Entry"),
args: { args: {
subcontract_order: frm.doc.name, subcontract_order: frm.doc.name,
rm_details: sco_rm_details, rm_details: sco_rm_details,
order_doctype: cur_frm.doc.doctype, order_doctype: frm.doc.doctype,
},
callback: function (r) {
if (r && r.message) {
const doc = frappe.model.sync(r.message);
frappe.set_route("Form", doc[0].doctype, doc[0].name);
}
}, },
freeze: true,
freeze_message: __("Creating Return of Components ..."),
}); });
}, },
__("Create") __("Create")

View File

@@ -554,7 +554,12 @@ class TestSubcontractingOrder(ERPNextTestSuite):
scr.submit() scr.submit()
# Get RM from Supplier # Get RM from Supplier
ste = get_materials_from_supplier(sco.name, [d.name for d in sco.supplied_items]) frappe.flags.args = frappe._dict(
subcontract_order=sco.name,
rm_details=[d.name for d in sco.supplied_items],
order_doctype=sco.doctype,
)
ste = get_materials_from_supplier(sco.name)
ste.save() ste.save()
ste.submit() ste.submit()