Browse Source
Add a new module 'pos_top_sellers'.
Add a new module 'pos_top_sellers'.
Add new statistics to point of sale report section to show your best selling products for all of your shops over a given date range.pull/22/head
Peter Hahn
10 years ago
9 changed files with 702 additions and 0 deletions
-
21pos_top_sellers/__init__.py
-
73pos_top_sellers/__openerp__.py
-
72pos_top_sellers/i18n/de.po
-
3pos_top_sellers/ir.model.access.csv
-
291pos_top_sellers/pos_top_sellers.py
-
83pos_top_sellers/pos_top_sellers_view.xml
-
4pos_top_sellers/static/src/css/pos_top_sellers.css
-
143pos_top_sellers/static/src/js/pos_top_sellers.js
-
12pos_top_sellers/static/src/xml/pos_top_sellers.xml
@ -0,0 +1,21 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Copyright (C) 2015 initOS GmbH & Co. KG (<http://www.initos.com>). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
|
|||
from . import pos_top_sellers |
@ -0,0 +1,73 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Copyright (C) 2015 initOS GmbH & Co. KG (<http://www.initos.com>). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
|
|||
{ |
|||
'name': 'Point of sale topseller report.', |
|||
'version': '1.0', |
|||
'category': '', |
|||
'summary': 'Report topseller products in point of sale for all of your shops.', |
|||
'description': """ |
|||
Report top selling products for point of sale |
|||
============================================= |
|||
|
|||
This module adds 2 new reports to report sales done via point of sale for all of |
|||
your companies shops. |
|||
|
|||
Top 40 sales by shop |
|||
-------------------- |
|||
* List top 40 sold products in a given period for all of your shops. |
|||
* Click on a product to show sales for this product by shop on a daily basis over that timeframe. |
|||
|
|||
Recent sales by shop for a given product |
|||
---------------------------------------- |
|||
* Show sales for a product by shop on a daily basis over a given period. |
|||
* Select product by product default code. |
|||
* Show current stock and total quantity of sales for this product and period. |
|||
""", |
|||
'author': 'initOS GmbH & Co. KG', |
|||
'website': 'http://www.initos.com', |
|||
'depends': [ |
|||
'web', |
|||
'web_listview_date_range_bar', |
|||
'sale', |
|||
'product', |
|||
'point_of_sale', |
|||
], |
|||
'data': [ |
|||
'ir.model.access.csv', |
|||
'pos_top_sellers_view.xml', |
|||
], |
|||
'demo': [ |
|||
], |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': False, |
|||
'images': [ |
|||
], |
|||
'css': [ |
|||
'static/src/css/pos_top_sellers.css', |
|||
], |
|||
'js': [ |
|||
'static/src/js/pos_top_sellers.js', |
|||
], |
|||
'qweb': [ |
|||
'static/src/xml/pos_top_sellers.xml', |
|||
], |
|||
} |
@ -0,0 +1,72 @@ |
|||
# Translation of OpenERP Server. |
|||
# This file contains the translation of the following modules: |
|||
# * pos_top_sellers |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: OpenERP Server 7.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2015-04-16 07:54+0000\n" |
|||
"PO-Revision-Date: 2015-04-16 09:54+0100\n" |
|||
"Last-Translator: \n" |
|||
"Language-Team: \n" |
|||
"Language: de\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"X-Generator: Poedit 1.5.4\n" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: code:addons/pos_top_sellers/pos_top_sellers.py:117 |
|||
#, python-format |
|||
msgid "Currently in stock" |
|||
msgstr "Lagerbestand" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: code:addons/pos_top_sellers/pos_top_sellers.py:214 |
|||
#, python-format |
|||
msgid "QT" |
|||
msgstr "Menge" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: model:ir.model,name:pos_top_sellers.model_pos_top_sellers_shop_report |
|||
msgid "pos.top.sellers.shop.report" |
|||
msgstr "" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: code:addons/pos_top_sellers/pos_top_sellers.py:116 |
|||
#, python-format |
|||
msgid "Sold" |
|||
msgstr "Verkäufe" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: model:ir.actions.act_window,name:pos_top_sellers.action_pos_top_sellers_shop_report |
|||
#: model:ir.ui.menu,name:pos_top_sellers.menu_pos_top_sellers_shop_report |
|||
#: view:pos.top.sellers.shop.report:0 |
|||
msgid "Best sellers by shop" |
|||
msgstr "Verkaufscharts Shop" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: model:ir.actions.act_window,name:pos_top_sellers.action_pos_top_sellers_product_report |
|||
#: model:ir.ui.menu,name:pos_top_sellers.menu_pos_top_sellers_product_report |
|||
#: view:pos.top.sellers.product.report:0 |
|||
msgid "Recent sales by product/shop" |
|||
msgstr "Verkäufe Produkt/Shop" |
|||
|
|||
#. module: pos_top_sellers |
|||
#. openerp-web |
|||
#: code:addons/pos_top_sellers/static/src/xml/pos_top_sellers.xml:7 |
|||
#, python-format |
|||
msgid "Product code:" |
|||
msgstr "Artikelnummer:" |
|||
|
|||
#. module: pos_top_sellers |
|||
#: model:ir.model,name:pos_top_sellers.model_pos_top_sellers_product_report |
|||
msgid "pos.top.sellers.product.report" |
|||
msgstr "" |
|||
|
|||
#~ msgid "Date from:" |
|||
#~ msgstr "Anfangsdatum:" |
|||
|
|||
#~ msgid "Date end:" |
|||
#~ msgstr "Enddatum" |
@ -0,0 +1,3 @@ |
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|||
access_pos_top_sellers_product_report,Access to pos.top.sellers.product.report,model_pos_top_sellers_product_report,point_of_sale.group_pos_manager,1,0,0,0 |
|||
access_pos_top_sellers_shop_report,Access to pos.top.sellers.shop.report,model_pos_top_sellers_shop_report,point_of_sale.group_pos_manager,1,0,0,0 |
@ -0,0 +1,291 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# Copyright (C) 2010-2013 OpenERP s.a. (<http://openerp.com>). |
|||
# Copyright (C) 2015 initOS GmbH & Co. KG (<http://www.initos.com>). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp.osv import orm, fields |
|||
from openerp.tools.translate import _ |
|||
from datetime import datetime, timedelta |
|||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT |
|||
from lxml import etree |
|||
|
|||
|
|||
class pos_top_sellers_product_report(orm.Model): |
|||
_name = 'pos.top.sellers.product.report' |
|||
|
|||
# Create no table. Everything is created dynamically in this model |
|||
_auto = False |
|||
|
|||
_columns = dict(date = fields.char(string='', readonly=True)) |
|||
|
|||
def get_product_code_for_id(self, cr, uid, id, context=None): |
|||
prod = self.pool['product.product'].browse(cr, uid, id, context) |
|||
return prod.default_code |
|||
|
|||
def get_product_id_for_code(self, cr, uid, default_code, context=None): |
|||
ids = self.pool['product.product'].search(cr, uid, [('default_code','=', default_code)], context) |
|||
return ids[0] if ids else 0 |
|||
|
|||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False): |
|||
res = super(pos_top_sellers_product_report, self).\ |
|||
fields_view_get(cr, uid, view_id=view_id, view_type=view_type, |
|||
context=context, toolbar=toolbar) |
|||
|
|||
if view_type == 'tree': |
|||
shop_model = self.pool['sale.shop'] |
|||
shop_ids = shop_model.search(cr, uid, []) |
|||
arch = etree.XML(res['arch']) |
|||
tree = arch.xpath("//tree") |
|||
for shop in shop_model.browse(cr, uid, shop_ids): |
|||
# create fields for shop |
|||
qty_key = 'qty_' + str(shop.id) |
|||
res['fields'].update({ |
|||
qty_key: dict( |
|||
string=shop.name, |
|||
type='integer', |
|||
readonly='True' |
|||
) |
|||
}) |
|||
|
|||
# add field to tree |
|||
etree.SubElement(tree[0], 'field', dict( |
|||
name=qty_key |
|||
)) |
|||
res['arch'] = etree.tostring(arch) |
|||
return res |
|||
|
|||
def _get_context_date_range(self, cr, uid, context=None): |
|||
""" |
|||
Check date range from context and create date range for the past |
|||
30 days if date range is missing in context. |
|||
""" |
|||
date_from = context and context.get('list_date_range_bar_start') |
|||
date_to = context and context.get('list_date_range_bar_end') |
|||
if not date_to: |
|||
date_to = fields.date.context_today(self, cr, uid, context=context) |
|||
|
|||
if not date_from: |
|||
timestamp = datetime.strptime(date_to, DEFAULT_SERVER_DATE_FORMAT) |
|||
timestamp -= timedelta(days=30) |
|||
date_from = fields.date.context_today(self, cr, uid, context=context, timestamp=timestamp) |
|||
|
|||
return (date_from, date_to) |
|||
|
|||
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): |
|||
product_id = context and context.get('my_res_id') |
|||
date_from, date_to = self._get_context_date_range(cr, user, context=context) |
|||
res = [] |
|||
|
|||
if product_id and date_from and date_to: |
|||
d0 = datetime.strptime(date_from, DEFAULT_SERVER_DATE_FORMAT) |
|||
d1 = datetime.strptime(date_to, DEFAULT_SERVER_DATE_FORMAT) |
|||
|
|||
# range depends on number of days in date range |
|||
num_days = abs((d1 - d0).days)+1 |
|||
res = range(1, 1+2+num_days) |
|||
|
|||
return res |
|||
|
|||
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): |
|||
# create empty result lines |
|||
res = [dict(id=id) for id in ids] |
|||
product_id = context and context.get('my_res_id') |
|||
date_from, date_to = self._get_context_date_range(cr, user, context=context) |
|||
|
|||
if not (product_id and date_from and date_to): |
|||
return res |
|||
|
|||
# first two lines are summary of sales and stock |
|||
res[0].update(date=_('Sold')) |
|||
res[1].update(date=_('Currently in stock')) |
|||
|
|||
# remaining lines are sales top statistics per date |
|||
for shop_id in self.pool['sale.shop'].search(cr, user, [], context=context): |
|||
sql=''' |
|||
select |
|||
date_trunc('day', dd)::date as date |
|||
,COALESCE(pd.qty, 0) as qty |
|||
from generate_series |
|||
( %(date_from)s |
|||
, %(date_to)s |
|||
, '1 day'::interval) as dd |
|||
left join ( |
|||
select |
|||
po.date_order::date as date |
|||
,sum(pol.qty) as qty |
|||
from pos_order_line pol |
|||
join pos_order po |
|||
on po.id = pol.order_id |
|||
join product_product pp |
|||
on pp.id = product_id |
|||
join product_template pt |
|||
on pp.product_tmpl_id = pt.id |
|||
where pt.list_price > 0 and |
|||
shop_id = %(shop_id)s and product_id = %(product_id)s |
|||
group by |
|||
po.date_order::date |
|||
) as pd |
|||
on pd.date = dd.date |
|||
order by |
|||
date desc |
|||
''' |
|||
cr.execute(sql, dict(shop_id=shop_id, product_id=product_id, |
|||
date_from=date_from, date_to=date_to)) |
|||
query_result = cr.fetchall() |
|||
|
|||
qty_key = 'qty_' + str(shop_id) |
|||
|
|||
line_id=2 |
|||
for date, qty in query_result: |
|||
res[line_id].update({ |
|||
'date': date, |
|||
qty_key: qty |
|||
}) |
|||
total_qty = res[0].get(qty_key, 0) + qty |
|||
res[0].update({qty_key: total_qty}) |
|||
line_id += 1 |
|||
|
|||
ctx = dict(context or {}) |
|||
ctx.update({'shop': shop_id, |
|||
'states': ('done',), |
|||
'what': ('in', 'out')}) |
|||
product = self.pool['product.product'].browse(cr, user, product_id, context=ctx) |
|||
res[1].update({qty_key: product.qty_available}) |
|||
|
|||
|
|||
# postprocess |
|||
for line in res[2:]: |
|||
# transform date format |
|||
# fixme: note this uses the server locale not the user language set in odoo |
|||
# to really do this right we need to format this in JS on the client side |
|||
date = datetime.strptime(line['date'], '%Y-%m-%d') |
|||
line['date'] = date.strftime('%A, %x') |
|||
|
|||
return res |
|||
|
|||
class pos_top_sellers_shop_report(orm.Model): |
|||
_name = 'pos.top.sellers.shop.report' |
|||
|
|||
# We do not have columns. Everything is created dynamically in this model |
|||
_auto = False |
|||
|
|||
# by default list the top 40 products |
|||
_top_ten_limit = 40 |
|||
|
|||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False): |
|||
res = super(pos_top_sellers_shop_report, self).\ |
|||
fields_view_get(cr, uid, view_id=view_id, view_type=view_type, |
|||
context=context, toolbar=toolbar) |
|||
|
|||
if view_type == 'tree': |
|||
shop_model = self.pool['sale.shop'] |
|||
shop_ids = shop_model.search(cr, uid, []) |
|||
arch = etree.XML(res['arch']) |
|||
tree = arch.xpath("//tree") |
|||
for shop in shop_model.browse(cr, uid, shop_ids): |
|||
# create fields for shop |
|||
product_key = 'product_id_' + str(shop.id) |
|||
qty_key = 'qty_' + str(shop.id) |
|||
res['fields'].update({ |
|||
product_key: dict( |
|||
string=shop.name, |
|||
type='many2one', |
|||
relation='product.product', |
|||
readonly='True', |
|||
), |
|||
qty_key: dict( |
|||
string=_('QT'), |
|||
type='integer', |
|||
readonly='True' |
|||
) |
|||
}) |
|||
|
|||
# add field to tree |
|||
etree.SubElement(tree[0], 'field', dict( |
|||
name=product_key, |
|||
widget="pos_top_sellers_product_col", |
|||
)) |
|||
etree.SubElement(tree[0], 'field', dict( |
|||
name=qty_key |
|||
)) |
|||
|
|||
res['arch'] = etree.tostring(arch) |
|||
return res |
|||
|
|||
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): |
|||
# ignore sorting, limit etc |
|||
return range(1,1+self._top_ten_limit) |
|||
|
|||
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): |
|||
|
|||
date_from = context and context.get('list_date_range_bar_start') |
|||
date_to = context and context.get('list_date_range_bar_end') |
|||
|
|||
# create empty result lines |
|||
res = [dict(id=id) for id in ids] |
|||
limit = len(res) |
|||
|
|||
for shop_id in self.pool['sale.shop'].search(cr, user, [], context=context): |
|||
sql=''' |
|||
select |
|||
product_id |
|||
,COALESCE(default_code, pt.name) |
|||
,sum(pol.qty) as qty |
|||
from pos_order_line pol |
|||
join pos_order po |
|||
on po.id = pol.order_id |
|||
join product_product pp |
|||
on pp.id = product_id |
|||
join product_template pt |
|||
on pp.product_tmpl_id = pt.id |
|||
where pt.list_price > 0 and |
|||
shop_id = %(shop_id)s |
|||
''' |
|||
|
|||
if date_from: |
|||
sql += '''and po.date_order::date >= %(date_from)s ''' |
|||
|
|||
if date_to: |
|||
sql += '''and po.date_order::date <= %(date_to)s ''' |
|||
|
|||
sql += \ |
|||
''' |
|||
group by |
|||
product_id |
|||
,COALESCE(default_code, pt.name) |
|||
order by |
|||
qty desc |
|||
fetch first %(limit)s rows only |
|||
''' |
|||
cr.execute(sql, dict(shop_id=shop_id, limit=limit, |
|||
date_from=date_from, date_to=date_to)) |
|||
|
|||
product_key = 'product_id_' + str(shop_id) |
|||
qty_key = 'qty_' + str(shop_id) |
|||
|
|||
line_id=0 |
|||
for product_id, default_code, qty in cr.fetchall(): |
|||
res[line_id].update({ |
|||
product_key: (product_id, default_code), |
|||
qty_key: qty |
|||
}) |
|||
line_id += 1 |
|||
|
|||
return res |
@ -0,0 +1,83 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# Copyright (C) 2010-2013 OpenERP s.a. (<http://openerp.com>). |
|||
# Copyright (C) 2015 initOS GmbH & Co. KG (<http://www.initos.com>). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# 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 Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
--> |
|||
|
|||
<openerp> |
|||
<data> |
|||
|
|||
<record id="view_pos_top_sellers_shop_report" model="ir.ui.view"> |
|||
<field name="name">pos.top.sellers.shop.report</field> |
|||
<field name="model">pos.top.sellers.shop.report</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Best sellers by shop" create='false'/> |
|||
<!-- |
|||
Content is created dynamically in fields_view_get() |
|||
Do not add fields here! |
|||
Do not inherit this view! |
|||
--> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_pos_top_sellers_shop_report" model="ir.actions.act_window"> |
|||
<field name="name">Best sellers by shop</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">pos.top.sellers.shop.report</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">pos_top_sellers_shop_view</field> |
|||
<field name="target">current</field> |
|||
</record> |
|||
|
|||
<record id="view_pos_top_sellers_product_report" model="ir.ui.view"> |
|||
<field name="name">pos.top.sellers.product.report</field> |
|||
<field name="model">pos.top.sellers.product.report</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Recent sales by product/shop" create='false'> |
|||
<field name="date"/> |
|||
</tree> |
|||
<!-- |
|||
Content is created dynamically in fields_view_get() |
|||
Do not add fields here! |
|||
Do not inherit this view! |
|||
--> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_pos_top_sellers_product_report" model="ir.actions.act_window"> |
|||
<field name="name">Recent sales by product/shop</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">pos.top.sellers.product.report</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">pos_top_sellers_product_view</field> |
|||
<field name="target">current</field> |
|||
</record> |
|||
|
|||
<menuitem name="Best sellers by shop" id="menu_pos_top_sellers_shop_report" |
|||
parent="point_of_sale.menu_point_rep" action="action_pos_top_sellers_shop_report" |
|||
sequence="40"/> |
|||
|
|||
<menuitem name="Recent sales by product/shop" id="menu_pos_top_sellers_product_report" |
|||
parent="point_of_sale.menu_point_rep" action="action_pos_top_sellers_product_report" |
|||
sequence="41"/> |
|||
|
|||
</data> |
|||
</openerp> |
@ -0,0 +1,4 @@ |
|||
.oe_pos_top_sellers_product_id{ |
|||
margin-right: 1em; |
|||
} |
|||
|
@ -0,0 +1,143 @@ |
|||
openerp.pos_top_sellers = function(instance) |
|||
{ |
|||
var _t = instance.web._t, |
|||
_lt = instance.web._lt; |
|||
var QWeb = instance.web.qweb; |
|||
|
|||
instance.web.list.columns.add( |
|||
'field.pos_top_sellers_product_col', |
|||
'instance.web.pos_top_sellers.PosTopSellersListClickableColumn'); |
|||
|
|||
instance.web.views.add( |
|||
'pos_top_sellers_shop_view', |
|||
'instance.web.pos_top_sellers.PosTopSellersShopListView' |
|||
); |
|||
|
|||
instance.web.views.add( |
|||
'pos_top_sellers_product_view', |
|||
'instance.web.pos_top_sellers.PosTopSellersProductListView' |
|||
); |
|||
|
|||
instance.web.pos_top_sellers = instance.web.pos_top_sellers || {}; |
|||
|
|||
instance.web.pos_top_sellers.PosTopSellersListClickableColumn = |
|||
instance.web.list.Column.extend({ |
|||
_format: function (row_data, options) |
|||
{ |
|||
var prod_id = row_data[this.id].value[0]; |
|||
var prod_name = _.escape(row_data[this.id].value[1] || options.value_if_empty); |
|||
|
|||
return _.str.sprintf('<a class="oe_form_uri" data-pos-t10-click-id="%s" >%s</a>', |
|||
prod_id, prod_name); |
|||
|
|||
}, |
|||
}); |
|||
|
|||
instance.web.ListView.List.include({ |
|||
render: function() |
|||
{ |
|||
var result = this._super(this, arguments), |
|||
self = this; |
|||
|
|||
this.$current.delegate('a[data-pos-t10-click-id]', |
|||
'click', function() |
|||
{ |
|||
// forward context from parent view
|
|||
var ctx = self.dataset.get_context().eval(); |
|||
$.extend(ctx, { |
|||
my_res_id: jQuery(this).data('pos-t10-click-id'), |
|||
}); |
|||
|
|||
self.view.do_action({ |
|||
type: 'ir.actions.act_window', |
|||
res_model: 'pos.top.sellers.product.report', |
|||
view_type: 'form', |
|||
view_mode: 'tree', |
|||
views: [[false, 'pos_top_sellers_product_view']], |
|||
}, |
|||
{ |
|||
additional_context: ctx |
|||
} |
|||
); |
|||
}); |
|||
|
|||
return result; |
|||
}, |
|||
}); |
|||
|
|||
instance.web.pos_top_sellers.PosTopSellersShopListView = |
|||
instance.web.web_listview_date_range_bar.DateRangeBar.extend({ |
|||
|
|||
init: function(parent, dataset, view_id, _options) { |
|||
_options.selectable = false |
|||
_options.sortable = false |
|||
_options.reorderable = false |
|||
_options.search_view = false |
|||
this._super.apply(this, arguments); |
|||
}, |
|||
}); |
|||
|
|||
instance.web.pos_top_sellers.PosTopSellersProductListView = |
|||
instance.web.pos_top_sellers.PosTopSellersShopListView.extend({ |
|||
|
|||
init: function(parent, dataset, view_id, options) { |
|||
this._super.apply(this, arguments); |
|||
}, |
|||
|
|||
start:function(){ |
|||
var tmp = this._super.apply(this, arguments); |
|||
var self = this; |
|||
var defs = []; |
|||
|
|||
this.$el.parent().find('.oe_list_date_range_bar_start'). |
|||
prepend(QWeb.render("pos_top_sellers_product_view_product_selector", {widget: this})); |
|||
|
|||
this.$el.parent().find('.oe_pos_top_sellers_product_id_input').change(function() { |
|||
var product_default_code = this.value === '' ? null : this.value; |
|||
if( product_default_code ){ |
|||
req = self.dataset.call('get_product_id_for_code', [product_default_code]); |
|||
req.then( |
|||
function(product_id){ |
|||
if(product_id) |
|||
{ |
|||
self.ViewManager.$el.find("span.oe_breadcrumb_item").text(product_default_code); |
|||
self.last_context["my_res_id"] = product_id; |
|||
self.do_search(self.last_domain, self.last_context, self.last_group_by); |
|||
} |
|||
} |
|||
); |
|||
} |
|||
}); |
|||
|
|||
var ctx = this.dataset.get_context().eval(); |
|||
if ( ctx.my_res_id ) |
|||
{ |
|||
req = self.dataset.call('get_product_code_for_id', [ctx.my_res_id]) |
|||
req.then( |
|||
function(product_default_code){ |
|||
self.$el.parent().find('.oe_pos_top_sellers_product_id_input').val( product_default_code ); |
|||
self.ViewManager.$el.find("span.oe_breadcrumb_item").text(product_default_code); |
|||
} |
|||
); |
|||
defs.push(req); |
|||
} |
|||
|
|||
return $.when(tmp, defs); |
|||
}, |
|||
|
|||
style_for: function (record) { |
|||
var self = this; |
|||
var tmp = self._super.apply(this, arguments); |
|||
var id = record.attributes.id; |
|||
if( id == 1 ) |
|||
{ |
|||
tmp += "color: #FF0000" |
|||
} |
|||
if( id == 2 ) |
|||
{ |
|||
tmp += "color: #FFCC00" |
|||
} |
|||
return tmp; |
|||
}, |
|||
}); |
|||
}; |
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
|
|||
<templates id="template" xml:space="preserve"> |
|||
|
|||
<t t-name="pos_top_sellers_product_view_product_selector"> |
|||
<div class="oe_form_dropdown_section oe_pos_top_sellers_product_id"> |
|||
<span style="font-weight:bold;">Product code:</span> |
|||
<input class="oe_pos_top_sellers_product_id_input" size="30"/> |
|||
</div> |
|||
</t> |
|||
|
|||
</templates> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue