From 8cb7112e72b9a463b4a50bdb679e3eabfd7cc9c4 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 25 Nov 2022 23:40:05 +0530 Subject: [PATCH] fix: production plan UX --- .../material_request_plan_item.json | 5 +- .../production_plan/production_plan.js | 93 ++++++++++--------- .../production_plan/production_plan.json | 25 +++-- .../production_plan/production_plan.py | 3 + .../production_plan_item.json | 4 +- 5 files changed, 78 insertions(+), 52 deletions(-) diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json index 27d7c4175e56..8c61d545b814 100644 --- a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json +++ b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json @@ -47,7 +47,7 @@ "fieldtype": "Link", "in_list_view": 1, "in_standard_filter": 1, - "label": "Warehouse", + "label": "For Warehouse", "options": "Warehouse", "reqd": 1 }, @@ -173,7 +173,7 @@ ], "istable": 1, "links": [], - "modified": "2021-08-23 18:17:58.400462", + "modified": "2022-11-26 14:59:25.879631", "modified_by": "Administrator", "module": "Manufacturing", "name": "Material Request Plan Item", @@ -182,5 +182,6 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index 59ddf1f0c589..62715e656531 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -3,13 +3,13 @@ frappe.ui.form.on('Production Plan', { - before_save: function(frm) { + before_save(frm) { // preserve temporary names on production plan item to re-link sub-assembly items frm.doc.po_items.forEach(item => { item.temporary_name = item.name; }); }, - setup: function(frm) { + setup(frm) { frm.custom_make_buttons = { 'Work Order': 'Work Order / Subcontract PO', 'Material Request': 'Material Request', @@ -70,7 +70,7 @@ frappe.ui.form.on('Production Plan', { } }, - refresh: function(frm) { + refresh(frm) { if (frm.doc.docstatus === 1) { frm.trigger("show_progress"); @@ -158,7 +158,7 @@ frappe.ui.form.on('Production Plan', { set_field_options("projected_qty_formula", projected_qty_formula); }, - close_open_production_plan: (frm, close=false) => { + close_open_production_plan(frm, close=false) { frappe.call({ method: "set_status", freeze: true, @@ -170,7 +170,7 @@ frappe.ui.form.on('Production Plan', { }); }, - make_work_order: function(frm) { + make_work_order(frm) { frappe.call({ method: "make_work_order", freeze: true, @@ -181,7 +181,7 @@ frappe.ui.form.on('Production Plan', { }); }, - make_material_request: function(frm) { + make_material_request(frm) { frappe.confirm(__("Do you want to submit the material request"), function() { @@ -193,7 +193,7 @@ frappe.ui.form.on('Production Plan', { ); }, - create_material_request: function(frm, submit) { + create_material_request(frm, submit) { frm.doc.submit_material_request = submit; frappe.call({ @@ -206,7 +206,7 @@ frappe.ui.form.on('Production Plan', { }); }, - get_sales_orders: function(frm) { + get_sales_orders(frm) { frappe.call({ method: "get_open_sales_orders", doc: frm.doc, @@ -216,7 +216,7 @@ frappe.ui.form.on('Production Plan', { }); }, - get_material_request: function(frm) { + get_material_request(frm) { frappe.call({ method: "get_pending_material_requests", doc: frm.doc, @@ -226,7 +226,7 @@ frappe.ui.form.on('Production Plan', { }); }, - get_items: function (frm) { + get_items(frm) { frm.clear_table('prod_plan_references'); frappe.call({ @@ -238,7 +238,7 @@ frappe.ui.form.on('Production Plan', { } }); }, - combine_items: function (frm) { + combine_items(frm) { frm.clear_table("prod_plan_references"); frappe.call({ @@ -254,14 +254,14 @@ frappe.ui.form.on('Production Plan', { }); }, - combine_sub_items: (frm) => { + combine_sub_items(frm) { if (frm.doc.sub_assembly_items.length > 0) { frm.clear_table("sub_assembly_items"); frm.trigger("get_sub_assembly_items"); } }, - get_sub_assembly_items: function(frm) { + get_sub_assembly_items(frm) { frm.dirty(); frappe.call({ @@ -274,9 +274,25 @@ frappe.ui.form.on('Production Plan', { }); }, - get_items_for_mr: function(frm) { + toggle_for_warehouse(frm) { + frm.toggle_reqd("for_warehouse", true); + }, + + get_items_for_mr(frm) { if (!frm.doc.for_warehouse) { - frappe.throw(__("To make material requests, 'Make Material Request for Warehouse' field is mandatory")); + frm.trigger("toggle_for_warehouse"); + frappe.throw(__("Select the Warehouse")); + } + + frm.events.get_items_for_material_requests(frm, [{ + warehouse: frm.doc.for_warehouse + }]); + }, + + transfer_materials(frm) { + if (!frm.doc.for_warehouse) { + frm.trigger("toggle_for_warehouse"); + frappe.throw(__("Select the Warehouse")); } if (frm.doc.ignore_existing_ordered_qty) { @@ -287,18 +303,10 @@ frappe.ui.form.on('Production Plan', { title: title, fields: [ { - 'label': __('Target Warehouse'), - 'fieldtype': 'Link', - 'fieldname': 'target_warehouse', - 'read_only': true, - 'default': frm.doc.for_warehouse - }, - { - 'label': __('Source Warehouses (Optional)'), + 'label': __('Transfer From Warehouses'), 'fieldtype': 'Table MultiSelect', 'fieldname': 'warehouses', 'options': 'Production Plan Material Request Warehouse', - 'description': __('If source warehouse selected then system will create the material request with type Material Transfer from Source to Target warehouse. If not selected then will create the material request with type Purchase for the target warehouse.'), get_query: function () { return { filters: { @@ -307,6 +315,13 @@ frappe.ui.form.on('Production Plan', { }; }, }, + { + 'label': __('For Warehouse'), + 'fieldtype': 'Link', + 'fieldname': 'target_warehouse', + 'read_only': true, + 'default': frm.doc.for_warehouse + } ] }); @@ -320,8 +335,8 @@ frappe.ui.form.on('Production Plan', { } }, - get_items_for_material_requests: function(frm, warehouses) { - const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse', + get_items_for_material_requests(frm, warehouses) { + let set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse', 'min_order_qty', 'required_bom_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'ordered_qty', 'reserved_qty_for_production', 'material_request_type']; @@ -335,13 +350,13 @@ frappe.ui.form.on('Production Plan', { callback: function(r) { if(r.message) { frm.set_value('mr_items', []); - $.each(r.message, function(i, d) { - var item = frm.add_child('mr_items'); - for (let key in d) { - if (d[key] && in_list(set_fields, key)) { - item[key] = d[key]; + r.message.forEach(row => { + let d = frm.add_child('mr_items'); + set_fields.forEach(field => { + if (row[field]) { + d[field] = row[field]; } - } + }); }); } refresh_field('mr_items'); @@ -349,13 +364,7 @@ frappe.ui.form.on('Production Plan', { }); }, - for_warehouse: function(frm) { - if (frm.doc.mr_items && frm.doc.for_warehouse) { - frm.trigger("get_items_for_mr"); - } - }, - - download_materials_required: function(frm) { + download_materials_required(frm) { const fields = [{ fieldname: 'warehouses', fieldtype: 'Table MultiSelect', @@ -381,7 +390,7 @@ frappe.ui.form.on('Production Plan', { }, __('Select Warehouses to get Stock for Materials Planning'), __('Get Stock')); }, - show_progress: function(frm) { + show_progress(frm) { var bars = []; var message = ''; var title = ''; @@ -416,7 +425,7 @@ frappe.ui.form.on('Production Plan', { }); frappe.ui.form.on("Production Plan Item", { - item_code: function(frm, cdt, cdn) { + item_code(frm, cdt, cdn) { const row = locals[cdt][cdn]; if (row.item_code) { frappe.call({ @@ -435,7 +444,7 @@ frappe.ui.form.on("Production Plan Item", { }); frappe.ui.form.on("Material Request Plan Item", { - warehouse: function(frm, cdt, cdn) { + warehouse(frm, cdt, cdn) { const row = locals[cdt][cdn]; if (row.warehouse && row.item_code && frm.doc.company) { frappe.call({ diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json index 85f98430cd43..2624daa41e2d 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.json +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json @@ -38,6 +38,8 @@ "get_sub_assembly_items", "combine_sub_items", "sub_assembly_items", + "download_materials_request_plan_section_section", + "download_materials_required", "material_request_planning", "include_non_stock_items", "include_subcontracted_items", @@ -45,8 +47,8 @@ "ignore_existing_ordered_qty", "column_break_25", "for_warehouse", - "download_materials_required", "get_items_for_mr", + "transfer_materials", "section_break_27", "mr_items", "other_details", @@ -206,7 +208,7 @@ { "fieldname": "material_request_planning", "fieldtype": "Section Break", - "label": "Material Requirement Planning" + "label": "Material Request Planning" }, { "default": "1", @@ -235,12 +237,12 @@ "depends_on": "eval:!doc.__islocal", "fieldname": "download_materials_required", "fieldtype": "Button", - "label": "Download Required Materials" + "label": "Download Materials Request Plan" }, { "fieldname": "get_items_for_mr", "fieldtype": "Button", - "label": "Get Raw Materials For Production" + "label": "Get Raw Materials for Purchase" }, { "fieldname": "section_break_27", @@ -304,7 +306,7 @@ { "fieldname": "for_warehouse", "fieldtype": "Link", - "label": "Make Material Request for Warehouse", + "label": "Raw Materials Warehouse", "options": "Warehouse" }, { @@ -378,13 +380,24 @@ "fieldname": "combine_sub_items", "fieldtype": "Check", "label": "Consolidate Sub Assembly Items" + }, + { + "fieldname": "transfer_materials", + "fieldtype": "Button", + "label": "Get Raw Materials for Transfer" + }, + { + "collapsible": 1, + "fieldname": "download_materials_request_plan_section_section", + "fieldtype": "Section Break", + "label": "Download Materials Request Plan Section" } ], "icon": "fa fa-calendar", "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2022-03-25 09:15:25.017664", + "modified": "2022-11-26 14:51:08.774372", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Plan", diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index caff0a3e15c2..1eb82a5728aa 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -312,6 +312,9 @@ def get_mr_items(self): def add_items(self, items): refs = {} for data in items: + if not data.pending_qty: + continue + item_details = get_item_details(data.item_code) if self.combine_items: if item_details.bom_no in refs: diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json index df5862fcac80..0688278e091b 100644 --- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json +++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json @@ -83,7 +83,7 @@ "fieldname": "warehouse", "fieldtype": "Link", "in_list_view": 1, - "label": "For Warehouse", + "label": "FG Warehouse", "options": "Warehouse" }, { @@ -216,7 +216,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2022-03-24 04:54:09.940224", + "modified": "2022-11-25 14:15:40.061514", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Plan Item",