diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json index 6991da2888a..c4e6dabc17f 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.json +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json @@ -822,7 +822,7 @@ "columns": 0, "fieldname": "apply_discount", "fieldtype": "Check", - "hidden": 0, + "hidden": 1, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, @@ -836,7 +836,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -851,7 +851,7 @@ "collapsible": 0, "columns": 0, "default": "Grand Total", - "depends_on": "apply_discount", + "depends_on": "", "fieldname": "apply_discount_on", "fieldtype": "Select", "hidden": 0, @@ -1291,7 +1291,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-07-28 03:40:03.253088", + "modified": "2017-08-27 16:39:00.713225", "modified_by": "Administrator", "module": "Accounts", "name": "POS Profile", diff --git a/erpnext/accounts/doctype/pos_settings/__init__.py b/erpnext/accounts/doctype/pos_settings/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.js b/erpnext/accounts/doctype/pos_settings/pos_settings.js new file mode 100644 index 00000000000..fab766bb4b3 --- /dev/null +++ b/erpnext/accounts/doctype/pos_settings/pos_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('POS Settings', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.json b/erpnext/accounts/doctype/pos_settings/pos_settings.json new file mode 100644 index 00000000000..ab3976e1ba7 --- /dev/null +++ b/erpnext/accounts/doctype/pos_settings/pos_settings.json @@ -0,0 +1,93 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2017-08-28 16:46:41.732676", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "type_of_pos", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Type of POS", + "length": 0, + "no_copy": 0, + "options": "Online\nOffline", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2017-08-28 16:46:41.732676", + "modified_by": "Administrator", + "module": "Accounts", + "name": "POS Settings", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/pos_settings/pos_settings.py b/erpnext/accounts/doctype/pos_settings/pos_settings.py new file mode 100644 index 00000000000..4a71775a706 --- /dev/null +++ b/erpnext/accounts/doctype/pos_settings/pos_settings.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class POSSettings(Document): + def validate(self): + link = 'point-of-sale' if self.type_of_pos == 'Online' else 'pos' + desktop_icon = frappe.db.get_value('Desktop Icon', {'module_name': 'POS'}, 'name') + if desktop_icon: + doc = frappe.get_doc('Desktop Icon', desktop_icon) + doc.link = link + doc.save() \ No newline at end of file diff --git a/erpnext/accounts/doctype/pos_settings/test_pos_settings.js b/erpnext/accounts/doctype/pos_settings/test_pos_settings.js new file mode 100644 index 00000000000..639c94ed10d --- /dev/null +++ b/erpnext/accounts/doctype/pos_settings/test_pos_settings.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: POS Settings", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new POS Settings + () => frappe.tests.make('POS Settings', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 9dfacbdb5ec..0b6926f2876 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -303,7 +303,7 @@ class SalesInvoice(SellingController): for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name', 'selling_price_list', 'company', 'select_print_heading', 'cash_bank_account', - 'write_off_account', 'write_off_cost_center'): + 'write_off_account', 'write_off_cost_center', 'apply_discount_on'): if (not for_validate) or (for_validate and not self.get(fieldname)): self.set(fieldname, pos.get(fieldname)) diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 08630e59984..ed5a0f6b8d1 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -1,15 +1,16 @@ erpnext.SerialNoBatchSelector = Class.extend({ - init: function(opts) { + init: function(opts, show_dialog) { $.extend(this, opts); + this.show_dialog = show_dialog; // frm, item, warehouse_details, has_batch, oldest let d = this.item; // Don't show dialog if batch no or serial no already set - if(d && d.has_batch_no && !d.batch_no) { + if(d && d.has_batch_no && (!d.batch_no || this.show_dialog)) { this.has_batch = 1; this.setup(); - } else if(d && d.has_serial_no && !d.serial_no) { + } else if(d && d.has_serial_no && (!d.serial_no || this.show_dialog)) { this.has_batch = 0; this.setup(); } @@ -93,6 +94,11 @@ erpnext.SerialNoBatchSelector = Class.extend({ } }); + if(this.show_dialog) { + let d = this.item; + this.dialog.set_value('serial_no', d.serial_no); + } + this.dialog.show(); }, @@ -140,6 +146,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ this.map_row_values(this.item, this.values, 'serial_no', 'qty'); } refresh_field("items"); + this.callback && this.callback(this.item) }, map_row_values: function(row, values, number, qty_field, warehouse) { 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 a3ea04e201b..4096ed436ef 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.js +++ b/erpnext/selling/page/point_of_sale/point_of_sale.js @@ -120,6 +120,7 @@ class PointOfSale { if(!this.frm.doc.customer) { frappe.throw(__('Please select a customer')); } + this.update_item_in_cart(item_code, 'qty', '+1'); this.cart && this.cart.unselect_all(); }, @@ -131,53 +132,76 @@ class PointOfSale { } update_item_in_cart(item_code, field='qty', value=1) { - if(this.cart.exists(item_code)) { const item = this.frm.doc.items.find(i => i.item_code === item_code); - if (typeof value === 'string') { + if (typeof value === 'string' && !in_list(['serial_no', 'batch_no'], field)) { // value can be of type '+1' or '-1' value = item[field] + flt(value); } - if (field === 'serial_no') { - value = item.serial_no + '\n' + value; + if(field === 'serial_no') { + value = item.serial_no + '\n'+ value; } - this.update_item_in_frm(item, field, value) - .then(() => { - // update cart - this.cart.add_item(item); - }) - .then(() => { - this.cart.update_taxes_and_totals(); - this.cart.update_grand_total(); - }); - - // if (barcode) { - // const value = barcode['serial_no'] ? - // item.serial_no + '\n' + barcode['serial_no'] : barcode['batch_no']; - // frappe.model.set_value(item.doctype, item.name, - // Object.keys(barcode)[0], value); - // } else { - // } + if(field === 'qty' && (item.serial_no || item.batch_no)) { + this.select_batch_and_serial_no(item) + } else { + this.update_item_in_frm(item, field, value) + .then(() => { + // update cart + this.update_cart_data(item); + }) + } return; } + let args = { item_code: item_code }; + if (in_list(['serial_no', 'batch_no'], field)) { + args[field] = value; + } + // add to cur_frm - const item = this.frm.add_child('items', { item_code: item_code }); + const item = this.frm.add_child('items', args); this.frm.script_manager .trigger('item_code', item.doctype, item.name) .then(() => { // update cart - this.cart.add_item(item); - this.cart.update_taxes_and_totals(); - this.cart.update_grand_total(); + this.update_cart_data(item) }); } + select_batch_and_serial_no(item) { + let dialog = new erpnext.SerialNoBatchSelector({ + frm: this.frm, + item: item, + warehouse_details: { + type: "Warehouse", + name: item.warehouse + }, + callback: (item) => { + this.update_item_in_frm(item) + .then(() => { + // update cart + this.update_cart_data(item); + }) + } + }, true) + } + + update_cart_data(item) { + this.cart.add_item(item); + this.cart.update_taxes_and_totals(); + this.cart.update_grand_total(); + } + update_item_in_frm(item, field, value) { - return frappe.model.set_value(item.doctype, item.name, field, value) + if (field) { + frappe.model.set_value(item.doctype, item.name, field, value) + } + + 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); @@ -307,7 +331,7 @@ class PointOfSale { this.make_new_invoice(); }); - this.page.add_menu_item(__("Email"), function () { + this.page.add_menu_item(__("Email"), () => { this.frm.email_doc(); }); } @@ -398,11 +422,11 @@ class POSCart {