Merge pull request #17169 from rohitwaghchaure/production_plan_multiple_enhancements

feat: Production plan enhancements
This commit is contained in:
Nabin Hait 2019-04-17 17:31:14 +05:30 committed by GitHub
commit 3a2d6a4043
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 974 additions and 331 deletions

View File

@ -682,6 +682,9 @@ def get_children(doctype, parent=None, is_root=False, **filters):
frappe.msgprint(_('Please select a BOM')) frappe.msgprint(_('Please select a BOM'))
return return
if parent:
frappe.form_dict.parent = parent
if frappe.form_dict.parent: if frappe.form_dict.parent:
bom_doc = frappe.get_doc("BOM", frappe.form_dict.parent) bom_doc = frappe.get_doc("BOM", frappe.form_dict.parent)
frappe.has_permission("BOM", doc=bom_doc, throw=True) frappe.has_permission("BOM", doc=bom_doc, throw=True)
@ -694,7 +697,7 @@ def get_children(doctype, parent=None, is_root=False, **filters):
item_names = tuple(d.get('item_code') for d in bom_items) item_names = tuple(d.get('item_code') for d in bom_items)
items = frappe.get_list('Item', items = frappe.get_list('Item',
fields=['image', 'description', 'name'], fields=['image', 'description', 'name', 'stock_uom', 'item_name'],
filters=[['name', 'in', item_names]]) # to get only required item dicts filters=[['name', 'in', item_names]]) # to get only required item dicts
for bom_item in bom_items: for bom_item in bom_items:

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -14,10 +15,12 @@
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_code", "fieldname": "item_code",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -41,14 +44,17 @@
"reqd": 1, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_name", "fieldname": "item_name",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "hidden": 0,
@ -72,14 +78,17 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "warehouse", "fieldname": "warehouse",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -103,14 +112,51 @@
"reqd": 1, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "material_request_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Material Request Type",
"length": 0,
"no_copy": 0,
"options": "\nPurchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -132,14 +178,17 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "quantity", "fieldname": "quantity",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -149,7 +198,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Quantity", "label": "Required Quantity",
"length": 0, "length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "permlevel": 0,
@ -162,14 +211,52 @@
"reqd": 1, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "projected_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Projected Qty",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "actual_qty", "fieldname": "actual_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -192,14 +279,17 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "min_order_qty", "fieldname": "min_order_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -222,14 +312,17 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_8", "fieldname": "section_break_8",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -252,14 +345,17 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "sales_order", "fieldname": "sales_order",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -283,14 +379,18 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "requested_qty", "fieldname": "requested_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -313,20 +413,19 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
} }
], ],
"has_web_view": 0, "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 0, "idx": 0,
"image_view": 0,
"in_create": 0, "in_create": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-02-15 13:08:30.535963", "modified": "2019-04-08 18:15:26.849602",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Material Request Plan Item", "name": "Material Request Plan Item",
@ -335,10 +434,10 @@
"permissions": [], "permissions": [],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0, "read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0, "show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1,
"track_seen": 0 "track_seen": 0,
"track_views": 0
} }

View File

@ -11,6 +11,23 @@ frappe.ui.form.on('Production Plan', {
} }
} }
frm.set_query('for_warehouse', function(doc) {
return {
filters: {
company: doc.company
}
}
});
frm.fields_dict['po_items'].grid.get_field('item_code').get_query = function(doc) {
return {
query: "erpnext.controllers.queries.item_query",
filters:{
'is_stock_item': 1,
}
}
}
frm.fields_dict['po_items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) { frm.fields_dict['po_items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
var d = locals[cdt][cdn]; var d = locals[cdt][cdn];
if (d.item_code) { if (d.item_code) {
@ -50,6 +67,51 @@ frappe.ui.form.on('Production Plan', {
} }
frm.trigger("material_requirement"); frm.trigger("material_requirement");
const projected_qty_formula = ` <table class="table table-bordered" style="background-color: #f9f9f9;">
<tr><td style="padding-left:25px">
<div>
<h3>
<a href = "https://erpnext.com/docs/user/manual/en/stock/projected-quantity">
${__("Projected Quantity Formula")}
</a>
</h3>
<div>
<h3 style="font-size: 13px">
(Actual Qty + Planned Qty + Requested Qty + Ordered Qty) - (Reserved Qty + Reserved for Production + Reserved for Subcontract)
</h3>
</div>
<br>
<div>
<ul>
<li>
${__("Actual Qty: Quantity available in the warehouse.")}
</li>
<li>
${__("Planned Qty: Quantity, for which, Work Order has been raised, but is pending to be manufactured.")}
</li>
<li>
${__('Requested Qty: Quantity requested for purchase, but not ordered.')}
</li>
<li>
${__('Ordered Qty: Quantity ordered for purchase, but not received.')}
</li>
<li>
${__("Reserved Qty: Quantity ordered for sale, but not delivered.")}
</li>
<li>
${__('Reserved Qty for Production: Raw materials quantity to make manufacturing items.')}
</li>
<li>
${__('Reserved Qty for Subcontract: Raw materials quantity to make subcotracted items.')}
</li>
</ul>
</div>
</div>
</td></tr>
</table>`;
set_field_options("projected_qty_formula", projected_qty_formula);
}, },
make_work_order: function(frm) { make_work_order: function(frm) {
@ -106,6 +168,8 @@ frappe.ui.form.on('Production Plan', {
}, },
get_items_for_mr: function(frm) { get_items_for_mr: function(frm) {
const set_fields = ['actual_qty', 'item_code',
'item_name', 'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
frappe.call({ frappe.call({
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests", method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
freeze: true, freeze: true,
@ -115,13 +179,11 @@ frappe.ui.form.on('Production Plan', {
frm.set_value('mr_items', []); frm.set_value('mr_items', []);
$.each(r.message, function(i, d) { $.each(r.message, function(i, d) {
var item = frm.add_child('mr_items'); var item = frm.add_child('mr_items');
item.actual_qty = d.actual_qty; for (let key in d) {
item.item_code = d.item_code; if (d[key] && in_list(set_fields, key)) {
item.item_name = d.item_name; item[key] = d[key];
item.min_order_qty = d.min_order_qty; }
item.quantity = d.quantity; }
item.sales_order = d.sales_order;
item.warehouse = d.warehouse;
}); });
} }
refresh_field('mr_items'); refresh_field('mr_items');
@ -129,6 +191,16 @@ frappe.ui.form.on('Production Plan', {
}); });
}, },
for_warehouse: function(frm) {
if (frm.doc.mr_items) {
frm.trigger("get_items_for_mr");
}
},
download_materials_required: function(frm) {
$c_obj_csv(frm.doc, 'download_raw_materials', '', '');
},
show_progress: function(frm) { show_progress: function(frm) {
var bars = []; var bars = [];
var message = ''; var message = '';
@ -163,6 +235,25 @@ frappe.ui.form.on('Production Plan', {
}, },
}); });
frappe.ui.form.on("Production Plan Item", {
item_code: function(frm, cdt, cdn) {
const row = locals[cdt][cdn];
if (row.item_code) {
frappe.call({
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_item_data",
args: {
item_code: row.item_code
},
callback: function(r) {
for (let key in r.message) {
frappe.model.set_value(cdt, cdn, key, r.message[key]);
}
}
});
}
}
});
frappe.ui.form.on("Material Request Plan Item", { frappe.ui.form.on("Material Request Plan Item", {
warehouse: function(frm, cdt, cdn) { warehouse: function(frm, cdt, cdn) {
const row = locals[cdt][cdn]; const row = locals[cdt][cdn];
@ -170,12 +261,16 @@ frappe.ui.form.on("Material Request Plan Item", {
frappe.call({ frappe.call({
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_bin_details", method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_bin_details",
args: { args: {
row: row row: row,
for_warehouse: row.warehouse
}, },
callback: function(r) { callback: function(r) {
frappe.model.set_value(cdt, cdn, 'actual_qty', r.message[1]) let {projected_qty, actual_qty} = r.message;
frappe.model.set_value(cdt, cdn, 'projected_qty', projected_qty);
frappe.model.set_value(cdt, cdn, 'actual_qty', actual_qty);
} }
}) })
} }
} }
}) });

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -22,6 +23,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "", "default": "",
"fetch_if_empty": 0,
"fieldname": "naming_series", "fieldname": "naming_series",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -56,6 +58,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "", "depends_on": "",
"fetch_if_empty": 0,
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -90,6 +93,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "", "default": "",
"fetch_if_empty": 0,
"fieldname": "get_items_from", "fieldname": "get_items_from",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -123,6 +127,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break1", "fieldname": "column_break1",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -155,6 +160,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "Today", "default": "Today",
"fetch_if_empty": 0,
"fieldname": "posting_date", "fieldname": "posting_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
@ -190,6 +196,7 @@
"columns": 0, "columns": 0,
"depends_on": "eval: doc.get_items_from", "depends_on": "eval: doc.get_items_from",
"description": "", "description": "",
"fetch_if_empty": 0,
"fieldname": "filters", "fieldname": "filters",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -222,6 +229,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_code", "fieldname": "item_code",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -256,6 +264,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval: doc.get_items_from == \"Sales Order\"", "depends_on": "eval: doc.get_items_from == \"Sales Order\"",
"fetch_if_empty": 0,
"fieldname": "customer", "fieldname": "customer",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -290,6 +299,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval: doc.get_items_from == \"Material Request\"", "depends_on": "eval: doc.get_items_from == \"Material Request\"",
"fetch_if_empty": 0,
"fieldname": "warehouse", "fieldname": "warehouse",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -324,6 +334,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval: doc.get_items_from == \"Sales Order\"", "depends_on": "eval: doc.get_items_from == \"Sales Order\"",
"fetch_if_empty": 0,
"fieldname": "project", "fieldname": "project",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -357,6 +368,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break2", "fieldname": "column_break2",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -389,6 +401,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "from_date", "fieldname": "from_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
@ -421,6 +434,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "to_date", "fieldname": "to_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "hidden": 0,
@ -455,6 +469,7 @@
"collapsible_depends_on": "eval: doc.__islocal", "collapsible_depends_on": "eval: doc.__islocal",
"columns": 0, "columns": 0,
"depends_on": "eval: doc.get_items_from == \"Sales Order\"", "depends_on": "eval: doc.get_items_from == \"Sales Order\"",
"fetch_if_empty": 0,
"fieldname": "sales_orders_detail", "fieldname": "sales_orders_detail",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -489,6 +504,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"description": "", "description": "",
"fetch_if_empty": 0,
"fieldname": "get_sales_orders", "fieldname": "get_sales_orders",
"fieldtype": "Button", "fieldtype": "Button",
"hidden": 0, "hidden": 0,
@ -522,6 +538,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "sales_orders", "fieldname": "sales_orders",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
@ -557,6 +574,7 @@
"collapsible_depends_on": "eval: doc.__islocal", "collapsible_depends_on": "eval: doc.__islocal",
"columns": 0, "columns": 0,
"depends_on": "eval: doc.get_items_from == \"Material Request\"", "depends_on": "eval: doc.get_items_from == \"Material Request\"",
"fetch_if_empty": 0,
"fieldname": "material_request_detail", "fieldname": "material_request_detail",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -590,6 +608,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"description": "", "description": "",
"fetch_if_empty": 0,
"fieldname": "get_material_request", "fieldname": "get_material_request",
"fieldtype": "Button", "fieldtype": "Button",
"hidden": 0, "hidden": 0,
@ -623,6 +642,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "material_requests", "fieldname": "material_requests",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
@ -657,7 +677,8 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"description": "", "description": "",
"fieldname": "items_for_production", "fetch_if_empty": 0,
"fieldname": "select_items_to_manufacture_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -666,7 +687,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Select Items", "label": "Select Items to Manufacture",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -690,6 +711,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "get_items_from", "depends_on": "get_items_from",
"fetch_if_empty": 0,
"fieldname": "get_items", "fieldname": "get_items",
"fieldtype": "Button", "fieldtype": "Button",
"hidden": 0, "hidden": 0,
@ -723,6 +745,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "po_items", "fieldname": "po_items",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
@ -732,7 +755,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Items", "label": "",
"length": 0, "length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Production Plan Item", "options": "Production Plan Item",
@ -757,6 +780,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "", "depends_on": "",
"fetch_if_empty": 0,
"fieldname": "material_request_planning", "fieldname": "material_request_planning",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -790,6 +814,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "1", "default": "1",
"fetch_if_empty": 0,
"fieldname": "include_non_stock_items", "fieldname": "include_non_stock_items",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -815,69 +840,6 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "ignore_existing_ordered_qty",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore Existing Ordered Quantity",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_25",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -886,6 +848,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "1", "default": "1",
"fetch_if_empty": 0,
"fieldname": "include_subcontracted_items", "fieldname": "include_subcontracted_items",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -918,9 +881,43 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "", "description": "If enabled, then system will create the material even if the raw materials are available",
"fieldname": "section_break_27", "fetch_if_empty": 0,
"fieldtype": "Section Break", "fieldname": "ignore_existing_ordered_qty",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore Existing Projected Quantity",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_25",
"fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -950,6 +947,74 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "for_warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "For Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "download_materials_required",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Download Materials Required",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "get_items_for_mr", "fieldname": "get_items_for_mr",
"fieldtype": "Button", "fieldtype": "Button",
"hidden": 0, "hidden": 0,
@ -982,6 +1047,40 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "section_break_27",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "mr_items", "fieldname": "mr_items",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0, "hidden": 0,
@ -1008,6 +1107,40 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "projected_qty_formula",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Projected Qty Formula",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -1015,6 +1148,7 @@
"bold": 0, "bold": 0,
"collapsible": 1, "collapsible": 1,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "other_details", "fieldname": "other_details",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -1048,6 +1182,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "0", "default": "0",
"fetch_if_empty": 0,
"fieldname": "total_planned_qty", "fieldname": "total_planned_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -1081,6 +1216,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "0", "default": "0",
"fetch_if_empty": 0,
"fieldname": "total_produced_qty", "fieldname": "total_produced_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -1113,6 +1249,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_32", "fieldname": "column_break_32",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -1145,6 +1282,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "Draft", "default": "Draft",
"fetch_if_empty": 0,
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -1178,6 +1316,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "amended_from", "fieldname": "amended_from",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -1205,17 +1344,15 @@
} }
], ],
"has_web_view": 0, "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"icon": "fa fa-calendar", "icon": "fa fa-calendar",
"idx": 0, "idx": 0,
"image_view": 0,
"in_create": 0, "in_create": 0,
"is_submittable": 1, "is_submittable": 1,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-08-21 14:44:25.071991", "modified": "2019-04-09 12:05:14.300886",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Production Plan", "name": "Production Plan",
@ -1244,7 +1381,6 @@
], ],
"quick_entry": 0, "quick_entry": 0,
"read_only": 0, "read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0, "show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "ASC", "sort_order": "ASC",

View File

@ -6,7 +6,7 @@ from __future__ import unicode_literals
import frappe, json import frappe, json
from frappe import msgprint, _ from frappe import msgprint, _
from frappe.model.document import Document from frappe.model.document import Document
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_children
from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and, now_datetime, ceil from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and, now_datetime, ceil
from erpnext.manufacturing.doctype.work_order.work_order import get_item_details from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
from six import string_types, iteritems from six import string_types, iteritems
@ -262,7 +262,8 @@ class ProductionPlan(Document):
"fg_warehouse" : d.warehouse, "fg_warehouse" : d.warehouse,
"production_plan" : self.name, "production_plan" : self.name,
"production_plan_item" : d.name, "production_plan_item" : d.name,
"product_bundle_item" : d.product_bundle_item "product_bundle_item" : d.product_bundle_item,
"make_work_order_for_sub_assembly_items": d.get("make_work_order_for_sub_assembly_items", 0)
} }
item_details.update({ item_details.update({
@ -293,6 +294,10 @@ class ProductionPlan(Document):
if work_order: if work_order:
wo_list.append(work_order) wo_list.append(work_order)
if item.get("make_work_order_for_sub_assembly_items"):
work_orders = self.make_work_order_for_sub_assembly_items(item)
wo_list.extend(work_orders)
frappe.flags.mute_messages = False frappe.flags.mute_messages = False
if wo_list: if wo_list:
@ -302,11 +307,35 @@ class ProductionPlan(Document):
else : else :
msgprint(_("No Work Orders created")) msgprint(_("No Work Orders created"))
def make_work_order_for_sub_assembly_items(self, item):
work_orders = []
bom_data = {}
get_sub_assembly_items(item.get("bom_no"), bom_data)
for key, data in bom_data.items():
data.update({
'qty': data.get("stock_qty") * item.get("qty"),
'production_plan': self.name,
'company': self.company,
'fg_warehouse': item.get("fg_warehouse")
})
work_order = self.create_work_order(data)
if work_order:
work_orders.append(work_order)
return work_orders
def create_work_order(self, item): def create_work_order(self, item):
from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError, get_default_warehouse from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError, get_default_warehouse
warehouse = get_default_warehouse() warehouse = get_default_warehouse()
wo = frappe.new_doc("Work Order") wo = frappe.new_doc("Work Order")
wo.update(item) wo.update(item)
if item.get("warehouse"):
wo.fg_warehouse = item.get("warehouse")
wo.set_work_order_operations() wo.set_work_order_operations()
if not wo.fg_warehouse: if not wo.fg_warehouse:
@ -325,8 +354,10 @@ class ProductionPlan(Document):
for item in self.mr_items: for item in self.mr_items:
item_doc = frappe.get_cached_doc('Item', item.item_code) item_doc = frappe.get_cached_doc('Item', item.item_code)
material_request_type = item.material_request_type or item_doc.default_material_request_type
# key for Sales Order:Material Request Type:Customer # key for Sales Order:Material Request Type:Customer
key = '{}:{}:{}'.format(item.sales_order, item_doc.default_material_request_type,item_doc.customer or '') key = '{}:{}:{}'.format(item.sales_order, material_request_type, item_doc.customer or '')
schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days)) schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days))
if not key in material_request_map: if not key in material_request_map:
@ -338,7 +369,7 @@ class ProductionPlan(Document):
"status": "Draft", "status": "Draft",
"company": self.company, "company": self.company,
"requested_by": frappe.session.user, "requested_by": frappe.session.user,
'material_request_type': item_doc.default_material_request_type, 'material_request_type': material_request_type,
'customer': item_doc.customer or '' 'customer': item_doc.customer or ''
}) })
material_request_list.append(material_request) material_request_list.append(material_request)
@ -373,6 +404,26 @@ class ProductionPlan(Document):
else : else :
msgprint(_("No material request created")) msgprint(_("No material request created"))
def download_raw_materials(self):
item_list = [['Item Code', 'Description', 'Stock UOM', 'Required Qty', 'Warehouse',
'projected Qty', 'Actual Qty']]
doc = self.as_dict()
for d in get_items_for_material_requests(doc, ignore_existing_ordered_qty=True):
item_list.append([d.get('item_code'), d.get('description'), d.get('stock_uom'), d.get('quantity'),
d.get('warehouse'), d.get('projected_qty'), d.get('actual_qty')])
if not self.for_warehouse:
row = {'item_code': d.get('item_code')}
for bin_dict in get_bin_details(row, self.company, all_warehouse=True):
if d.get("warehouse") == bin_dict.get('warehouse'):
continue
item_list.append(['', '', '', '', bin_dict.get('warehouse'),
bin_dict.get('projected_qty'), bin_dict.get('actual_qty')])
return item_list
def get_exploded_items(item_details, company, bom_no, include_non_stock_items, planned_qty=1): def get_exploded_items(item_details, company, bom_no, include_non_stock_items, planned_qty=1):
for d in frappe.db.sql("""select bei.item_code, item.default_bom as bom, for d in frappe.db.sql("""select bei.item_code, item.default_bom as bom,
ifnull(sum(bei.stock_qty/ifnull(bom.quantity, 1)), 0)*%s as qty, item.item_name, ifnull(sum(bei.stock_qty/ifnull(bom.quantity, 1)), 0)*%s as qty, item.item_name,
@ -439,17 +490,17 @@ def get_subitems(doc, data, item_details, bom_no, company, include_non_stock_ite
include_non_stock_items, include_subcontracted_items, d.qty) include_non_stock_items, include_subcontracted_items, d.qty)
return item_details return item_details
def get_material_request_items(row, sales_order, company, ignore_existing_ordered_qty, warehouse): def get_material_request_items(row, sales_order,
company, ignore_existing_ordered_qty, warehouse, bin_dict):
total_qty = row['qty'] total_qty = row['qty']
projected_qty, actual_qty = get_bin_details(row)
requested_qty = 0 required_qty = 0
if ignore_existing_ordered_qty: if ignore_existing_ordered_qty or bin_dict.get("projected_qty") < 0:
requested_qty = total_qty required_qty = total_qty
elif total_qty > projected_qty: elif total_qty > bin_dict.get("projected_qty"):
requested_qty = total_qty - projected_qty required_qty = total_qty - bin_dict.get("projected_qty")
if requested_qty > 0 and requested_qty < row['min_order_qty']: if required_qty > 0 and required_qty < row['min_order_qty']:
requested_qty = row['min_order_qty'] required_qty = row['min_order_qty']
item_group_defaults = get_item_group_defaults(row.item_code, company) item_group_defaults = get_item_group_defaults(row.item_code, company)
if not row['purchase_uom']: if not row['purchase_uom']:
@ -459,20 +510,24 @@ def get_material_request_items(row, sales_order, company, ignore_existing_ordere
if not row['conversion_factor']: if not row['conversion_factor']:
frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}") frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}")
.format(row['purchase_uom'], row['stock_uom'], row.item_code)) .format(row['purchase_uom'], row['stock_uom'], row.item_code))
requested_qty = requested_qty / row['conversion_factor'] required_qty = required_qty / row['conversion_factor']
if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"): if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"):
requested_qty = ceil(requested_qty) required_qty = ceil(required_qty)
if requested_qty > 0: if required_qty > 0:
return { return {
'item_code': row.item_code, 'item_code': row.item_code,
'item_name': row.item_name, 'item_name': row.item_name,
'quantity': requested_qty, 'quantity': required_qty,
'description': row.description,
'stock_uom': row.get("stock_uom"),
'warehouse': warehouse or row.get('source_warehouse') \ 'warehouse': warehouse or row.get('source_warehouse') \
or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"), or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"),
'actual_qty': actual_qty, 'actual_qty': bin_dict.get("actual_qty", 0),
'projected_qty': bin_dict.get("projected_qty", 0),
'min_order_qty': row['min_order_qty'], 'min_order_qty': row['min_order_qty'],
'material_request_type': row.get("default_material_request_type"),
'sales_order': sales_order 'sales_order': sales_order
} }
@ -515,37 +570,48 @@ def get_sales_orders(self):
return open_so return open_so
@frappe.whitelist() @frappe.whitelist()
def get_bin_details(row): def get_bin_details(row, company, for_warehouse=None, all_warehouse=False):
if isinstance(row, string_types): if isinstance(row, string_types):
row = frappe._dict(json.loads(row)) row = frappe._dict(json.loads(row))
conditions = "" company = frappe.db.escape(company)
warehouse = row.get('source_warehouse') or row.get('default_warehouse') conditions, warehouse = "", ""
conditions = " and warehouse in (select name from `tabWarehouse` where company = {0})".format(company)
if not all_warehouse:
warehouse = for_warehouse or row.get('source_warehouse') or row.get('default_warehouse')
if warehouse: if warehouse:
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"]) lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
conditions = " and exists(select name from `tabWarehouse` where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse)".format(lft, rgt) conditions = """ and warehouse in (select name from `tabWarehouse`
where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse and company = {2})
""".format(lft, rgt, company)
item_projected_qty = frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty, return frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
ifnull(sum(actual_qty),0) as actual_qty from `tabBin` ifnull(sum(actual_qty),0) as actual_qty, warehouse from `tabBin`
where item_code = %(item_code)s {conditions} where item_code = %(item_code)s {conditions}
""".format(conditions=conditions), { "item_code": row['item_code'] }, as_list=1) group by item_code, warehouse
""".format(conditions=conditions), { "item_code": row['item_code'] }, as_dict=1)
return item_projected_qty and item_projected_qty[0] or (0,0)
@frappe.whitelist() @frappe.whitelist()
def get_items_for_material_requests(doc, sales_order=None, company=None): def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None):
if isinstance(doc, string_types): if isinstance(doc, string_types):
doc = frappe._dict(json.loads(doc)) doc = frappe._dict(json.loads(doc))
doc['mr_items'] = [] doc['mr_items'] = []
po_items = doc.get('po_items') if doc.get('po_items') else doc.get('items') po_items = doc.get('po_items') if doc.get('po_items') else doc.get('items')
company = doc.get('company') company = doc.get('company')
warehouse = doc.get('for_warehouse')
if not ignore_existing_ordered_qty:
ignore_existing_ordered_qty = doc.get('ignore_existing_ordered_qty')
so_item_details = frappe._dict() so_item_details = frappe._dict()
for data in po_items: for data in po_items:
warehouse = data.get('for_warehouse')
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or doc.get('ignore_existing_ordered_qty')
planned_qty = data.get('required_qty') or data.get('planned_qty') planned_qty = data.get('required_qty') or data.get('planned_qty')
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
warehouse = data.get("warehouse") or warehouse
item_details = {} item_details = {}
if data.get("bom") or data.get("bom_no"): if data.get("bom") or data.get("bom_no"):
if data.get('required_qty'): if data.get('required_qty'):
@ -592,7 +658,7 @@ def get_items_for_material_requests(doc, sales_order=None, company=None):
'conversion_factor' : conversion_factor, 'conversion_factor' : conversion_factor,
} }
) )
if not sales_order:
sales_order = doc.get("sales_order") sales_order = doc.get("sales_order")
for item_code, details in iteritems(item_details): for item_code, details in iteritems(item_details):
@ -606,10 +672,48 @@ def get_items_for_material_requests(doc, sales_order=None, company=None):
for sales_order, item_code in iteritems(so_item_details): for sales_order, item_code in iteritems(so_item_details):
item_dict = so_item_details[sales_order] item_dict = so_item_details[sales_order]
for details in item_dict.values(): for details in item_dict.values():
bin_dict = get_bin_details(details, doc.company, warehouse)
bin_dict = bin_dict[0] if bin_dict else {}
if details.qty > 0: if details.qty > 0:
items = get_material_request_items(details, sales_order, company, items = get_material_request_items(details, sales_order, company,
ignore_existing_ordered_qty, warehouse) ignore_existing_ordered_qty, warehouse, bin_dict)
if items: if items:
mr_items.append(items) mr_items.append(items)
if not mr_items:
frappe.msgprint(_("""As raw materials projected quantity is more than required quantity, there is no need to create material request.
Still if you want to make material request, kindly enable <b>Ignore Existing Projected Quantity</b> checkbox"""))
return mr_items return mr_items
@frappe.whitelist()
def get_item_data(item_code):
item_details = get_item_details(item_code)
return {
"bom_no": item_details.get("bom_no"),
"stock_uom": item_details.get("stock_uom"),
"description": item_details.get("description")
}
def get_sub_assembly_items(bom_no, bom_data):
data = get_children('BOM', parent = bom_no)
for d in data:
if d.expandable:
key = (d.name, d.value)
if key not in bom_data:
bom_data.setdefault(key, {
'stock_qty': 0,
'description': d.description,
'production_item': d.item_code,
'item_name': d.item_name,
'stock_uom': d.stock_uom,
'uom': d.stock_uom,
'bom_no': d.value
})
bom_item = bom_data.get(key)
bom_item["stock_qty"] += d.stock_qty
get_sub_assembly_items(bom_item.get("bom_no"), bom_data)

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -13,10 +14,12 @@
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 2, "columns": 2,
"fetch_if_empty": 0,
"fieldname": "include_exploded_items", "fieldname": "include_exploded_items",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -44,10 +47,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 2, "columns": 2,
"fetch_if_empty": 0,
"fieldname": "item_code", "fieldname": "item_code",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -79,10 +84,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 2, "columns": 2,
"fetch_if_empty": 0,
"fieldname": "bom_no", "fieldname": "bom_no",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -114,10 +121,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "planned_qty", "fieldname": "planned_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -148,11 +157,114 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_6",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"description": "If enabled, system will create the work order for the exploded items against which BOM is available.",
"fetch_if_empty": 0,
"fieldname": "make_work_order_for_sub_assembly_items",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Make Work Order for Sub Assembly Items",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "For Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "Today", "default": "Today",
"fetch_if_empty": 0,
"fieldname": "planned_start_date", "fieldname": "planned_start_date",
"fieldtype": "Datetime", "fieldtype": "Datetime",
"hidden": 0, "hidden": 0,
@ -180,12 +292,14 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "column_break_6", "fetch_if_empty": 0,
"fieldtype": "Column Break", "fieldname": "section_break_9",
"fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -193,6 +307,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Quantity and Description",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -210,169 +325,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"description": "Reserved Warehouse in Sales Order / Finished Goods Warehouse", "default": "0",
"fieldname": "warehouse", "fetch_if_empty": 0,
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "produced_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Produced Qty",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sales_order",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Order",
"length": 0,
"no_copy": 0,
"oldfieldname": "source_docname",
"oldfieldtype": "Data",
"options": "Sales Order",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sales_order_item",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Order Item",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "material_request",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Material Request",
"length": 0,
"no_copy": 0,
"options": "Material Request",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "pending_qty", "fieldname": "pending_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -403,10 +362,148 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "0",
"fetch_if_empty": 0,
"fieldname": "ordered_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ordered Qty",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fetch_if_empty": 0,
"fieldname": "produced_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Produced Qty",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_17",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "200px",
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "200px"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "stock_uom", "fieldname": "stock_uom",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -438,12 +535,14 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "description", "fetch_if_empty": 0,
"fieldtype": "Text Editor", "fieldname": "reference_section",
"fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -451,15 +550,48 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Description", "label": "Reference",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"oldfieldname": "description", "permlevel": 0,
"oldfieldtype": "Text", "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sales_order",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Order",
"length": 0,
"no_copy": 0,
"oldfieldname": "source_docname",
"oldfieldtype": "Data",
"options": "Sales Order",
"permlevel": 0, "permlevel": 0,
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"print_width": "200px",
"read_only": 1, "read_only": 1,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
@ -467,15 +599,115 @@
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
"unique": 0, "unique": 0
"width": "200px"
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "sales_order_item",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Order Item",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "material_request",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Material Request",
"length": 0,
"no_copy": 0,
"options": "Material Request",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "material_request_item", "fieldname": "material_request_item",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 1, "hidden": 1,
@ -503,41 +735,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "ordered_qty", "fetch_if_empty": 0,
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ordered Qty",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "product_bundle_item", "fieldname": "product_bundle_item",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -566,16 +769,14 @@
} }
], ],
"has_web_view": 0, "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 1, "idx": 1,
"image_view": 0,
"in_create": 0, "in_create": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-04-25 17:19:24.572528", "modified": "2019-04-08 23:09:57.199423",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Production Plan Item", "name": "Production Plan Item",
@ -583,9 +784,9 @@
"permissions": [], "permissions": [],
"quick_entry": 0, "quick_entry": 0,
"read_only": 0, "read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0, "show_name_in_global_search": 0,
"sort_order": "ASC", "sort_order": "ASC",
"track_changes": 0, "track_changes": 0,
"track_seen": 0 "track_seen": 0,
"track_views": 0
} }

View File

@ -365,6 +365,8 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
fields: [ fields: [
{fieldtype:'Read Only', fieldname:'item_code', {fieldtype:'Read Only', fieldname:'item_code',
label: __('Item Code'), in_list_view:1}, label: __('Item Code'), in_list_view:1},
{fieldtype:'Link', fieldname:'warehouse', options: 'Warehouse',
label: __('For Warehouse'), in_list_view:1},
{fieldtype:'Link', fieldname:'bom', options: 'BOM', reqd: 1, {fieldtype:'Link', fieldname:'bom', options: 'BOM', reqd: 1,
label: __('BOM'), in_list_view:1, get_query: function(doc) { label: __('BOM'), in_list_view:1, get_query: function(doc) {
return {filters: {item: doc.item_code}}; return {filters: {item: doc.item_code}};
@ -372,8 +374,6 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
}, },
{fieldtype:'Float', fieldname:'required_qty', reqd: 1, {fieldtype:'Float', fieldname:'required_qty', reqd: 1,
label: __('Qty'), in_list_view:1}, label: __('Qty'), in_list_view:1},
{fieldtype:'Link', fieldname:'for_warehouse', options: 'Warehouse',
label: __('For Warehouse')}
], ],
data: r.message, data: r.message,
get_data: function() { get_data: function() {

View File

@ -937,7 +937,12 @@ def make_raw_material_request(items, company, sales_order, project=None):
item["ignore_existing_ordered_qty"] = items.get('ignore_existing_ordered_qty') item["ignore_existing_ordered_qty"] = items.get('ignore_existing_ordered_qty')
item["include_raw_materials_from_sales_order"] = items.get('include_raw_materials_from_sales_order') item["include_raw_materials_from_sales_order"] = items.get('include_raw_materials_from_sales_order')
raw_materials = get_items_for_material_requests(items, sales_order, company) items.update({
'company': company,
'sales_order': sales_order
})
raw_materials = get_items_for_material_requests(items)
if not raw_materials: if not raw_materials:
frappe.msgprint(_("Material Request not created, as quantity for Raw Materials already available.")) frappe.msgprint(_("Material Request not created, as quantity for Raw Materials already available."))
return return