From ac8100f1e53de005e7cd2386b3275433209d20f8 Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Tue, 27 Sep 2022 15:44:38 +0530 Subject: [PATCH 1/3] fix: POS only validate QTY if is_stock_item POS invoice raised " Item not available " validation error even though item is non_stock. (cherry picked from commit e39e088f18177ab4a189da60c18d57b92a6f8aff) --- erpnext/accounts/doctype/pos_invoice/pos_invoice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 990fd22e4d6..42084661074 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -239,14 +239,14 @@ class POSInvoice(SalesInvoice): frappe.bold(d.warehouse), frappe.bold(d.qty), ) - if flt(available_stock) <= 0: + if is_stock_item and flt(available_stock) <= 0: frappe.throw( _("Row #{}: Item Code: {} is not available under warehouse {}.").format( d.idx, item_code, warehouse ), title=_("Item Unavailable"), ) - elif flt(available_stock) < flt(d.qty): + elif is_stock_item and flt(available_stock) < flt(d.qty): frappe.throw( _( "Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. Available quantity {}." From 96fa14be889832495ad7e87d33106175f6dc1060 Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Tue, 27 Sep 2022 23:44:56 +0530 Subject: [PATCH 2/3] fix: POS properly validate stock for bundle products Stock availability was not calculated properly for Product Bundle with non stock item so i have added logic to properly calculate that as well. (cherry picked from commit e392ea1104fee5add5c893c4e092edb6ad21f486) # Conflicts: # erpnext/selling/page/point_of_sale/pos_item_details.js --- erpnext/accounts/doctype/pos_invoice/pos_invoice.py | 9 ++++++--- erpnext/selling/page/point_of_sale/pos_controller.js | 4 ++-- erpnext/selling/page/point_of_sale/pos_item_details.js | 7 ++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 42084661074..6f1434d429b 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -634,11 +634,12 @@ def get_stock_availability(item_code, warehouse): pos_sales_qty = get_pos_reserved_qty(item_code, warehouse) return bin_qty - pos_sales_qty, is_stock_item else: - is_stock_item = False + is_stock_item = True if frappe.db.exists("Product Bundle", item_code): return get_bundle_availability(item_code, warehouse), is_stock_item else: - # Is a service item + is_stock_item = False + # Is a service item or non_stock item return 0, is_stock_item @@ -652,7 +653,9 @@ def get_bundle_availability(bundle_item_code, warehouse): available_qty = item_bin_qty - item_pos_reserved_qty max_available_bundles = available_qty / item.qty - if bundle_bin_qty > max_available_bundles: + if bundle_bin_qty > max_available_bundles and frappe.get_value( + "Item", item.item_code, "is_stock_item" + ): bundle_bin_qty = max_available_bundles pos_sales_qty = get_pos_reserved_qty(bundle_item_code, warehouse) diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index da7576e08de..24375d8252d 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -660,7 +660,7 @@ erpnext.PointOfSale.Controller = class { } else { return; } - } else if (available_qty < qty_needed) { + } else if (is_stock_item && available_qty < qty_needed) { frappe.throw({ message: __('Stock quantity not enough for Item Code: {0} under warehouse {1}. Available quantity {2}.', [bold_item_code, bold_warehouse, bold_available_qty]), indicator: 'orange' @@ -694,7 +694,7 @@ erpnext.PointOfSale.Controller = class { callback(res) { if (!me.item_stock_map[item_code]) me.item_stock_map[item_code] = {}; - me.item_stock_map[item_code][warehouse] = res.message[0]; + me.item_stock_map[item_code][warehouse] = res.message; } }); } diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js index 1d720f7291a..5b4f22b65a8 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_details.js +++ b/erpnext/selling/page/point_of_sale/pos_item_details.js @@ -242,13 +242,18 @@ erpnext.PointOfSale.ItemDetails = class { if (this.value) { me.events.form_updated(me.current_item, 'warehouse', this.value).then(() => { me.item_stock_map = me.events.get_item_stock_map(); +<<<<<<< HEAD const available_qty = me.item_stock_map[me.item_row.item_code][this.value]; +======= + const available_qty = me.item_stock_map[me.item_row.item_code][this.value][0]; + const is_stock_item = Boolean(me.item_stock_map[me.item_row.item_code][this.value][1]); +>>>>>>> e392ea1104 (fix: POS properly validate stock for bundle products) if (available_qty === undefined) { me.events.get_available_stock(me.item_row.item_code, this.value).then(() => { // item stock map is updated now reset warehouse me.warehouse_control.set_value(this.value); }) - } else if (available_qty === 0) { + } else if (available_qty === 0 && is_stock_item) { me.warehouse_control.set_value(''); const bold_item_code = me.item_row.item_code.bold(); const bold_warehouse = this.value.bold(); From a604eed1b9a2876ee53f9c430da9a640a26ddd00 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 28 Sep 2022 14:49:25 +0530 Subject: [PATCH 3/3] chore: Resolve conflicts --- erpnext/selling/page/point_of_sale/pos_item_details.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js index 5b4f22b65a8..f9b5bb2e452 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_details.js +++ b/erpnext/selling/page/point_of_sale/pos_item_details.js @@ -242,12 +242,8 @@ erpnext.PointOfSale.ItemDetails = class { if (this.value) { me.events.form_updated(me.current_item, 'warehouse', this.value).then(() => { me.item_stock_map = me.events.get_item_stock_map(); -<<<<<<< HEAD - const available_qty = me.item_stock_map[me.item_row.item_code][this.value]; -======= const available_qty = me.item_stock_map[me.item_row.item_code][this.value][0]; const is_stock_item = Boolean(me.item_stock_map[me.item_row.item_code][this.value][1]); ->>>>>>> e392ea1104 (fix: POS properly validate stock for bundle products) if (available_qty === undefined) { me.events.get_available_stock(me.item_row.item_code, this.value).then(() => { // item stock map is updated now reset warehouse