fix: Add option to create Stock Entry from Pick List
This commit is contained in:
		
							parent
							
								
									298d38cde3
								
							
						
					
					
						commit
						ec92486377
					
				| @ -28,8 +28,11 @@ frappe.ui.form.on('Pick List', { | ||||
| 				frm.call('set_item_locations'); | ||||
| 			}).addClass('btn-primary'); | ||||
| 		} | ||||
| 
 | ||||
| 		frm.add_custom_button(__('Delivery Note'), () => frm.trigger('make_delivery_note'), __('Create')); | ||||
| 		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'); | ||||
| @ -42,12 +45,23 @@ frappe.ui.form.on('Pick List', { | ||||
| 	items_based_on: (frm) => { | ||||
| 		frm.trigger('add_get_items_button'); | ||||
| 	}, | ||||
| 	make_delivery_note(frm) { | ||||
| 	create_delivery_note(frm) { | ||||
| 		frappe.model.open_mapped_doc({ | ||||
| 			method: 'erpnext.stock.doctype.pick_list.pick_list.make_delivery_note', | ||||
| 			method: 'erpnext.stock.doctype.pick_list.pick_list.create_delivery_note', | ||||
| 			frm: frm | ||||
| 		}); | ||||
| 	}, | ||||
| 	create_stock_entry(frm) { | ||||
| 		// TODO: show dialog for qty
 | ||||
| 
 | ||||
| 		frappe.xcall('erpnext.stock.doctype.pick_list.pick_list.create_stock_entry', { | ||||
| 			'pick_list': frm.doc, | ||||
| 			'qty': 1 | ||||
| 		}).then(stock_entry => { | ||||
| 			frappe.model.sync(stock_entry); | ||||
| 			frappe.set_route("Form", 'Stock Entry', stock_entry.name); | ||||
| 		}); | ||||
| 	}, | ||||
| 	add_get_items_button(frm) { | ||||
| 		let source_doctype = frm.doc.items_based_on; | ||||
| 		if (source_doctype != 'Sales Order') return; | ||||
|  | ||||
| @ -4,11 +4,12 @@ | ||||
| 
 | ||||
| from __future__ import unicode_literals | ||||
| import frappe | ||||
| from frappe.model.document import Document | ||||
| import json | ||||
| from six import iteritems | ||||
| from frappe.model.mapper import get_mapped_doc, map_child_doc | ||||
| from frappe.model.document import Document | ||||
| from frappe.utils import floor, flt, today | ||||
| from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note as make_delivery_note_from_sales_order | ||||
| from frappe.model.mapper import get_mapped_doc, map_child_doc | ||||
| from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note as create_delivery_note_from_sales_order | ||||
| 
 | ||||
| # TODO: Prioritize SO or WO group warehouse | ||||
| 
 | ||||
| @ -49,7 +50,6 @@ class PickList(Document): | ||||
| 
 | ||||
| def get_items_with_warehouse_and_quantity(item_doc, from_warehouses, item_location_map): | ||||
| 	available_locations = item_location_map.get(item_doc.item_code) | ||||
| 
 | ||||
| 	locations = [] | ||||
| 	remaining_stock_qty = item_doc.stock_qty | ||||
| 	while remaining_stock_qty > 0 and available_locations: | ||||
| @ -98,15 +98,6 @@ def get_available_items(item_code, from_warehouses): | ||||
| 
 | ||||
| 	return available_items | ||||
| 
 | ||||
| def set_serial_nos(item_doc): | ||||
| 	serial_nos = frappe.get_all('Serial No', { | ||||
| 		'item_code': item_doc.item_code, | ||||
| 		'warehouse': item_doc.warehouse | ||||
| 	}, limit=item_doc.stock_qty, order_by='purchase_date') | ||||
| 	item_doc.set('serial_no', '\n'.join([serial_no.name for serial_no in serial_nos])) | ||||
| 
 | ||||
| 	# should we assume that all serialized item_code available in stock will have serial no? | ||||
| 
 | ||||
| def get_item_locations_based_on_serial_nos(item_doc): | ||||
| 	serial_nos = frappe.get_all('Serial No', | ||||
| 		fields = ['name', 'warehouse'], | ||||
| @ -176,26 +167,26 @@ def get_item_locations_based_on_batch_nos(item_doc): | ||||
| 	return locations | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def make_delivery_note(source_name, target_doc=None): | ||||
| def create_delivery_note(source_name, target_doc=None): | ||||
| 	pick_list = frappe.get_doc('Pick List', source_name) | ||||
| 	sales_orders = [d.sales_order for d in pick_list.locations] | ||||
| 	sales_orders = set(sales_orders) | ||||
| 
 | ||||
| 	delivery_note = None | ||||
| 	for sales_order in sales_orders: | ||||
| 		delivery_note = make_delivery_note_from_sales_order(sales_order, | ||||
| 		delivery_note = create_delivery_note_from_sales_order(sales_order, | ||||
| 			delivery_note, skip_item_mapping=True) | ||||
| 
 | ||||
| 	for location in pick_list.locations: | ||||
| 		sales_order_item = frappe.get_cached_doc('Sales Order Item', location.sales_order_item) | ||||
| 		item_table_mapper = { | ||||
| 			"doctype": "Delivery Note Item", | ||||
| 			"field_map": { | ||||
| 				"rate": "rate", | ||||
| 				"name": "so_detail", | ||||
| 				"parent": "against_sales_order", | ||||
| 			'doctype': 'Delivery Note Item', | ||||
| 			'field_map': { | ||||
| 				'rate': 'rate', | ||||
| 				'name': 'so_detail', | ||||
| 				'parent': 'against_sales_order', | ||||
| 			}, | ||||
| 			"condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1 | ||||
| 			'condition': lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1 | ||||
| 		} | ||||
| 
 | ||||
| 		dn_item = map_child_doc(sales_order_item, delivery_note, item_table_mapper) | ||||
| @ -211,11 +202,6 @@ def make_delivery_note(source_name, target_doc=None): | ||||
| 	return delivery_note | ||||
| 
 | ||||
| 
 | ||||
| def set_delivery_note_missing_values(target): | ||||
| 	target.run_method("set_missing_values") | ||||
| 	target.run_method("set_po_nos") | ||||
| 	target.run_method("calculate_taxes_and_totals") | ||||
| 
 | ||||
| def update_delivery_note_item(source, target, delivery_note): | ||||
| 	cost_center = frappe.db.get_value("Project", delivery_note.project, "cost_center") | ||||
| 	if not cost_center: | ||||
| @ -238,6 +224,56 @@ def update_delivery_note_item(source, target, delivery_note): | ||||
| 
 | ||||
| 	target.cost_center = cost_center | ||||
| 
 | ||||
| def set_delivery_note_missing_values(target): | ||||
| 	target.run_method('set_missing_values') | ||||
| 	target.run_method('set_po_nos') | ||||
| 	target.run_method('calculate_taxes_and_totals') | ||||
| 
 | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def create_stock_entry(pick_list, qty): | ||||
| 	pick_list = frappe.get_doc(json.loads(pick_list)) | ||||
| 	work_order = frappe.get_doc("Work Order", pick_list.get('work_order')) | ||||
| 	if not qty: | ||||
| 		qty = work_order.qty - work_order.material_transferred_for_manufacturing | ||||
| 	if not qty: return | ||||
| 
 | ||||
| 	stock_entry = frappe.new_doc('Stock Entry') | ||||
| 	stock_entry.purpose = 'Material Transfer For Manufacture' | ||||
| 	stock_entry.set_stock_entry_type() | ||||
| 	stock_entry.work_order = work_order.name | ||||
| 	stock_entry.company = work_order.company | ||||
| 	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 = (flt(work_order.qty) - flt(work_order.produced_qty)) | ||||
| 	if work_order.bom_no: | ||||
| 		stock_entry.inspection_required = frappe.db.get_value('BOM', | ||||
| 			work_order.bom_no, 'inspection_required') | ||||
| 
 | ||||
| 	is_wip_warehouse_group = frappe.db.get_value('Warehouse', work_order.wip_warehouse, 'is_group') | ||||
| 	if not (is_wip_warehouse_group and work_order.skip_transfer): | ||||
| 		wip_warehouse = work_order.wip_warehouse | ||||
| 	else: | ||||
| 		wip_warehouse = None | ||||
| 	stock_entry.to_warehouse = wip_warehouse | ||||
| 
 | ||||
| 	stock_entry.project = work_order.project | ||||
| 
 | ||||
| 	for location in pick_list.locations: | ||||
| 		item = frappe._dict() | ||||
| 		item.item_code = location.item_code | ||||
| 		item.s_warehouse = location.warehouse | ||||
| 		item.t_warehouse = wip_warehouse | ||||
| 		item.qty = location.qty | ||||
| 		item.uom = location.uom | ||||
| 		item.conversion_factor = location.conversion_factor | ||||
| 		item.stock_uom = location.stock_uom | ||||
| 
 | ||||
| 		stock_entry.append('items', item) | ||||
| 
 | ||||
| 	return stock_entry.as_dict() | ||||
| 
 | ||||
| @frappe.whitelist() | ||||
| def get_pending_work_orders(doctype, txt, searchfield, start, page_length, filters, as_dict): | ||||
| 	return frappe.db.sql(""" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user