diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 9115ee88541..a9be620b993 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -212,11 +212,24 @@ class POSInvoice(SalesInvoice): frappe.throw(error_msg, title=_("Invalid Item"), as_list=True) def validate_stock_availablility(self): +<<<<<<< HEAD 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 self.is_return: + return + + if self.docstatus.is_draft() and not frappe.db.get_value('POS Profile', self.pos_profile, 'validate_stock_on_save'): + return + + from erpnext.stock.stock_ledger import is_negative_stock_allowed + + for d in self.get('items'): + is_service_item = not (frappe.db.get_value('Item', d.get('item_code'), 'is_stock_item')) +>>>>>>> aff7408775 (fix(pos): allow validating stock on save) if is_service_item: return if d.serial_no: diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json index 9c9f37bba27..11646a6517d 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.json +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json @@ -22,6 +22,7 @@ "hide_images", "hide_unavailable_items", "auto_add_item_to_cart", + "validate_stock_on_save", "column_break_16", "update_stock", "ignore_pricing_rule", @@ -351,6 +352,12 @@ { "fieldname": "column_break_25", "fieldtype": "Column Break" + }, + { + "default": "0", + "fieldname": "validate_stock_on_save", + "fieldtype": "Check", + "label": "Validate Stock on Save" } ], "icon": "icon-cog", @@ -378,10 +385,11 @@ "link_fieldname": "pos_profile" } ], - "modified": "2021-10-14 14:17:00.469298", + "modified": "2022-03-21 13:29:28.480533", "modified_by": "Administrator", "module": "Accounts", "name": "POS Profile", + "naming_rule": "Set by user", "owner": "Administrator", "permissions": [ { @@ -404,5 +412,6 @@ } ], "sort_field": "modified", - "sort_order": "DESC" + "sort_order": "DESC", + "states": [] } \ No newline at end of file diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js index 49e85ecc7a0..6974bed4f1f 100644 --- a/erpnext/selling/page/point_of_sale/pos_controller.js +++ b/erpnext/selling/page/point_of_sale/pos_controller.js @@ -720,7 +720,14 @@ erpnext.PointOfSale.Controller = class { } async save_and_checkout() { - this.frm.is_dirty() && await this.frm.save(); - this.payment.checkout(); + if (this.frm.is_dirty()) { + // only move to payment section if save is successful + frappe.route_hooks.after_save = () => this.payment.checkout(); + return this.frm.save( + null, null, null, () => this.cart.toggle_checkout_btn(true) // show checkout button on error + ); + } else { + this.payment.checkout(); + } } }; diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js index 326ee59d11a..b4ece46e6e1 100644 --- a/erpnext/selling/page/point_of_sale/pos_payment.js +++ b/erpnext/selling/page/point_of_sale/pos_payment.js @@ -172,7 +172,7 @@ erpnext.PointOfSale.Payment = class { frappe.ui.form.on('POS Invoice', 'coupon_code', (frm) => { if (frm.doc.coupon_code && !frm.applying_pos_coupon_code) { if (!frm.doc.ignore_pricing_rule) { - frm.applying_pos_coupon_code = true + frm.applying_pos_coupon_code = true; frappe.run_serially([ () => frm.doc.ignore_pricing_rule=1, () => frm.trigger('ignore_pricing_rule'),