feat: show only available items in point of sale (#23667)

* feat: show available items in pos

* feat: show selected pos profile on pos screen

* fix: codacy

* fix: codacy
This commit is contained in:
Saqib
2020-10-19 11:37:22 +05:30
committed by GitHub
parent 334c282f7b
commit 8e7a755aeb
5 changed files with 91 additions and 137 deletions

View File

@@ -1,4 +1,5 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "Prompt",
"creation": "2013-05-24 12:15:51",
@@ -22,6 +23,7 @@
"allow_user_to_edit_discount",
"allow_print_before_pay",
"display_items_in_stock",
"hide_unavailable_items",
"section_break_15",
"applicable_for_users",
"section_break_11",
@@ -389,11 +391,18 @@
"fieldtype": "Link",
"label": "Tax Category",
"options": "Tax Category"
},
{
"default": "0",
"fieldname": "hide_unavailable_items",
"fieldtype": "Check",
"label": "Hide Unavailable Items"
}
],
"icon": "icon-cog",
"idx": 1,
"modified": "2020-01-24 15:52:03.797701",
"links": [],
"modified": "2020-10-16 04:33:57.283873",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -1,123 +1,39 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-10-27 16:46:06.060930",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"creation": "2017-10-27 16:46:06.060930",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"default",
"user"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "default",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Default",
"length": 0,
"no_copy": 0,
"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
},
"default": "0",
"fieldname": "default",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Default"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "user",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "User",
"length": 0,
"no_copy": 0,
"options": "User",
"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
"fieldname": "user",
"fieldtype": "Link",
"in_list_view": 1,
"label": "User",
"options": "User"
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-23 17:13:16.005475",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile User",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"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
],
"istable": 1,
"links": [],
"modified": "2020-10-16 04:33:27.594859",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile User",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -175,6 +175,13 @@ def get_items_list(pos_profile, company):
if args_list:
cond = "and i.item_group in (%s)" % (', '.join(['%s'] * len(args_list)))
bin_join = bin_cond = ""
if pos_profile.get('hide_unavailable_items'):
bin_join = ",`tabBin` b"
bin_cond = "and i.item_code = b.item_code and ifnull(b.actual_qty, 0) > 0 "
if pos_profile.get('warehouse'):
bin_cond += "and b.warehouse = {}".format(frappe.db.escape(pos_profile.get('warehouse')))
return frappe.db.sql("""
select
i.name, i.item_code, i.item_name, i.description, i.item_group, i.has_batch_no,
@@ -186,11 +193,13 @@ def get_items_list(pos_profile, company):
left join `tabItem Default` id on id.parent = i.name and id.company = %s
left join `tabItem Tax` it on it.parent = i.name
left join `tabUOM Conversion Detail` c on i.name = c.parent and i.sales_uom = c.uom
{bin_join}
where
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
{cond}
{bin_cond}
group by i.item_code
""".format(cond=cond), tuple([company] + args_list), as_dict=1)
""".format(cond=cond, bin_join=bin_join, bin_cond=bin_cond), tuple([company] + args_list), as_dict=1)
def get_item_groups(pos_profile):

View File

@@ -81,7 +81,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
me.page.set_indicator(__("Online"), "green")
}
}
})
});
},
onload: function () {
@@ -278,6 +278,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
})
},
set_pos_profile_title(pos_profile) {
this.page.set_title_sub(
`<span class="indicator blue">
<a class="text-muted" href="#Form/POS Profile/${pos_profile}">${pos_profile}</a>
</span>`
);
},
get_data_from_server: function (callback) {
var me = this;
frappe.call({
@@ -286,6 +294,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
freeze_message: __("Master data syncing, it might take some time"),
callback: function (r) {
localStorage.setItem('doc', JSON.stringify(r.message.doc));
me.set_pos_profile_title(r.message.pos_profile.name);
me.init_master_data(r)
me.set_interval_for_si_sync();
me.check_internet_connection();

View File

@@ -16,7 +16,9 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
display_items_in_stock = 0
if pos_profile:
warehouse, display_items_in_stock = frappe.db.get_value('POS Profile', pos_profile, ['warehouse', 'display_items_in_stock'])
warehouse, display_items_in_stock, hide_unavailable_items = frappe.db.get_value(
'POS Profile', pos_profile, ['warehouse', 'display_items_in_stock', 'hide_unavailable_items']
)
if not frappe.db.exists('Item Group', item_group):
item_group = get_root_of('Item Group')
@@ -37,24 +39,31 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
lft, rgt = frappe.db.get_value('Item Group', item_group, ['lft', 'rgt'])
# locate function is used to sort by closest match from the beginning of the value
bin_join = bin_cond = ""
if hide_unavailable_items:
bin_join = ",`tabBin` b"
bin_cond = "and i.item_code = b.item_code and ifnull(b.actual_qty, 0) > 0 "
if warehouse:
bin_cond += "and b.warehouse = {}".format(frappe.db.escape(warehouse))
result = []
items_data = frappe.db.sql("""
SELECT
name AS item_code,
item_name,
stock_uom,
image AS item_image,
idx AS idx,
is_stock_item
i.name AS item_code,
i.item_name,
i.stock_uom,
i.image AS item_image,
i.idx AS idx,
i.is_stock_item
FROM
`tabItem`
`tabItem` i {bin_join}
WHERE
disabled = 0
AND has_variants = 0
AND is_sales_item = 1
AND item_group in (SELECT name FROM `tabItem Group` WHERE lft >= {lft} AND rgt <= {rgt})
AND {condition}
AND i.has_variants = 0
AND i.is_sales_item = 1
AND i.item_group in (SELECT name FROM `tabItem Group` WHERE lft >= {lft} AND rgt <= {rgt})
{condition} {bin_cond}
ORDER BY
idx desc
LIMIT
@@ -64,7 +73,9 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
page_length=page_length,
lft=lft,
rgt=rgt,
condition=condition
condition=condition,
bin_join=bin_join,
bin_cond=bin_cond
), as_dict=1)
if items_data:
@@ -154,16 +165,16 @@ def search_serial_or_batch_or_barcode_number(search_value):
def get_conditions(item_code, serial_no, batch_no, barcode):
if serial_no or batch_no or barcode:
return "name = {0}".format(frappe.db.escape(item_code))
return "and i.name = {0}".format(frappe.db.escape(item_code))
return """(name like {item_code}
or item_name like {item_code})""".format(item_code = frappe.db.escape('%' + item_code + '%'))
return ("""and (i.name like {item_code} or i.item_name like {item_code})"""
.format(item_code=frappe.db.escape('%' + item_code + '%')))
def get_item_group_condition(pos_profile):
cond = "and 1=1"
item_groups = get_item_groups(pos_profile)
if item_groups:
cond = "and item_group in (%s)"%(', '.join(['%s']*len(item_groups)))
cond = "and i.item_group in (%s)"%(', '.join(['%s']*len(item_groups)))
return cond % tuple(item_groups)