From ec37930404dd1bf4563e4bc2ea4acd767d77aff4 Mon Sep 17 00:00:00 2001 From: Subin Tom Date: Wed, 22 Dec 2021 19:14:47 +0530 Subject: [PATCH] fix: Allowing non stock items in POS --- .../accounts/doctype/pos_invoice/pos_invoice.py | 15 ++++++++++----- .../selling/page/point_of_sale/point_of_sale.py | 4 ++-- .../selling/page/point_of_sale/pos_controller.js | 16 +++++++++++----- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 0d6404c324..e6e92f367c 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -41,7 +41,7 @@ class POSInvoice(SalesInvoice): self.validate_serialised_or_batched_item() self.validate_stock_availablility() self.validate_return_items_qty() - self.validate_non_stock_items() + # self.validate_non_stock_items() self.set_status() self.set_account_for_mode_of_payment() self.validate_pos() @@ -143,9 +143,11 @@ class POSInvoice(SalesInvoice): def validate_stock_availablility(self): if self.is_return or self.docstatus != 1: return - allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock') for d in self.get('items'): + is_service_item = not (frappe.db.get_value('Item', d.get('item_code'), 'is_stock_item')) + if is_service_item: + return if d.serial_no: self.validate_pos_reserved_serial_nos(d) self.validate_delivered_serial_nos(d) @@ -475,9 +477,12 @@ def get_stock_availability(item_code, warehouse): bin_qty = get_bin_qty(item_code, warehouse) pos_sales_qty = get_pos_reserved_qty(item_code, warehouse) return bin_qty - pos_sales_qty - else: - if frappe.db.exists('Product Bundle', item_code): - return get_bundle_availability(item_code, warehouse) + elif frappe.db.exists('Product Bundle', item_code): + return get_bundle_availability(item_code, warehouse) + #To continue the flow considering a service item + elif frappe.db.get_value('Item', item_code, 'is_stock_item') == 0: + return 0 + def get_bundle_availability(bundle_item_code, warehouse): product_bundle = frappe.get_doc('Product Bundle', bundle_item_code) diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index db5b20e3e1..14201c65ab 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -99,7 +99,7 @@ def get_items(start, page_length, price_list, item_group, pos_profile, search_te ), {'warehouse': warehouse}, as_dict=1) if items_data: - items_data = filter_service_items(items_data) + # items_data = filter_service_items(items_data) items = [d.item_code for d in items_data] item_prices_data = frappe.get_all("Item Price", fields = ["item_code", "price_list_rate", "currency"], @@ -146,7 +146,7 @@ def search_for_serial_or_batch_or_barcode_number(search_value): def filter_service_items(items): for item in items: - if not item['is_stock_item']: + if not item.get('is_stock_item'): if not frappe.db.exists('Product Bundle', item['item_code']): items.remove(item) diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index e61a634aae..0508170dc1 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -637,11 +637,17 @@ erpnext.PointOfSale.Controller = class { const bold_warehouse = warehouse.bold(); const bold_available_qty = available_qty.toString().bold() if (!(available_qty > 0)) { - frappe.model.clear_doc(item_row.doctype, item_row.name); - frappe.throw({ - title: __("Not Available"), - message: __('Item Code: {0} is not available under warehouse {1}.', [bold_item_code, bold_warehouse]) - }) + frappe.db.get_value('Item', item_row.item_code, 'is_stock_item').then(({message}) => { + const is_service_item = message.is_stock_item; + console.log('is_service_item', is_service_item); + if (!is_service_item) return; + + frappe.model.clear_doc(item_row.doctype, item_row.name); + frappe.throw({ + title: __("Not Available"), + message: __('Item Code: {0} is not available under warehouse {1}.', [bold_item_code, bold_warehouse]) + }) + }); } else if (available_qty < qty_needed) { frappe.show_alert({ message: __('Stock quantity not enough for Item Code: {0} under warehouse {1}. Available quantity {2}.', [bold_item_code, bold_warehouse, bold_available_qty]),