diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 181ac33782..1f889ab58c 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -999,77 +999,5 @@ def make_inter_company_purchase_order(source_name, target_doc=None): @frappe.whitelist() def make_pick_ticket(source_name, target_doc=None, offset=None): - - doc = get_mapped_doc("Sales Order", source_name, { - "Sales Order": { - "doctype": "Pick Ticket", - "validation": { - "docstatus": ["=", 1] - }, - "field_map": { - "name": "reference_name", - }, - }, - "Sales Order Item": { - "doctype": 'Pick Ticket Item', - "field_map": { - 'item_code': 'item' - }, - } - }, target_doc, postprocess) - - return doc - -def get_available_items(item): - # gets all items available in different warehouses - # FIFO - available_items = frappe.get_all('Bin', filters={ - 'item_code': item, - 'actual_qty': ['>', 0] - }, fields=['warehouse', 'actual_qty as qty'], order_by='creation') - - return available_items - -def get_items_with_warehouse_and_quantity(item_doc): - items = [] - item_locations = get_available_items(item_doc.item) - if not item_locations: return - - remaining_qty = item_doc.qty - - while remaining_qty > 0 and item_locations: - item_location = item_locations.pop(0) - qty = item_doc.qty if item_location.qty >= item_doc.qty else item_location.qty - items.append({ - 'qty': qty, - 'warehouse': item_location.warehouse - }) - remaining_qty -= qty - - return items - -def postprocess(source, doc): - for item in doc.items: - data = get_items_with_warehouse_and_quantity(item) - item.delete() - - for item_info in data: - print(item_info) - pick_item = frappe.new_doc('Pick Ticket Item', doc, 'items') - pick_item.update(item_info) - print(pick_item.qty) - - for item in doc.items: - if item.has_serial_no: - serial_nos = frappe.get_all('Serial No', { - 'item_code': item.item, - 'warehouse': item.warehouse - }, limit=item.qty, order_by='purchase_date') - item.serial_no = '\n'.join([serial_no.name for serial_no in serial_nos]) - - if item.has_batch_no: - serial_nos = frappe.get_all('Serial No', { - 'item_code': item.item, - 'warehouse': item.warehouse - }, limit=item.qty, order_by='purchase_date') - item.serial_no = '\n'.join([serial_no.name for serial_no in serial_nos]) \ No newline at end of file + from erpnext.stock.doctype.pick_ticket.pick_ticket import get_pick_list + return get_pick_list('Sales Order', source_name, 'items') diff --git a/erpnext/stock/doctype/pick_ticket/pick_ticket.json b/erpnext/stock/doctype/pick_ticket/pick_ticket.json index 28aa6997cb..392786f030 100644 --- a/erpnext/stock/doctype/pick_ticket/pick_ticket.json +++ b/erpnext/stock/doctype/pick_ticket/pick_ticket.json @@ -1,11 +1,10 @@ { + "autoname": "PICK.####", "creation": "2019-07-11 16:03:13.681045", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "reference_doctype", - "reference_name", "company", "column_break_4", "group_warehouse", @@ -13,18 +12,6 @@ "items" ], "fields": [ - { - "fieldname": "reference_doctype", - "fieldtype": "Select", - "label": "Reference Document Type", - "options": "Sales Order\nWork Order" - }, - { - "fieldname": "reference_name", - "fieldtype": "Dynamic Link", - "label": "Reference Name", - "options": "reference_doctype" - }, { "fieldname": "items", "fieldtype": "Table", @@ -53,7 +40,7 @@ "fieldtype": "Section Break" } ], - "modified": "2019-07-12 11:42:03.508514", + "modified": "2019-07-24 14:59:44.542987", "modified_by": "Administrator", "module": "Stock", "name": "Pick Ticket", diff --git a/erpnext/stock/doctype/pick_ticket/pick_ticket.py b/erpnext/stock/doctype/pick_ticket/pick_ticket.py index 7f2e89bb6c..8982688451 100644 --- a/erpnext/stock/doctype/pick_ticket/pick_ticket.py +++ b/erpnext/stock/doctype/pick_ticket/pick_ticket.py @@ -3,8 +3,73 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe from frappe.model.document import Document class PickTicket(Document): pass + +def get_pick_list(reference_doctype, reference_name, items_field): + doc = frappe.new_doc('Pick Ticket') + reference_doc = frappe.get_doc(reference_doctype, reference_name) + doc.company = reference_doc.company + items = reference_doc.get(items_field) + + add_picklist_items(items, doc, reference_doc) + + doc.insert() + + return doc + +def get_available_items(item): + # gets all items available in different warehouses + # FIFO + available_items = frappe.get_all('Bin', filters={ + 'item_code': item, + 'actual_qty': ['>', 0] + }, fields=['warehouse', 'actual_qty as qty'], order_by='creation') + + return available_items + +def get_items_with_warehouse_and_quantity(item_doc, reference_doc): + items = [] + item_locations = get_available_items(item_doc.item_code) + if not item_locations: return items + + remaining_qty = item_doc.qty + + 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_code, + 'qty': qty, + 'warehouse': item_location.warehouse, + 'reference_doctype': reference_doc.doctype, + 'reference_name': reference_doc.name + }) + remaining_qty -= qty + + return items + +def add_picklist_items(reference_items, doc, reference_doc): + for item in reference_items: + data = get_items_with_warehouse_and_quantity(item, reference_doc) + + for item_info in data: + doc.append('items', item_info) + + for item in doc.get('items'): + if item.has_serial_no: + serial_nos = frappe.get_all('Serial No', { + 'item_code': item.item, + 'warehouse': item.warehouse + }, limit=item.qty, order_by='purchase_date') + item.serial_no = '\n'.join([serial_no.name for serial_no in serial_nos]) + + # if item.has_batch_no: + # serial_nos = frappe.get_all('Batch', { + # 'item_code': item.item, + # 'warehouse': item.warehouse + # }, limit=item.qty, order_by='purchase_date') + # item.serial_no = '\n'.join([serial_no.name for serial_no in serial_nos]) \ No newline at end of file diff --git a/erpnext/stock/doctype/pick_ticket_item/pick_ticket_item.json b/erpnext/stock/doctype/pick_ticket_item/pick_ticket_item.json index cba0743c8a..33a42737b1 100644 --- a/erpnext/stock/doctype/pick_ticket_item/pick_ticket_item.json +++ b/erpnext/stock/doctype/pick_ticket_item/pick_ticket_item.json @@ -6,15 +6,20 @@ "field_order": [ "item", "item_name", + "column_break_2", "description", - "reference_document_item", + "has_batch_no", + "has_serial_no", + "section_break_5", "warehouse", "qty", "picked_qty", - "has_serial_no", - "has_batch_no", "serial_no", - "batch_no" + "batch_no", + "reference_section", + "reference_doctype", + "reference_name", + "reference_document_item" ], "fields": [ { @@ -47,13 +52,15 @@ "fetch_from": "item.item_name", "fieldname": "item_name", "fieldtype": "Data", - "label": "Item Name" + "label": "Item Name", + "read_only": 1 }, { "fetch_from": "item.description", "fieldname": "description", "fieldtype": "Text", - "label": "Description" + "label": "Description", + "read_only": 1 }, { "fieldname": "reference_document_item", @@ -89,10 +96,35 @@ "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" + }, + { + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "label": "Reference Document", + "options": "reference_doctype" + }, + { + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, + { + "fieldname": "section_break_5", + "fieldtype": "Section Break" } ], "istable": 1, - "modified": "2019-07-24 11:05:27.407791", + "modified": "2019-07-24 15:09:35.712289", "modified_by": "Administrator", "module": "Stock", "name": "Pick Ticket Item",