Skip to content

Commit

Permalink
feat: option to add raw materials manually against operation
Browse files Browse the repository at this point in the history
  • Loading branch information
rohitwaghchaure committed Jun 1, 2024
1 parent 8f5c718 commit a532028
Show file tree
Hide file tree
Showing 33 changed files with 1,876 additions and 642 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:11:24.979325",
"modified": "2024-03-27 13:12:24.979325",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
Expand Down
158 changes: 130 additions & 28 deletions erpnext/manufacturing/doctype/bom/bom.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ frappe.ui.form.on("BOM", {
};
});

frm.set_query("bom_no", "operations", function(doc, cdt, cdn) {
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,
'make_finished_good_against_job_card': 0
}
currency: frm.doc.currency,
company: frm.doc.company,
item: row.finished_good,
is_active: 1,
docstatus: 1,
track_semi_finished_goods: 0,
},
};
});

Expand Down Expand Up @@ -103,7 +103,12 @@ frappe.ui.form.on("BOM", {
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);
frappe.model.set_value(
d.doctype,
d.name,
"source_warehouse",
frm.doc.default_source_warehouse
);
});
}
},
Expand All @@ -127,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 @@ -463,8 +481,7 @@ frappe.ui.form.on("BOM", {
},
});


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

Expand All @@ -480,11 +497,11 @@ frappe.ui.form.on('BOM Operation', {
},
callback(r) {
refresh_field("items");
}
})
},
});
}
}
})
},
});

erpnext.bom.BomController = class BomController extends erpnext.TransactionController {
conversion_rate(doc) {
Expand Down Expand Up @@ -855,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,
},
});
},
});
24 changes: 13 additions & 11 deletions erpnext/manufacturing/doctype/bom/bom.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"conversion_rate",
"operations_section_section",
"with_operations",
"make_finished_good_against_job_card",
"track_semi_finished_goods",
"column_break_23",
"transfer_material_against",
"routing",
Expand Down Expand Up @@ -62,8 +62,8 @@
"base_total_cost",
"more_info_tab",
"item_name",
"description",
"column_break_27",
"description",
"has_variants",
"quality_inspection_section_break",
"inspection_required",
Expand Down Expand Up @@ -214,7 +214,7 @@
},
{
"default": "Work Order",
"depends_on": "eval: doc.with_operations === 1 && doc.make_finished_good_against_job_card === 0",
"depends_on": "eval: doc.with_operations === 1 && doc.track_semi_finished_goods === 0",
"fieldname": "transfer_material_against",
"fieldtype": "Select",
"label": "Transfer Material Against",
Expand Down Expand Up @@ -409,8 +409,8 @@
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "section_break0",
"fieldtype": "Section Break",
"label": "Materials Required (Exploded)"
"fieldtype": "Tab Break",
"label": "Exploded Items"
},
{
"fieldname": "exploded_items",
Expand Down Expand Up @@ -617,15 +617,17 @@
"no_copy": 1,
"options": "BOM Creator",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "bom_creator_item",
"fieldtype": "Data",
"label": "BOM Creator Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "column_break_oxbz",
Expand All @@ -634,10 +636,10 @@
{
"default": "0",
"depends_on": "with_operations",
"description": "User can consume the raw materials, Add Semi Finished Goods / Final Finished Good against the Operation using Job Cards",
"fieldname": "make_finished_good_against_job_card",
"description": "Users can consume raw materials and add semi-finished goods or final finished goods against the operation using job cards.",
"fieldname": "track_semi_finished_goods",
"fieldtype": "Check",
"label": "Make Finished Good Against Job Card"
"label": "Track Semi Finished Goods"
},
{
"fieldname": "column_break_joxb",
Expand All @@ -661,7 +663,7 @@
"image_field": "image",
"is_submittable": 1,
"links": [],
"modified": "2024-04-02 16:23:47.518411",
"modified": "2024-04-02 16:24:47.518411",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
Expand Down
30 changes: 24 additions & 6 deletions erpnext/manufacturing/doctype/bom/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from frappe import _
from frappe.core.doctype.version.version import get_diff
from frappe.model.mapper import get_mapped_doc
from frappe.utils import cint, cstr, flt, today
from frappe.utils import cint, cstr, flt, parse_json, today
from frappe.website.website_generator import WebsiteGenerator

import erpnext
Expand Down Expand Up @@ -125,6 +125,8 @@ class BOM(WebsiteGenerator):
company: DF.Link
conversion_rate: DF.Float
currency: DF.Link
default_source_warehouse: DF.Link | None
default_target_warehouse: DF.Link | None
description: DF.SmallText | None
exploded_items: DF.Table[BOMExplosionItem]
fg_based_operating_cost: DF.Check
Expand All @@ -136,6 +138,7 @@ class BOM(WebsiteGenerator):
item: DF.Link
item_name: DF.Data | None
items: DF.Table[BOMItem]
track_semi_finished_goods: DF.Check
operating_cost: DF.Currency
operating_cost_per_bom_quantity: DF.Currency
operations: DF.Table[BOMOperation]
Expand Down Expand Up @@ -545,8 +548,8 @@ def clear_operations(self):
if not self.with_operations:
self.set("operations", [])

if not self.with_operations and self.make_finished_good_against_job_card:
self.make_finished_good_against_job_card = 0
if not self.with_operations and self.track_semi_finished_goods:
self.track_semi_finished_goods = 0

def clear_inspection(self):
if not self.inspection_required:
Expand Down Expand Up @@ -650,13 +653,29 @@ def _throw_error(bom_name):
_throw_error(self.name)

def set_materials_based_on_operation_bom(self):
if not self.make_finished_good_against_job_card:
if not self.track_semi_finished_goods:
return

for row in self.get("operations"):
if row.bom_no and row.finished_good:
self.add_materials_from_bom(row.finished_good, row.bom_no, row.idx, qty=row.finished_good_qty)

@frappe.whitelist()
def add_raw_materials(self, operation_row_id, items):
if isinstance(items, str):
items = parse_json(items)

for row in items:
row = parse_json(row)

row.update(get_item_details(row.get("item_code")))
row.operation_row_id = operation_row_id
row.idx = None
row.name = None
self.append("items", row)

self.save()

@frappe.whitelist()
def add_materials_from_bom(self, finished_good, bom_no, operation_row_id, qty=None):
if not frappe.db.exists("BOM", {"item": finished_good, "name": bom_no, "docstatus": 1}):
Expand Down Expand Up @@ -1126,7 +1145,7 @@ def get_bom_items_as_dict(
item_dict = {}

group_by_cond = "group by item_code, stock_uom"
if frappe.get_cached_value("BOM", bom, "make_finished_good_against_job_card"):
if frappe.get_cached_value("BOM", bom, "track_semi_finished_goods"):
fetch_exploded = 0
group_by_cond = "group by item_code, operation_row_id, stock_uom"

Expand Down Expand Up @@ -1221,7 +1240,6 @@ def get_bom_items_as_dict(
if not item_details.get(d[1]) or (company_in_record and company != company_in_record):
item_dict[item][d[1]] = frappe.get_cached_value("Company", company, d[2]) if d[2] else None

print(item_dict)
return item_dict


Expand Down
Loading

0 comments on commit a532028

Please sign in to comment.