fix: Delivery note creation from pick list
- Changes in serial no and batch no seletion
- Changes in warehouse overrwite logic
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 14bf9d5..f6d4eee 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -263,7 +263,7 @@
if self.get("is_subcontracted"):
args["is_subcontracted"] = self.is_subcontracted
- ret = get_item_details(args, self)
+ ret = get_item_details(args, self, overwrite_warehouse=False)
for fieldname, value in ret.items():
if item.meta.get_field(fieldname) and value is not None:
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index b79a292..2dc3788 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -568,7 +568,7 @@
return doc
@frappe.whitelist()
-def make_delivery_note(source_name, target_doc=None):
+def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False):
def set_missing_values(source, target):
target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
@@ -593,23 +593,13 @@
or item.get("buying_cost_center") \
or item_group.get("buying_cost_center")
- target_doc = get_mapped_doc("Sales Order", source_name, {
+ mapper = {
"Sales Order": {
"doctype": "Delivery Note",
"validation": {
"docstatus": ["=", 1]
}
},
- "Sales Order Item": {
- "doctype": "Delivery Note Item",
- "field_map": {
- "rate": "rate",
- "name": "so_detail",
- "parent": "against_sales_order",
- },
- "postprocess": update_item,
- "condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1
- },
"Sales Taxes and Charges": {
"doctype": "Sales Taxes and Charges",
"add_if_empty": True
@@ -618,7 +608,21 @@
"doctype": "Sales Team",
"add_if_empty": True
}
- }, target_doc, set_missing_values)
+ }
+
+ if not skip_item_mapping:
+ mapper["Sales Order Item"] = {
+ "doctype": "Delivery Note Item",
+ "field_map": {
+ "rate": "rate",
+ "name": "so_detail",
+ "parent": "against_sales_order",
+ },
+ "postprocess": update_item,
+ "condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1
+ }
+
+ target_doc = get_mapped_doc("Sales Order", source_name, mapper, target_doc, set_missing_values)
return target_doc
@@ -999,9 +1003,16 @@
@frappe.whitelist()
def make_pick_list(source_name, target_doc=None):
+ def update_item_quantity(source, target, source_parent):
+ target.qty = flt(source.qty) - flt(source.delivered_qty)
+ target.stock_qty = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.conversion_factor)
+
doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
"doctype": "Pick List",
+ "field_map": {
+ "doctype": "items_based_on"
+ },
"validation": {
"docstatus": ["=", 1]
}
@@ -1009,11 +1020,11 @@
"Sales Order Item": {
"doctype": "Pick List Reference Item",
"field_map": {
- "item_code": "item",
- "parenttype": "reference_doctype",
- "parent": "reference_name",
- "name": "reference_document_item"
+ "parent": "sales_order",
+ "name": "sales_order_item"
},
+ "postprocess": update_item_quantity,
+ "conditions": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1
},
}, target_doc)
diff --git a/erpnext/stock/doctype/pick_list/pick_list.json b/erpnext/stock/doctype/pick_list/pick_list.json
index 3f96630..c7a5fc8 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.json
+++ b/erpnext/stock/doctype/pick_list/pick_list.json
@@ -7,6 +7,7 @@
"field_order": [
"company",
"column_break_4",
+ "items_based_on",
"parent_warehouse",
"section_break_4",
"reference_items",
@@ -50,9 +51,16 @@
"fieldtype": "Table",
"label": "Items To Be Picked",
"options": "Pick List Reference Item"
+ },
+ {
+ "default": "Sales Order",
+ "fieldname": "items_based_on",
+ "fieldtype": "Select",
+ "label": "Items Based On",
+ "options": "\nSales Order\nWork Order"
}
],
- "modified": "2019-08-01 10:50:17.055509",
+ "modified": "2019-08-13 19:30:01.151720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List",
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 77dacd5..20b4230 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -5,7 +5,10 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
-from frappe.model.mapper import get_mapped_doc
+from six import iteritems
+from frappe.model.mapper import get_mapped_doc, map_child_doc
+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
class PickList(Document):
def set_item_locations(self):
@@ -17,46 +20,56 @@
# Reset
self.delete_key('item_locations')
- for item in reference_items:
- data = get_items_with_warehouse_and_quantity(item, from_warehouses)
- for item_info in data:
- print(self.append('item_locations', item_info))
+ for item_doc in reference_items:
+ if frappe.get_cached_value('Item', item_doc.item_code, 'has_serial_no'):
+ item_locations = get_item_locations_based_on_serial_nos(item_doc)
+ elif frappe.get_cached_value('Item', item_doc.item_code, 'has_batch_no'):
+ item_locations = get_item_locations_based_on_batch_nos(item_doc)
+ else:
+ item_locations = get_items_with_warehouse_and_quantity(item_doc, from_warehouses)
- for item_doc in self.get('item_locations'):
- if frappe.get_cached_value('Item', item_doc.item, 'has_serial_no'):
- set_serial_nos(item_doc)
- elif frappe.get_cached_value('Item', item_doc.item, 'has_batch_no'):
- set_batch_no(item_doc, self)
+ for row in item_locations:
+ row.update({
+ 'item_code': item_doc.item_code,
+ 'sales_order': item_doc.sales_order,
+ 'sales_order_item': item_doc.sales_order_item,
+ 'uom': item_doc.uom,
+ 'stock_uom': item_doc.stock_uom,
+ 'conversion_factor': item_doc.conversion_factor,
+ 'stock_qty': row.get("qty", 0) * item_doc.conversion_factor,
+ 'picked_qty': row.get("qty", 0) * item_doc.conversion_factor
+ })
+ self.append('item_locations', row)
def get_items_with_warehouse_and_quantity(item_doc, from_warehouses):
- items = []
- item_locations = get_available_items(item_doc.item, from_warehouses)
- remaining_qty = item_doc.qty
+ item_locations = []
+ item_location_map = get_available_items(item_doc.item_code, from_warehouses)
+ remaining_stock_qty = item_doc.stock_qty
+ while remaining_stock_qty > 0 and item_location_map:
+ item_location = item_location_map.pop(0)
+ stock_qty = remaining_stock_qty if item_location.qty >= remaining_stock_qty else item_location.qty
+ qty = stock_qty / (item_doc.conversion_factor or 1)
- while remaining_qty > 0 and item_locations:
- item_location = item_locations.pop(0)
- qty = remaining_qty if item_location.qty >= remaining_qty else item_location.qty
- items.append({
- 'item': item_doc.item,
+ uom_must_be_whole_number = frappe.db.get_value("UOM", item_doc.uom, "must_be_whole_number")
+ if uom_must_be_whole_number:
+ qty = floor(qty)
+ stock_qty = qty * item_doc.conversion_factor
+
+ item_locations.append({
'qty': qty,
- 'warehouse': item_location.warehouse,
- 'reference_doctype': item_doc.reference_doctype,
- 'reference_name': item_doc.reference_name,
- 'reference_document_item': item_doc.reference_document_item,
+ 'warehouse': item_location.warehouse
})
- remaining_qty -= qty
+ remaining_stock_qty -= stock_qty
- if remaining_qty:
- frappe.msgprint('{} qty of {} is out of stock. Skipping...'.format(remaining_qty, item_doc.item))
- return items
+ if remaining_stock_qty:
+ frappe.msgprint('{0} {1} of {2} is not available.'
+ .format(remaining_stock_qty / item_doc.conversion_factor, item_doc.uom, item_doc.item_code))
+ return item_locations
- return items
-
-def get_available_items(item, from_warehouses):
+def get_available_items(item_code, from_warehouses):
# gets all items available in different warehouses
- # FIFO
filters = frappe._dict({
- 'item_code': item,
+ 'item_code': item_code,
'actual_qty': ['>', 0]
})
if from_warehouses:
@@ -71,79 +84,170 @@
def set_serial_nos(item_doc):
serial_nos = frappe.get_all('Serial No', {
- 'item_code': item_doc.item,
+ 'item_code': item_doc.item_code,
'warehouse': item_doc.warehouse
- }, limit=item_doc.qty, order_by='purchase_date')
+ }, 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 available in stock will have serial no?
+ # should we assume that all serialized item_code available in stock will have serial no?
-def set_batch_no(item_doc, parent_doc):
- batches = frappe.db.sql("""
+def get_item_locations_based_on_serial_nos(item_doc):
+ serial_nos = frappe.get_all('Serial No',
+ fields = ['name', 'warehouse'],
+ filters = {
+ 'item_code': item_doc.item_code,
+ 'warehouse': ['!=', '']
+ }, limit=item_doc.stock_qty, order_by='purchase_date', as_list=1)
+
+ remaining_stock_qty = flt(item_doc.stock_qty) - len(serial_nos)
+ if remaining_stock_qty:
+ frappe.msgprint('{0} {1} of {2} is not available.'
+ .format(remaining_stock_qty, item_doc.stock_uom, item_doc.item_code))
+
+ warehouse_serial_nos_map = frappe._dict()
+ for serial_no, warehouse in serial_nos:
+ warehouse_serial_nos_map.setdefault(warehouse, []).append(serial_no)
+
+ item_locations = []
+ for warehouse, serial_nos in iteritems(warehouse_serial_nos_map):
+ item_locations.append({
+ 'qty': len(serial_nos),
+ 'warehouse': warehouse,
+ 'serial_no': '\n'.join(serial_nos)
+ })
+
+ return item_locations
+
+def get_item_locations_based_on_batch_nos(item_doc):
+ batch_qty = frappe.db.sql("""
SELECT
- `batch_no`,
- SUM(`actual_qty`) AS `qty`
+ sle.`warehouse`,
+ sle.`batch_no`,
+ SUM(sle.`actual_qty`) AS `qty`
FROM
- `tabStock Ledger Entry`
+ `tabStock Ledger Entry` sle, `tabBatch` batch
WHERE
- `item_code`=%(item_code)s
- AND `warehouse`=%(warehouse)s
+ sle.batch_no = batch.name
+ and sle.`item_code`=%(item_code)s
+ and IFNULL(batch.expiry_date, '2200-01-01') > %(today)s
GROUP BY
`warehouse`,
`batch_no`,
`item_code`
HAVING `qty` > 0
+ ORDER BY IFNULL(batch.expiry_date, '2200-01-01')
""", {
- 'item_code': item_doc.item,
- 'warehouse': item_doc.warehouse,
+ 'item_code': item_doc.item_code,
+ 'today': today()
}, as_dict=1)
+ item_locations = []
required_qty = item_doc.qty
- while required_qty > 0 and batches:
- batch = batches.pop()
- batch_expiry = frappe.get_value('Batch', batch.batch_no, 'expiry_date')
- if batch_expiry and batch_expiry <= frappe.utils.getdate():
- frappe.msgprint('Skipping expired Batch {}'.format(batch.batch_no))
- continue
- item_doc.batch_no = batch.batch_no
- if batch.qty >= item_doc.qty:
- required_qty = 0
- break
+ for d in batch_qty:
+ if d.qty > required_qty:
+ d.qty = required_qty
else:
- # split item if quantity of item in batch is less that required
- # Look for another batch
+ required_qty -= d.qty
- required_qty -= batch.qty
- # set quantity of current item equal to batch quantity
- item_doc.set('qty', batch.qty)
- item_doc = parent_doc.append('items', {
- 'item': item_doc.item,
- 'qty': required_qty,
- 'warehouse': item_doc.warehouse,
- 'reference_doctype': item_doc.reference_doctype,
- 'reference_name': item_doc.reference_name,
- 'reference_document_item': item_doc.reference_document_item,
- })
+ item_locations.append(d)
+
+ if required_qty <= 0:
+ break
+
+ # required_qty = item_doc.qty
+ # while required_qty > 0 and batches:
+ # batch = batches.pop()
+ # batch_expiry = frappe.get_value('Batch', batch.batch_no, 'expiry_date')
+ # if batch_expiry and batch_expiry <= frappe.utils.getdate():
+ # frappe.msgprint('Skipping expired Batch {}'.format(batch.batch_no))
+ # continue
+ # item_doc.batch_no = batch.batch_no
+ # if batch.qty >= item_doc.qty:
+ # required_qty = 0
+ # break
+ # else:
+ # # split item_code if quantity of item_code in batch is less that required
+ # # Look for another batch
+
+ # required_qty -= batch.qty
+ # # set quantity of current item_code equal to batch quantity
+ # item_doc.set('qty', batch.qty)
+ # item_doc = parent_doc.append('items', {
+ # 'item_code': item_doc.item_code,
+ # 'qty': required_qty,
+ # 'warehouse': item_doc.warehouse,
+ # 'sales_order': item_doc.sales_order,
+ # 'sales_order_item': item_doc.sales_order_item,
+ # 'uom': item_doc.uom,
+ # 'stock_uom': item_doc.stock_uom,
+ # 'conversion_factor': item_doc.conversion_factor,
+ # 'stock_qty': qty * item_doc.conversion_factor,
+ # })
+
if required_qty:
- frappe.msgprint('No batches found for {} qty of {}. Skipping...'.format(required_qty, item_doc.item))
- parent_doc.remove(item_doc)
+ frappe.msgprint('No batches found for {} qty of {}.'.format(required_qty, item_doc.item_code))
+
+ return item_locations
@frappe.whitelist()
def make_delivery_note(source_name, target_doc=None):
- target_doc = get_mapped_doc("Pick List", source_name, {
- "Pick List": {
- "doctype": "Delivery Note",
- # "validation": {
- # "docstatus": ["=", 1]
- # }
- },
- "Pick List Item": {
+ pick_list = frappe.get_doc('Pick List', source_name)
+ sales_orders = [d.sales_order for d in pick_list.item_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, skip_item_mapping=True)
+
+ for location in pick_list.item_locations:
+ sales_order_item = frappe.get_cached_doc('Sales Order Item', location.sales_order_item)
+ item_table_mapper = {
"doctype": "Delivery Note Item",
"field_map": {
- "item": "item_code",
- "reference_docname": "against_sales_order",
+ "rate": "rate",
+ "name": "so_detail",
+ "parent": "against_sales_order",
},
- },
- }, target_doc)
+ "condition": lambda doc: abs(doc.delivered_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1
+ }
- return target_doc
\ No newline at end of file
+ dn_item = map_child_doc(sales_order_item, delivery_note, item_table_mapper)
+
+ if dn_item:
+ dn_item.warehouse = location.warehouse
+ dn_item.qty = location.qty
+
+ update_delivery_note_item(sales_order_item, dn_item, delivery_note)
+
+ set_delivery_note_missing_values(delivery_note)
+
+ 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:
+ cost_center = frappe.db.get_value('Item Default',
+ fieldname=['buying_cost_center'],
+ filters={
+ 'parent': source.item_code,
+ 'parenttype': 'Item',
+ 'company': delivery_note.company
+ })
+
+ if not cost_center:
+ cost_center = frappe.db.get_value('Item Default',
+ fieldname=['buying_cost_center'],
+ filters={
+ 'parent': source.item_group,
+ 'parenttype': 'Item Group',
+ 'company': delivery_note.company
+ })
+
+ target.cost_center = cost_center
\ No newline at end of file
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
index c83b696..9ee806a 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
@@ -4,33 +4,30 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
- "item",
+ "item_code",
"item_name",
"column_break_2",
"description",
- "has_batch_no",
- "has_serial_no",
"section_break_5",
"warehouse",
+ "quantity_section",
"qty",
+ "stock_qty",
"picked_qty",
+ "column_break_11",
+ "uom",
+ "stock_uom",
+ "conversion_factor",
+ "serial_no_and_batch_section",
"serial_no",
+ "column_break_20",
"batch_no",
- "reference_section",
- "reference_doctype",
- "reference_name",
- "reference_document_item"
+ "column_break_15",
+ "sales_order",
+ "sales_order_item"
],
"fields": [
{
- "fieldname": "item",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Item",
- "options": "Item",
- "read_only": 1
- },
- {
"fieldname": "qty",
"fieldtype": "Float",
"in_list_view": 1,
@@ -52,72 +49,31 @@
"read_only": 1
},
{
- "fetch_from": "item.item_name",
+ "fetch_from": "item_code.item_name",
"fieldname": "item_name",
"fieldtype": "Data",
"label": "Item Name",
"read_only": 1
},
{
- "fetch_from": "item.description",
+ "fetch_from": "item_code.description",
"fieldname": "description",
"fieldtype": "Text",
"label": "Description",
"read_only": 1
},
{
- "fieldname": "reference_document_item",
- "fieldtype": "Data",
- "label": "Reference Document Item",
- "read_only": 1
- },
- {
+ "depends_on": "serial_no",
"fieldname": "serial_no",
"fieldtype": "Small Text",
- "label": "Serial No",
- "read_only": 1
+ "label": "Serial No"
},
{
+ "depends_on": "batch_no",
"fieldname": "batch_no",
"fieldtype": "Link",
"label": "Batch No",
- "options": "Batch",
- "read_only": 1
- },
- {
- "default": "0",
- "fetch_from": "item.has_serial_no",
- "fieldname": "has_serial_no",
- "fieldtype": "Check",
- "label": "Has Serial No",
- "read_only": 1
- },
- {
- "default": "0",
- "fetch_from": "item.has_batch_no",
- "fieldname": "has_batch_no",
- "fieldtype": "Check",
- "label": "Has Batch No",
- "read_only": 1
- },
- {
- "fieldname": "reference_section",
- "fieldtype": "Section Break",
- "label": "Reference"
- },
- {
- "fieldname": "reference_doctype",
- "fieldtype": "Select",
- "label": "Reference Document Type",
- "options": "Sales Order\nWork Order",
- "read_only": 1
- },
- {
- "fieldname": "reference_name",
- "fieldtype": "Dynamic Link",
- "label": "Reference Document",
- "options": "reference_doctype",
- "read_only": 1
+ "options": "Batch"
},
{
"fieldname": "column_break_2",
@@ -126,10 +82,80 @@
{
"fieldname": "section_break_5",
"fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "stock_uom",
+ "fieldtype": "Link",
+ "label": "Stock UOM",
+ "options": "UOM",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_11",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "label": "UOM",
+ "options": "UOM",
+ "read_only": 1
+ },
+ {
+ "fieldname": "conversion_factor",
+ "fieldtype": "Float",
+ "label": "UOM Conversion Factor",
+ "read_only": 1
+ },
+ {
+ "fieldname": "stock_qty",
+ "fieldtype": "Float",
+ "label": "Qty as per Stock UOM",
+ "read_only": 1
+ },
+ {
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Item",
+ "options": "Item",
+ "read_only": 1
+ },
+ {
+ "fieldname": "quantity_section",
+ "fieldtype": "Section Break",
+ "label": "Quantity"
+ },
+ {
+ "fieldname": "column_break_15",
+ "fieldtype": "Section Break",
+ "label": "Reference"
+ },
+ {
+ "fieldname": "sales_order",
+ "fieldtype": "Link",
+ "label": "Sales Order",
+ "options": "Sales Order",
+ "read_only": 1
+ },
+ {
+ "fieldname": "sales_order_item",
+ "fieldtype": "Data",
+ "label": "Sales Order Item",
+ "read_only": 1
+ },
+ {
+ "fieldname": "serial_no_and_batch_section",
+ "fieldtype": "Section Break",
+ "label": "Serial No and Batch"
+ },
+ {
+ "fieldname": "column_break_20",
+ "fieldtype": "Column Break"
}
],
"istable": 1,
- "modified": "2019-07-30 23:47:53.566473",
+ "modified": "2019-08-14 18:41:37.727388",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List Item",
diff --git a/erpnext/stock/doctype/pick_list_reference_item/pick_list_reference_item.json b/erpnext/stock/doctype/pick_list_reference_item/pick_list_reference_item.json
index 23ef255..0aa94fe 100644
--- a/erpnext/stock/doctype/pick_list_reference_item/pick_list_reference_item.json
+++ b/erpnext/stock/doctype/pick_list_reference_item/pick_list_reference_item.json
@@ -4,46 +4,82 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
- "item",
+ "item_code",
+ "quantity_section",
"qty",
- "reference_doctype",
- "reference_name",
- "reference_document_item"
+ "stock_qty",
+ "column_break_5",
+ "uom",
+ "stock_uom",
+ "conversion_factor",
+ "reference_section",
+ "sales_order",
+ "sales_order_item"
],
"fields": [
{
- "fieldname": "item",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Item",
- "options": "Item"
- },
- {
- "fieldname": "reference_doctype",
- "fieldtype": "Link",
- "label": "Reference Document type",
- "options": "DocType"
- },
- {
- "fieldname": "reference_name",
- "fieldtype": "Dynamic Link",
- "label": "Reference Name",
- "options": "reference_doctype"
- },
- {
"fieldname": "qty",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Qty"
},
{
- "fieldname": "reference_document_item",
+ "fieldname": "quantity_section",
+ "fieldtype": "Section Break",
+ "label": "Quantity"
+ },
+ {
+ "fieldname": "stock_qty",
+ "fieldtype": "Float",
+ "label": "Stock Qty"
+ },
+ {
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "label": "UOM",
+ "options": "UOM"
+ },
+ {
+ "fieldname": "stock_uom",
+ "fieldtype": "Link",
+ "label": "Stock UOM",
+ "options": "UOM"
+ },
+ {
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Item",
+ "options": "Item"
+ },
+ {
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "reference_section",
+ "fieldtype": "Section Break",
+ "label": "Reference"
+ },
+ {
+ "fieldname": "sales_order",
+ "fieldtype": "Link",
+ "label": "Sales Order",
+ "options": "Sales Order"
+ },
+ {
+ "fieldname": "sales_order_item",
"fieldtype": "Data",
- "label": "Reference Document Item"
+ "label": "Sales Order Item"
+ },
+ {
+ "fieldname": "conversion_factor",
+ "fieldtype": "Float",
+ "label": "UOM Conversion Factor"
}
],
"istable": 1,
- "modified": "2019-07-30 23:43:30.901151",
+ "modified": "2019-08-14 18:38:28.867113",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List Reference Item",
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index f1d784c..41101f4 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -22,7 +22,7 @@
purchase_doctypes = ['Material Request', 'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice']
@frappe.whitelist()
-def get_item_details(args, doc=None):
+def get_item_details(args, doc=None, overwrite_warehouse=True):
"""
args = {
"item_code": "",
@@ -44,11 +44,15 @@
"set_warehouse": ""
}
"""
+
args = process_args(args)
+ print('warehouse', args.warehouse, '========')
item = frappe.get_cached_doc("Item", args.item_code)
validate_item_details(args, item)
- out = get_basic_details(args, item)
+ out = get_basic_details(args, item, overwrite_warehouse)
+
+ print('warehouse2', out.warehouse, '========')
get_item_tax_template(args, item, out)
out["item_tax_rate"] = get_item_tax_map(args.company, args.get("item_tax_template") if out.get("item_tax_template") is None \
@@ -178,7 +182,7 @@
throw(_("Item {0} must be a Sub-contracted Item").format(item.name))
-def get_basic_details(args, item):
+def get_basic_details(args, item, overwrite_warehouse=True):
"""
:param args: {
"item_code": "",
@@ -225,14 +229,26 @@
item_group_defaults = get_item_group_defaults(item.name, args.company)
brand_defaults = get_brand_defaults(item.name, args.company)
- warehouse = (args.get("set_warehouse") or item_defaults.get("default_warehouse") or
- item_group_defaults.get("default_warehouse") or brand_defaults.get("default_warehouse") or args.warehouse)
+ if overwrite_warehouse or not args.warehouse:
+ warehouse = (
+ args.get("set_warehouse") or
+ item_defaults.get("default_warehouse") or
+ item_group_defaults.get("default_warehouse") or
+ brand_defaults.get("default_warehouse") or
+ args.warehouse
+ )
- if not warehouse:
- defaults = frappe.defaults.get_defaults() or {}
- if defaults.get("default_warehouse") and frappe.db.exists("Warehouse",
- {'name': defaults.default_warehouse, 'company': args.company}):
- warehouse = defaults.default_warehouse
+ if not warehouse:
+ defaults = frappe.defaults.get_defaults() or {}
+ warehouse_exists = frappe.db.exists("Warehouse", {
+ 'name': defaults.default_warehouse,
+ 'company': args.company
+ })
+ if defaults.get("default_warehouse") and warehouse_exists:
+ warehouse = defaults.default_warehouse
+
+ else:
+ warehouse = args.warehouse
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
args['material_request_type'] = frappe.db.get_value('Material Request',
@@ -784,6 +800,7 @@
@frappe.whitelist()
def get_bin_details(item_code, warehouse):
+ print(item_code, warehouse, '---------------------------')
return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
["projected_qty", "actual_qty", "reserved_qty"], as_dict=True, cache=True) \
or {"projected_qty": 0, "actual_qty": 0, "reserved_qty": 0}