From 8d55f81baa26df3da82bda179abadbb6f4c95c6d Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 22 Aug 2019 16:37:44 +0530 Subject: [PATCH] fix: Fix raw matterial selection based on finished item qty --- .../doctype/work_order/work_order.py | 43 ++++++++++++++++--- erpnext/stock/doctype/pick_list/pick_list.js | 33 ++++++++++---- .../stock/doctype/pick_list/pick_list.json | 4 +- erpnext/stock/doctype/pick_list/pick_list.py | 3 +- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 988cd223f2..804d22ce6b 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -711,13 +711,29 @@ def get_work_order_operation_data(work_order, operation, workstation): @frappe.whitelist() def create_pick_list(source_name, target_doc=None): + pick_list = json.loads(target_doc) + max_finished_goods_qty = frappe.db.get_value('Work Order', source_name, 'qty') def update_item_quantity(source, target, source_parent): - qty = source.required_qty - source.transferred_qty - target.qty = qty - target.stock_qty = qty - target.uom = frappe.get_value('Item', source.item_code, 'stock_uom') - target.stock_uom = target.uom - target.conversion_factor = 1 + # qty = source.required_qty - source.transferred_qty + # target.qty = qty + + pending_to_issue = flt(source.required_qty) - flt(source.transferred_qty) + desire_to_transfer = flt(source.required_qty) / max_finished_goods_qty * flt(pick_list.get('for_qty')) + + qty = 0 + if desire_to_transfer <= pending_to_issue: + qty = desire_to_transfer + elif pending_to_issue > 0: + qty = pending_to_issue + + if qty: + target.qty = qty + target.stock_qty = qty + target.uom = frappe.get_value('Item', source.item_code, 'stock_uom') + target.stock_uom = target.uom + target.conversion_factor = 1 + else: + target.delete() doc = get_mapped_doc("Work Order", source_name, { "Work Order": { @@ -733,4 +749,17 @@ def create_pick_list(source_name, target_doc=None): }, }, target_doc) - return doc + # # aggregate qty for same item + # item_map = frappe._dict() + # for item in doc.items: + # item.idx = None + # if not item_map.get(item.item_code): + # item_map[item.item_code] = item + # else: + # item_map[item.item_code].qty += item.qty + # item_map[item.item_code].stock_qty += item.stock_qty + + # doc.delete_key('items') + # doc.set('items', item_map.values()) + + return doc \ No newline at end of file diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js index e3064fe757..6f39d88a6b 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.js +++ b/erpnext/stock/doctype/pick_list/pick_list.js @@ -28,32 +28,35 @@ frappe.ui.form.on('Pick List', { frm.call('set_item_locations'); }).addClass('btn-primary'); } - if (frm.doc.items_based_on === 'Sales Order') { - frm.add_custom_button(__('Delivery Note'), () => frm.trigger('create_delivery_note'), __('Create')); - } else { - frm.add_custom_button(__('Stock Entry'), () => frm.trigger('create_stock_entry'), __('Create')); + if (frm.doc.docstatus == 1) { + if (frm.doc.items_based_on === 'Sales Order') { + frm.add_custom_button(__('Delivery Note'), () => frm.trigger('create_delivery_note'), __('Create')); + } else { + frm.add_custom_button(__('Stock Entry'), () => frm.trigger('create_stock_entry'), __('Create')); + } } }, work_order: (frm) => { - frm.clear_table('items'); frappe.db.get_value('Work Order', frm.doc.work_order, - ['qty', 'produced_qty'] + ['qty', 'material_transferred_for_manufacturing'] ).then(data => { let qty_data = data.message; - let max = qty_data.qty - qty_data.produced_qty; + let max = qty_data.qty - qty_data.material_transferred_for_manufacturing; frappe.prompt({ fieldtype: 'Float', - label: __('Qty'), + label: __('Qty of Finished Goods Item'), fieldname: 'qty', description: __('Max: {0}', [max]), default: max }, (data) => { - frm.set_value('qty', data.qty); + frm.set_value('for_qty', data.qty); if (data.qty > max) { frappe.msgprint(__('Quantity must not be more than {0}', [max])); return; } + frm.clear_table('items'); + frm.clear_table('locations'); erpnext.utils.map_current_doc({ method: 'erpnext.manufacturing.doctype.work_order.work_order.create_pick_list', target: frm, @@ -63,6 +66,8 @@ frappe.ui.form.on('Pick List', { }); }, items_based_on: (frm) => { + frm.clear_table('items'); + frm.clear_table('locations'); frm.trigger('add_get_items_button'); }, create_delivery_note(frm) { @@ -107,3 +112,13 @@ frappe.ui.form.on('Pick List', { }); } }); + + +// frappe.ui.form.on('Pick List Reference Item', { +// item_code: (frm, cdt, cdn) => { +// let row = locals[cdt][cdn]; +// if (row.item_code) { +// frappe.xcall(''); +// } +// } +// }); \ No newline at end of file diff --git a/erpnext/stock/doctype/pick_list/pick_list.json b/erpnext/stock/doctype/pick_list/pick_list.json index e321a0bf5b..0fd7dfbfc2 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.json +++ b/erpnext/stock/doctype/pick_list/pick_list.json @@ -8,7 +8,7 @@ "items_based_on", "customer", "work_order", - "qty", + "for_qty", "column_break_4", "parent_warehouse", "company", @@ -85,7 +85,7 @@ { "depends_on": "work_order", "description": "Qty of raw materials will be decided based on the qty of the Finished Goods Item", - "fieldname": "qty", + "fieldname": "for_qty", "fieldtype": "Float", "label": "Qty of Finished Goods Item" } diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index d7f420d8f6..f69fbd53b3 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -61,6 +61,7 @@ def get_items_with_warehouse_and_quantity(item_doc, from_warehouses, item_locati if uom_must_be_whole_number: qty = floor(qty) stock_qty = qty * item_doc.conversion_factor + if not stock_qty: break locations.append({ 'qty': qty, @@ -243,7 +244,7 @@ def create_stock_entry(pick_list): stock_entry.from_bom = 1 stock_entry.bom_no = work_order.bom_no stock_entry.use_multi_level_bom = work_order.use_multi_level_bom - stock_entry.fg_completed_qty = pick_list.qty + stock_entry.fg_completed_qty = pick_list.for_qty if work_order.bom_no: stock_entry.inspection_required = frappe.db.get_value('BOM', work_order.bom_no, 'inspection_required')