mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-01 03:09:09 +00:00
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:
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "Prompt",
|
"autoname": "Prompt",
|
||||||
"creation": "2013-05-24 12:15:51",
|
"creation": "2013-05-24 12:15:51",
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
"allow_user_to_edit_discount",
|
"allow_user_to_edit_discount",
|
||||||
"allow_print_before_pay",
|
"allow_print_before_pay",
|
||||||
"display_items_in_stock",
|
"display_items_in_stock",
|
||||||
|
"hide_unavailable_items",
|
||||||
"section_break_15",
|
"section_break_15",
|
||||||
"applicable_for_users",
|
"applicable_for_users",
|
||||||
"section_break_11",
|
"section_break_11",
|
||||||
@@ -389,11 +391,18 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Tax Category",
|
"label": "Tax Category",
|
||||||
"options": "Tax Category"
|
"options": "Tax Category"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "hide_unavailable_items",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Hide Unavailable Items"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2020-01-24 15:52:03.797701",
|
"links": [],
|
||||||
|
"modified": "2020-10-16 04:33:57.283873",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "POS Profile",
|
"name": "POS Profile",
|
||||||
|
|||||||
@@ -1,123 +1,39 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"creation": "2017-10-27 16:46:06.060930",
|
||||||
"allow_import": 0,
|
"doctype": "DocType",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2017-10-27 16:46:06.060930",
|
"field_order": [
|
||||||
"custom": 0,
|
"default",
|
||||||
"docstatus": 0,
|
"user"
|
||||||
"doctype": "DocType",
|
],
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "default",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Default"
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "user",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "User",
|
||||||
"columns": 0,
|
"options": "User"
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"links": [],
|
||||||
"hide_toolbar": 0,
|
"modified": "2020-10-16 04:33:27.594859",
|
||||||
"idx": 0,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "Accounts",
|
||||||
"in_create": 0,
|
"name": "POS Profile User",
|
||||||
"is_submittable": 0,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
"permissions": [],
|
||||||
"istable": 0,
|
"quick_entry": 1,
|
||||||
"max_attachments": 0,
|
"sort_field": "modified",
|
||||||
"modified": "2017-11-23 17:13:16.005475",
|
"sort_order": "DESC",
|
||||||
"modified_by": "Administrator",
|
"track_changes": 1
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
@@ -175,6 +175,13 @@ def get_items_list(pos_profile, company):
|
|||||||
if args_list:
|
if args_list:
|
||||||
cond = "and i.item_group in (%s)" % (', '.join(['%s'] * len(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("""
|
return frappe.db.sql("""
|
||||||
select
|
select
|
||||||
i.name, i.item_code, i.item_name, i.description, i.item_group, i.has_batch_no,
|
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 Default` id on id.parent = i.name and id.company = %s
|
||||||
left join `tabItem Tax` it on it.parent = i.name
|
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
|
left join `tabUOM Conversion Detail` c on i.name = c.parent and i.sales_uom = c.uom
|
||||||
|
{bin_join}
|
||||||
where
|
where
|
||||||
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
|
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
|
||||||
{cond}
|
{cond}
|
||||||
|
{bin_cond}
|
||||||
group by i.item_code
|
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):
|
def get_item_groups(pos_profile):
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
me.page.set_indicator(__("Online"), "green")
|
me.page.set_indicator(__("Online"), "green")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onload: function () {
|
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) {
|
get_data_from_server: function (callback) {
|
||||||
var me = this;
|
var me = this;
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@@ -286,6 +294,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
freeze_message: __("Master data syncing, it might take some time"),
|
freeze_message: __("Master data syncing, it might take some time"),
|
||||||
callback: function (r) {
|
callback: function (r) {
|
||||||
localStorage.setItem('doc', JSON.stringify(r.message.doc));
|
localStorage.setItem('doc', JSON.stringify(r.message.doc));
|
||||||
|
me.set_pos_profile_title(r.message.pos_profile.name);
|
||||||
me.init_master_data(r)
|
me.init_master_data(r)
|
||||||
me.set_interval_for_si_sync();
|
me.set_interval_for_si_sync();
|
||||||
me.check_internet_connection();
|
me.check_internet_connection();
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
|
|||||||
display_items_in_stock = 0
|
display_items_in_stock = 0
|
||||||
|
|
||||||
if pos_profile:
|
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):
|
if not frappe.db.exists('Item Group', item_group):
|
||||||
item_group = get_root_of('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'])
|
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
|
# 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 = []
|
result = []
|
||||||
|
|
||||||
items_data = frappe.db.sql("""
|
items_data = frappe.db.sql("""
|
||||||
SELECT
|
SELECT
|
||||||
name AS item_code,
|
i.name AS item_code,
|
||||||
item_name,
|
i.item_name,
|
||||||
stock_uom,
|
i.stock_uom,
|
||||||
image AS item_image,
|
i.image AS item_image,
|
||||||
idx AS idx,
|
i.idx AS idx,
|
||||||
is_stock_item
|
i.is_stock_item
|
||||||
FROM
|
FROM
|
||||||
`tabItem`
|
`tabItem` i {bin_join}
|
||||||
WHERE
|
WHERE
|
||||||
disabled = 0
|
disabled = 0
|
||||||
AND has_variants = 0
|
AND i.has_variants = 0
|
||||||
AND is_sales_item = 1
|
AND i.is_sales_item = 1
|
||||||
AND item_group in (SELECT name FROM `tabItem Group` WHERE lft >= {lft} AND rgt <= {rgt})
|
AND i.item_group in (SELECT name FROM `tabItem Group` WHERE lft >= {lft} AND rgt <= {rgt})
|
||||||
AND {condition}
|
{condition} {bin_cond}
|
||||||
ORDER BY
|
ORDER BY
|
||||||
idx desc
|
idx desc
|
||||||
LIMIT
|
LIMIT
|
||||||
@@ -64,7 +73,9 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
|
|||||||
page_length=page_length,
|
page_length=page_length,
|
||||||
lft=lft,
|
lft=lft,
|
||||||
rgt=rgt,
|
rgt=rgt,
|
||||||
condition=condition
|
condition=condition,
|
||||||
|
bin_join=bin_join,
|
||||||
|
bin_cond=bin_cond
|
||||||
), as_dict=1)
|
), as_dict=1)
|
||||||
|
|
||||||
if items_data:
|
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):
|
def get_conditions(item_code, serial_no, batch_no, barcode):
|
||||||
if serial_no or batch_no or 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}
|
return ("""and (i.name like {item_code} or i.item_name like {item_code})"""
|
||||||
or item_name like {item_code})""".format(item_code = frappe.db.escape('%' + item_code + '%'))
|
.format(item_code=frappe.db.escape('%' + item_code + '%')))
|
||||||
|
|
||||||
def get_item_group_condition(pos_profile):
|
def get_item_group_condition(pos_profile):
|
||||||
cond = "and 1=1"
|
cond = "and 1=1"
|
||||||
item_groups = get_item_groups(pos_profile)
|
item_groups = get_item_groups(pos_profile)
|
||||||
if item_groups:
|
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)
|
return cond % tuple(item_groups)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user