diff --git a/pos_product_category_filter/__init__.py b/pos_product_category_filter/__init__.py new file mode 100644 index 000000000..313bd8fe8 --- /dev/null +++ b/pos_product_category_filter/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import models \ No newline at end of file diff --git a/pos_product_category_filter/__manifest__.py b/pos_product_category_filter/__manifest__.py new file mode 100644 index 000000000..bbc798cf3 --- /dev/null +++ b/pos_product_category_filter/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': 'POS Product Category Filter', + 'version': '10.0.1.0.0', + 'category': 'Point of Sale', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'http://www.cybrosys.com', + 'sequence': 6, + 'summary': 'Show Only Specified Categories of Product in Point of Sale ', + 'description': """ + +======================= + +""", + 'depends': ['point_of_sale'], + 'images': ['static/description/banner.jpg'], + 'data': ['views/category.xml', + 'views/template.xml'], + 'installable': True, + 'auto_install': False, +} diff --git a/pos_product_category_filter/models/__init__.py b/pos_product_category_filter/models/__init__.py new file mode 100644 index 000000000..a7247a97f --- /dev/null +++ b/pos_product_category_filter/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import category diff --git a/pos_product_category_filter/models/category.py b/pos_product_category_filter/models/category.py new file mode 100644 index 000000000..838e5b2b5 --- /dev/null +++ b/pos_product_category_filter/models/category.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from odoo import models, fields + + +class PosProductCateg(models.Model): + _inherit = 'pos.config' + + available_categ = fields.Many2many('pos.category', string='Available Product Categories') diff --git a/pos_product_category_filter/static/description/banner.jpg b/pos_product_category_filter/static/description/banner.jpg new file mode 100644 index 000000000..022c17a95 Binary files /dev/null and b/pos_product_category_filter/static/description/banner.jpg differ diff --git a/pos_product_category_filter/static/description/icon.png b/pos_product_category_filter/static/description/icon.png new file mode 100644 index 000000000..323e8d805 Binary files /dev/null and b/pos_product_category_filter/static/description/icon.png differ diff --git a/pos_product_category_filter/static/description/index.html b/pos_product_category_filter/static/description/index.html new file mode 100644 index 000000000..ed3921893 --- /dev/null +++ b/pos_product_category_filter/static/description/index.html @@ -0,0 +1,57 @@ +
+
+

Point of Sale : Setting Product Categories for POS

+

Cybrosys Technologies

+
+

+By installing this module, we can set available product categories for each POS in our system. +Only those categories set in the POS will be available in that particular POS. +

+
+
+
+ +
+
+

You can set it in POS form as:

+
+

+ Point of sale > Configuration > Point of Sale > Available Product Categories. +

+
+
+
+ +
+
+
+
+ + +
+

Need Any Help?

+ +
+ + diff --git a/pos_product_category_filter/static/description/pos.png b/pos_product_category_filter/static/description/pos.png new file mode 100644 index 000000000..3df67a4b8 Binary files /dev/null and b/pos_product_category_filter/static/description/pos.png differ diff --git a/pos_product_category_filter/static/src/js/category.js b/pos_product_category_filter/static/src/js/category.js new file mode 100644 index 000000000..d3e00b58e --- /dev/null +++ b/pos_product_category_filter/static/src/js/category.js @@ -0,0 +1,203 @@ +odoo.define('pos_product_category_filter.pos_product_category_filter', function (require) { + "use strict"; + var models = require('point_of_sale.models'); + var screens = require('point_of_sale.screens'); + var PosBaseWidget = require('point_of_sale.BaseWidget'); + var PosDB = require('point_of_sale.DB'); + var core = require('web.core'); + var gui = require('point_of_sale.gui'); + var Widget = require('web.Widget'); + var QWeb = core.qweb; + + var model1 = { + model: 'pos.category', + fields: ['id','name','parent_id','child_id','image'], + domain: null, + loaded: function(self, categories){ + for(var i = 0, len = categories.length; i < len; i++){ + categories[i].available = false; + for(var j = 0, jlen = self.config.available_categ.length; j < jlen; j++){ + if(categories[i].id == self.config.available_categ[j]){ + categories[i].available = true; + } + } + } + self.db.add_categories(categories); + }, + } + + for(var i=0; i< models.PosModel.prototype.models.length; i++){ + var model = models.PosModel.prototype.models[i]; + if(model.model === 'pos.category'){ + models.PosModel.prototype.models[i] = model1; + } + } + + PosDB.include({ + add_categories: function(categories){ + var self = this; + if(!this.category_by_id[this.root_category_id]){ + this.category_by_id[this.root_category_id] = { + id : this.root_category_id, + name : 'Root', + }; + } + for(var i=0, len = categories.length; i < len; i++){ + if(categories[i].available === true){ + categories[i].parent_id = 0; + } + } + for(var i=0, len = categories.length; i < len; i++){ + this.category_by_id[categories[i].id] = categories[i]; + } + for(var i=0, len = categories.length; i < len; i++){ + + var cat = categories[i]; + var parent_id = cat.parent_id[0] || this.root_category_id; + this.category_parent[cat.id] = cat.parent_id[0]; + if(!this.category_childs[parent_id]){ + this.category_childs[parent_id] = []; + } + this.category_childs[parent_id].push(cat.id); + } + function make_ancestors(cat_id, ancestors){ + self.category_ancestors[cat_id] = ancestors; + ancestors = ancestors.slice(0); + ancestors.push(cat_id); + var childs = self.category_childs[cat_id] || []; + for(var i=0, len = childs.length; i < len; i++){ + make_ancestors(childs[i], ancestors); + } + } + make_ancestors(this.root_category_id, []); + + }, + + add_products: function(products){ + console.log(this.category_by_id); + var stored_categories = this.product_by_category_id; + for(var i = 0, len = products.length; i < len; i++){ + var ancestor_ids = this.get_category_ancestors_ids(products[i].pos_categ_id[0]); + products[i].pos_categ_ancestors = ancestor_ids; + } + for(var i = 0, len = products.length; i < len; i++){ + products[i].available = false; + var category = this.get_category_by_id(products[i].pos_categ_id[0]); + if(category && category.available == true){ + products[i].available = true; + }else{ + if(products[i].pos_categ_ancestors){ + for(var j = 0, jlen = products[i].pos_categ_ancestors.length; j < jlen; j++){ + var temp_categ = this.get_category_by_id(products[i].pos_categ_ancestors[j]) + if(temp_categ != 0 && temp_categ.available == true){ + products[i].available = true; + } + } + } + } + } + if(!products instanceof Array){ + products = [products]; + } + for(var i = 0, len = products.length; i < len; i++){ + var product = products[i]; + var search_string = this._product_search_string(product); + var categ_id = product.pos_categ_id ? product.pos_categ_id[0] : this.root_category_id; + product.product_tmpl_id = product.product_tmpl_id[0]; + if(!stored_categories[categ_id]){ + stored_categories[categ_id] = []; + } + stored_categories[categ_id].push(product.id); + if(this.category_search_string[categ_id] === undefined){ + this.category_search_string[categ_id] = ''; + } + this.category_search_string[categ_id] += search_string; + var ancestors = this.get_category_ancestors_ids(categ_id) || []; + for(var j = 0, jlen = ancestors.length; j < jlen; j++){ + var ancestor = ancestors[j]; + if(! stored_categories[ancestor]){ + stored_categories[ancestor] = []; + } + stored_categories[ancestor].push(product.id); + + if( this.category_search_string[ancestor] === undefined){ + this.category_search_string[ancestor] = ''; + } + this.category_search_string[ancestor] += search_string; + } + this.product_by_id[product.id] = product; + if(product.barcode){ + this.product_by_barcode[product.barcode] = product; + } + } + }, + }); + + screens.ProductCategoriesWidget.include({ + renderElement: function(){ + var db = this.pos.db; + var self = this; + var el_str = QWeb.render(this.template, {widget: this}); + var el_node = document.createElement('div'); + + el_node.innerHTML = el_str; + el_node = el_node.childNodes[1]; + + if(this.el && this.el.parentNode){ + this.el.parentNode.replaceChild(el_node,this.el); + } + + this.el = el_node; + + var withpics = this.pos.config.iface_display_categ_images; + + var list_container = el_node.querySelector('.category-list'); + if (list_container) { + if (!withpics) { + list_container.classList.add('simple'); + } else { + list_container.classList.remove('simple'); + } + for(var i = 0, len = this.subcategories.length; i < len; i++){ + if(this.subcategories[i].available == true){ + list_container.appendChild(this.render_category(this.subcategories[i],withpics)); + }else{ + var ancestor_ids = db.get_category_ancestors_ids(this.subcategories[i].id) + for(var j = 0, jlen = ancestor_ids.length; j < jlen; j++){ + if(ancestor_ids[j] != 0){ + var ancestor = db.get_category_by_id(ancestor_ids[j]) + if(ancestor.available == true){ + list_container.appendChild(this.render_category(this.subcategories[i],withpics)); + } + } + } + } + + } + } + var buttons = el_node.querySelectorAll('.js-category-switch'); + for(var i = 0; i < buttons.length; i++){ + buttons[i].addEventListener('click',this.switch_category_handler); + } + var products = this.pos.db.get_product_by_category(this.category.id); + var available_products = []; + for(var i = 0, len = products.length; i < len; i++){ + if(products[i].available == true){ + available_products.push(products[i]); + } + } + this.product_list_widget.set_product_list(available_products); + + this.el.querySelector('.searchbox input').addEventListener('keypress',this.search_handler); + + this.el.querySelector('.searchbox input').addEventListener('keydown',this.search_handler); + + this.el.querySelector('.search-clear').addEventListener('click',this.clear_search_handler); + + if(this.pos.config.iface_vkeyboard && this.chrome.widget.keyboard){ + this.chrome.widget.keyboard.connect($(this.el.querySelector('.searchbox input'))); + } + }, + + }); +}); \ No newline at end of file diff --git a/pos_product_category_filter/views/category.xml b/pos_product_category_filter/views/category.xml new file mode 100644 index 000000000..110e68d93 --- /dev/null +++ b/pos_product_category_filter/views/category.xml @@ -0,0 +1,16 @@ + + + + + pos.config.form.view.inherit + pos.config + + + + + + + + + + \ No newline at end of file diff --git a/pos_product_category_filter/views/template.xml b/pos_product_category_filter/views/template.xml new file mode 100644 index 000000000..c1d32fe1c --- /dev/null +++ b/pos_product_category_filter/views/template.xml @@ -0,0 +1,11 @@ + + + + + + +