diff --git a/erpnext/__init__.py b/erpnext/__init__.py index c589e35977..405274a144 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -4,7 +4,7 @@ import inspect import frappe from erpnext.hooks import regional_overrides -__version__ = '9.0.5' +__version__ = '9.0.6' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index 2b3459ad27..dd10977665 100644 --- a/erpnext/accounts/doctype/sales_invoice/pos.py +++ b/erpnext/accounts/doctype/sales_invoice/pos.py @@ -417,6 +417,7 @@ def make_contact(args,customer): 'link_doctype': 'Customer', 'link_name': customer }) + doc.flags.ignore_mandatory = True doc.save(ignore_permissions=True) def make_address(args, customer): @@ -441,6 +442,7 @@ def make_address(args, customer): address.is_primary_address = 1 address.is_shipping_address = 1 address.update(args) + address.flags.ignore_mandatory = True address.save(ignore_permissions = True) def make_email_queue(email_queue): diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index be0b6f7b72..57a8a186b9 100644 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -113,6 +113,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ }); this.page.add_menu_item(__("Sync Offline Invoices"), function () { + me.freeze_screen = true; me.sync_sales_invoice() }); @@ -1684,6 +1685,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ set_interval_for_si_sync: function () { var me = this; setInterval(function () { + me.freeze_screen = false; me.sync_sales_invoice() }, 60000) }, @@ -1697,9 +1699,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ this.freeze = this.customer_doc.display } + freeze_screen = this.freeze_screen || false; + if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) { frappe.call({ method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice", + freeze: freeze_screen, args: { doc_list: me.si_docs, email_queue_list: me.email_queue_list, diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 3e2414e665..69e3d2fb9f 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -96,7 +96,17 @@ erpnext.SerialNoBatchSelector = Class.extend({ if(this.show_dialog) { let d = this.item; - this.dialog.set_value('serial_no', d.serial_no); + if (d.has_serial_no && d.serial_no) { + this.dialog.set_value('serial_no', d.serial_no); + } else if (d.batch_no) { + this.dialog.fields_dict.batches.df.data.push({ + 'batch_no': d.batch_no, + 'actual_qty': d.actual_qty, + 'selected_qty': d.qty + }); + + this.dialog.fields_dict.batches.grid.refresh(); + } } this.dialog.show(); @@ -116,8 +126,10 @@ erpnext.SerialNoBatchSelector = Class.extend({ } values.batches.map((batch, i) => { if(!batch.selected_qty || batch.selected_qty === 0 ) { - frappe.throw(__("Please select quantity on row " + (i+1))); - return false; + if (!this.show_dialog) { + frappe.throw(__("Please select quantity on row " + (i+1))); + return false; + } } }); return true; @@ -125,9 +137,11 @@ erpnext.SerialNoBatchSelector = Class.extend({ } else { let serial_nos = values.serial_no || ''; if (!serial_nos || !serial_nos.replace(/\s/g, '').length) { - frappe.throw(__("Please enter serial numbers for serialized item " - + values.item_code)); - return false; + if (!this.show_dialog) { + frappe.throw(__("Please enter serial numbers for serialized item " + + values.item_code)); + return false; + } } return true; } diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js index 1b67ff2b72..f9045b5454 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -89,6 +89,7 @@ erpnext.pos.PointOfSale = class PointOfSale { this.cart = new POSCart({ frm: this.frm, wrapper: this.wrapper.find('.cart-container'), + pos_profile: this.pos_profile, events: { on_customer_change: (customer) => this.frm.set_value('customer', customer), on_field_change: (item_code, field, value) => { @@ -196,6 +197,7 @@ erpnext.pos.PointOfSale = class PointOfSale { this.update_item_in_frm(item) .then(() => { // update cart + this.remove_item_from_cart(item); this.update_cart_data(item); }); }, true); @@ -215,12 +217,18 @@ erpnext.pos.PointOfSale = class PointOfSale { return this.frm.script_manager .trigger('qty', item.doctype, item.name) .then(() => { - if (field === 'qty' && value === 0) { - frappe.model.clear_doc(item.doctype, item.name); + if (field === 'qty') { + this.remove_item_from_cart(item); } }); } + remove_item_from_cart(item) { + if (item.qty === 0) { + frappe.model.clear_doc(item.doctype, item.name); + } + } + make_payment_modal() { this.payment = new Payment({ frm: this.frm, @@ -363,10 +371,11 @@ erpnext.pos.PointOfSale = class PointOfSale { }; class POSCart { - constructor({frm, wrapper, events}) { + constructor({frm, wrapper, pos_profile, events}) { this.frm = frm; this.wrapper = wrapper; this.events = events; + this.pos_profile = pos_profile; this.make(); this.bind_events(); } @@ -514,6 +523,7 @@ class POSCart { } make_customer_field() { + let customer = this.frm.doc.customer || this.pos_profile['customer']; this.customer_field = frappe.ui.form.make_control({ df: { fieldtype: 'Link', @@ -521,7 +531,6 @@ class POSCart { fieldname: 'customer', options: 'Customer', reqd: 1, - default: this.frm.doc.customer, onchange: () => { this.events.on_customer_change(this.customer_field.get_value()); } @@ -529,6 +538,10 @@ class POSCart { parent: this.wrapper.find('.customer-field'), render_input: true }); + + if (customer) { + this.customer_field.set_value(customer); + } } make_numpad() { @@ -919,7 +932,7 @@ class POSItems { } if(batch_no) { this.events.update_cart(items[0].item_code, - 'batch_no', serial_no); + 'batch_no', batch_no); this.search_field.set_value(''); } });