From 64f174fcaadc186e9bd9cddad96a007ac1690de8 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 26 Jul 2019 13:22:05 +0530 Subject: [PATCH] feat: Get item location from reference items - Add option to get items from multiple sales order - Add some required fiels to Pick TIcket Reference Item --- .../doctype/sales_order/sales_order.py | 22 ++++++-- .../stock/doctype/pick_ticket/pick_ticket.js | 25 ++++++++- .../doctype/pick_ticket/pick_ticket.json | 3 +- .../stock/doctype/pick_ticket/pick_ticket.py | 54 ++++++++----------- .../pick_ticket_reference_item.json | 25 ++++++++- 5 files changed, 88 insertions(+), 41 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 1f889ab58c..97a9739e79 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -998,6 +998,22 @@ def make_inter_company_purchase_order(source_name, target_doc=None): return make_inter_company_transaction("Sales Order", source_name, target_doc) @frappe.whitelist() -def make_pick_ticket(source_name, target_doc=None, offset=None): - from erpnext.stock.doctype.pick_ticket.pick_ticket import get_pick_list - return get_pick_list('Sales Order', source_name, 'items') +def make_pick_ticket(source_name, target_doc=None): + doc = get_mapped_doc("Sales Order", source_name, { + "Sales Order": { + "doctype": "Pick Ticket", + "validation": { + "docstatus": ["=", 1] + } + }, + "Sales Order Item": { + "doctype": "Pick Ticket Reference Item", + "field_map": { + "item_code": "item", + "parenttype": "reference_doctype", + "parent": "reference_name" + }, + }, + }, target_doc) + + return doc diff --git a/erpnext/stock/doctype/pick_ticket/pick_ticket.js b/erpnext/stock/doctype/pick_ticket/pick_ticket.js index f9ae38a3e2..a2d6cd71de 100644 --- a/erpnext/stock/doctype/pick_ticket/pick_ticket.js +++ b/erpnext/stock/doctype/pick_ticket/pick_ticket.js @@ -2,7 +2,28 @@ // For license information, please see license.txt frappe.ui.form.on('Pick Ticket', { - // onload: function(frm) { + refresh: (frm) => { + this.frm.add_custom_button(__('Sales Order'), function() { + erpnext.utils.map_current_doc({ + method: "erpnext.selling.doctype.sales_order.sales_order.make_pick_ticket", + source_doctype: "Sales Order", + target: frm, + setters: { + company: frm.doc.company || undefined, + }, + get_query_filters: { + docstatus: 1, + } + }); + }, __("Get items from")); + + frm.add_custom_button(__('Get Item Locations'), () => { + frm.trigger('set_item_locations'); + }); + }, + + set_item_locations: (frm) => { + frm.call('set_item_locations') + } - // } }); diff --git a/erpnext/stock/doctype/pick_ticket/pick_ticket.json b/erpnext/stock/doctype/pick_ticket/pick_ticket.json index fe331ac3c4..935192568e 100644 --- a/erpnext/stock/doctype/pick_ticket/pick_ticket.json +++ b/erpnext/stock/doctype/pick_ticket/pick_ticket.json @@ -43,7 +43,6 @@ "fieldtype": "Section Break" }, { - "collapsible": 1, "fieldname": "section_break_4", "fieldtype": "Section Break", "label": "Reference Items" @@ -55,7 +54,7 @@ "options": "Pick Ticket Reference Item" } ], - "modified": "2019-07-24 16:13:51.668880", + "modified": "2019-07-26 12:06:08.941760", "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 4c5fdb8297..eb54730616 100644 --- a/erpnext/stock/doctype/pick_ticket/pick_ticket.py +++ b/erpnext/stock/doctype/pick_ticket/pick_ticket.py @@ -7,16 +7,20 @@ import frappe from frappe.model.document import Document class PickTicket(Document): - pass + def set_item_locations(self): + reference_items = self.reference_document_items + self.delete_key('items') + for item in reference_items: + data = get_items_with_warehouse_and_quantity(item) -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.save() - return doc + for item_info in data: + self.append('items', item_info) + + for item in self.get('items'): + if frappe.get_cached_value('Item', item.item, 'has_serial_no'): + set_serial_nos(item) + elif frappe.get_cached_value('Item', item.item, 'has_batch_no'): + set_batch_no(item, self) def get_available_items(item): # gets all items available in different warehouses @@ -28,44 +32,30 @@ def get_available_items(item): return available_items -def get_items_with_warehouse_and_quantity(item_doc, reference_doc): +def get_items_with_warehouse_and_quantity(item_doc): items = [] - item_locations = get_available_items(item_doc.item_code) + item_locations = get_available_items(item_doc.item) remaining_qty = item_doc.qty - if not item_locations: - print('{} qty of {} is out of stock. Skipping...'.format(remaining_qty, item_doc.item)) - return items 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, + 'item': item_doc.item, 'qty': qty, 'warehouse': item_location.warehouse, - 'reference_doctype': reference_doc.doctype, - 'reference_name': reference_doc.name + 'reference_doctype': item_doc.reference_doctype, + 'reference_name': item_doc.reference_name }) remaining_qty -= qty + if remaining_qty: + print('---------- {} qty of {} is out of stock. Skipping... -------------'.format(remaining_qty, item_doc.item)) + return items + 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) - - doc.insert() - - for item in doc.get('items'): - if item.has_serial_no: - set_serial_nos(item) - elif item.has_batch_no: - set_batch_no(item, doc) - def set_serial_nos(item): serial_nos = frappe.get_all('Serial No', { 'item_code': item.item, diff --git a/erpnext/stock/doctype/pick_ticket_reference_item/pick_ticket_reference_item.json b/erpnext/stock/doctype/pick_ticket_reference_item/pick_ticket_reference_item.json index 446e075686..ae7ea3567e 100644 --- a/erpnext/stock/doctype/pick_ticket_reference_item/pick_ticket_reference_item.json +++ b/erpnext/stock/doctype/pick_ticket_reference_item/pick_ticket_reference_item.json @@ -4,7 +4,10 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "item" + "item", + "qty", + "reference_doctype", + "reference_name" ], "fields": [ { @@ -13,10 +16,28 @@ "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" } ], "istable": 1, - "modified": "2019-07-24 16:12:58.000378", + "modified": "2019-07-26 12:17:52.142186", "modified_by": "Administrator", "module": "Stock", "name": "Pick Ticket Reference Item",