Skip to content

Commit

Permalink
feat: track Semi-finished goods (including subcontracted items) again…
Browse files Browse the repository at this point in the history
…st Job Cards (#38341)

* feat: Track Semi-finished goods (including subcontracted items) against Job Cards

* feat: option to add raw materials manually against operation
  • Loading branch information
rohitwaghchaure authored Jun 1, 2024
1 parent 24926ab commit 9e9296e
Show file tree
Hide file tree
Showing 43 changed files with 2,919 additions and 667 deletions.
10 changes: 9 additions & 1 deletion erpnext/buying/doctype/purchase_order/purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def validate_fg_item_for_subcontracting(self):
item.idx, item.fg_item
)
)
elif not frappe.get_value("Item", item.fg_item, "default_bom"):
elif not item.bom and not frappe.get_value("Item", item.fg_item, "default_bom"):
frappe.throw(
_("Row #{0}: Default BOM not found for FG Item {1}").format(
item.idx, item.fg_item
Expand Down Expand Up @@ -919,6 +919,14 @@ def get_mapped_subcontracting_order(source_name, target_doc=None):
for idx, item in enumerate(target_doc.items):
item.warehouse = source_doc.items[idx].warehouse

for idx, item in enumerate(target_doc.items):
item.job_card = source_doc.items[idx].job_card
if not target_doc.supplier_warehouse:
# WIP warehouse is set as Supplier Warehouse in Job Card
target_doc.supplier_warehouse = frappe.get_cached_value(
"Job Card", item.job_card, "wip_warehouse"
)

return target_doc


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@
"production_plan",
"production_plan_item",
"production_plan_sub_assembly_item",
"page_break"
"page_break",
"column_break_pjyo",
"job_card"
],
"fields": [
{
Expand Down Expand Up @@ -909,13 +911,24 @@
{
"fieldname": "column_break_fyqr",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_pjyo",
"fieldtype": "Column Break"
},
{
"fieldname": "job_card",
"fieldtype": "Link",
"label": "Job Card",
"options": "Job Card",
"search_index": 1
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:24.979325",
"modified": "2024-03-27 13:12:24.979325",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
Expand Down
182 changes: 169 additions & 13 deletions erpnext/manufacturing/doctype/bom/bom.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ frappe.ui.form.on("BOM", {
};
});

frm.set_query("bom_no", "operations", function (doc, cdt, cdn) {
let row = locals[cdt][cdn];
return {
query: "erpnext.controllers.queries.bom",
filters: {
currency: frm.doc.currency,
company: frm.doc.company,
item: row.finished_good,
is_active: 1,
docstatus: 1,
track_semi_finished_goods: 0,
},
};
});

frm.set_query("source_warehouse", "items", function () {
return {
filters: {
Expand Down Expand Up @@ -85,6 +100,27 @@ frappe.ui.form.on("BOM", {
frm.get_field("items").grid.set_multiple_add("item_code", "qty");
},

default_source_warehouse(frm) {
if (frm.doc.default_source_warehouse) {
frm.doc.operations.forEach((d) => {
frappe.model.set_value(
d.doctype,
d.name,
"source_warehouse",
frm.doc.default_source_warehouse
);
});
}
},

default_target_warehouse(frm) {
if (frm.doc.default_source_warehouse) {
frm.doc.operations.forEach((d) => {
frappe.model.set_value(d.doctype, d.name, "fg_warehouse", frm.doc.default_target_warehouse);
});
}
},

refresh(frm) {
frm.toggle_enable("item", frm.doc.__islocal);

Expand All @@ -96,22 +132,35 @@ frappe.ui.form.on("BOM", {
});

if (!frm.is_new() && frm.doc.docstatus < 2) {
frm.add_custom_button(__("Update Cost"), function () {
frm.events.update_cost(frm, true);
});
frm.add_custom_button(__("Browse BOM"), function () {
frappe.route_options = {
bom: frm.doc.name,
};
frappe.set_route("Tree", "BOM");
});
frm.add_custom_button(
__("Update Cost"),
function () {
frm.events.update_cost(frm, true);
},
__("Actions")
);

frm.add_custom_button(
__("Browse BOM"),
function () {
frappe.route_options = {
bom: frm.doc.name,
};
frappe.set_route("Tree", "BOM");
},
__("Actions")
);
}

if (!frm.is_new() && !frm.doc.docstatus == 0) {
frm.add_custom_button(__("New Version"), function () {
let new_bom = frappe.model.copy_doc(frm.doc);
frappe.set_route("Form", "BOM", new_bom.name);
});
frm.add_custom_button(
__("New Version"),
function () {
let new_bom = frappe.model.copy_doc(frm.doc);
frappe.set_route("Form", "BOM", new_bom.name);
},
__("Actions")
);
}

if (frm.doc.docstatus == 1) {
Expand Down Expand Up @@ -432,6 +481,28 @@ frappe.ui.form.on("BOM", {
},
});

frappe.ui.form.on("BOM Operation", {
bom_no(frm, cdt, cdn) {
let row = locals[cdt][cdn];

if (row.bom_no && row.finished_good) {
frappe.call({
method: "add_materials_from_bom",
doc: frm.doc,
args: {
finished_good: row.finished_good,
bom_no: row.bom_no,
operation_row_id: row.idx,
qty: row.finished_good_qty,
},
callback(r) {
refresh_field("items");
},
});
}
},
});

erpnext.bom.BomController = class BomController extends erpnext.TransactionController {
conversion_rate(doc) {
if (this.frm.doc.currency === this.get_company_currency()) {
Expand Down Expand Up @@ -801,3 +872,88 @@ function trigger_process_loss_qty_prompt(frm, cdt, cdn, item_code) {
__("Set Quantity")
);
}

frappe.ui.form.on("BOM Operation", {
add_raw_materials(frm, cdt, cdn) {
let row = locals[cdt][cdn];
frm.events._prompt_for_raw_materials(frm, row);
},
});

frappe.ui.form.on("BOM", {
_prompt_for_raw_materials(frm, row) {
let fields = frm.events.get_fields_for_prompt(frm, row);
frm._bom_rm_dialog = new frappe.ui.Dialog({
title: __("Add Raw Materials"),
fields: fields,
primary_action_label: __("Add"),
primary_action: () => {
let values = frm._bom_rm_dialog.get_values();
if (values) {
frm.events._add_raw_materials(frm, values);
frm._bom_rm_dialog.hide();
}
},
});

frm._bom_rm_dialog.show();
},

get_fields_for_prompt(frm, row) {
return [
{
label: __("Raw Materials"),
fieldname: "items",
fieldtype: "Table",
reqd: 1,
fields: [
{
label: __("Item"),
fieldname: "item_code",
fieldtype: "Link",
options: "Item",
reqd: 1,
in_list_view: 1,
change() {
let doc = this.doc;
doc.qty = 1.0;
this.grid.set_value("qty", 1.0, doc);
},
get_query() {
return {
filters: {
name: ["!=", row.finished_good],
},
};
},
},
{
label: __("Qty"),
fieldname: "qty",
default: 1.0,
fieldtype: "Float",
reqd: 1,
in_list_view: 1,
},
],
},
{
fieldname: "operation_row_id",
fieldtype: "Data",
hidden: 1,
default: row.idx,
},
];
},

_add_raw_materials(frm, values) {
frm.call({
method: "add_raw_materials",
doc: frm.doc,
args: {
operation_row_id: values.operation_row_id,
items: values.items,
},
});
},
});
Loading

0 comments on commit 9e9296e

Please sign in to comment.