fix: Add option to create Stock Entry from Pick List

This commit is contained in:
Suraj Shetty 2019-08-21 22:10:27 +05:30
parent 298d38cde3
commit ec92486377
2 changed files with 80 additions and 30 deletions

View File

@ -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;

View File

@ -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("""