Open reporting per product from reporting per product category

issue10489
review358211002
This commit is contained in:
Cédric Krier committed 2021-06-25 01:13:46 +02:00
1 parent b2397091db
commit 4de662e12e
9 files changed
+113 -100

No files matched your search

+3 -3
View File
@@ -39,9 +39,9 @@ def register():
sale_reporting.CustomerTimeseries,
sale_reporting.Product,
sale_reporting.ProductTimeseries,
sale_reporting.Category,
sale_reporting.CategoryTimeseries,
sale_reporting.CategoryTree,
sale_reporting.ProductCategory,
sale_reporting.ProductCategoryTimeseries,
sale_reporting.ProductCategoryTree,
sale_reporting.Country,
sale_reporting.CountryTimeseries,
sale_reporting.Subdivision,
+29 -26
View File
@@ -376,7 +376,7 @@ class ProductTimeseries(ProductMixin, AbstractTimeseries, ModelView):
__name__ = 'sale.reporting.product.time_series'
class CategoryMixin(object):
class ProductCategoryMixin(object):
__slots__ = ()
category = fields.Many2One(
'product.category', "Category",
@@ -390,7 +390,7 @@ class CategoryMixin(object):
pool = Pool()
Product = pool.get('product.product')
TemplateCategory = pool.get('product.template-product.category.all')
from_item, tables, withs = super(CategoryMixin, cls)._joins()
from_item, tables, withs = super()._joins()
if 'line.product' not in tables:
product = Product.__table__()
tables['line.product'] = product
@@ -409,7 +409,7 @@ class CategoryMixin(object):
@classmethod
def _columns(cls, tables, withs):
template_category = tables['line.product.template_category']
return super(CategoryMixin, cls)._columns(tables, withs) + [
return super()._columns(tables, withs) + [
template_category.category.as_('category')]
@classmethod
@@ -428,13 +428,12 @@ class CategoryMixin(object):
@classmethod
def _group_by(cls, tables, withs):
template_category = tables['line.product.template_category']
return super(CategoryMixin, cls)._group_by(tables, withs) + [
template_category.category]
return super()._group_by(tables, withs) + [template_category.category]
@classmethod
def _where(cls, tables, withs):
template_category = tables['line.product.template_category']
where = super(CategoryMixin, cls)._where(tables, withs)
where = super()._where(tables, withs)
where &= template_category.category != Null
return where
@@ -442,12 +441,13 @@ class CategoryMixin(object):
return self.category.rec_name if self.category else None
class Category(CategoryMixin, Abstract, ModelView):
"Sale Reporting per Category"
__name__ = 'sale.reporting.category'
class ProductCategory(ProductCategoryMixin, Abstract, ModelView):
"Sale Reporting per Product Category"
__name__ = 'sale.reporting.product.category'
time_series = fields.One2Many(
'sale.reporting.category.time_series', 'category', "Time Series")
'sale.reporting.product.category.time_series', 'category',
"Time Series")
@classmethod
def __setup__(cls):
@@ -460,19 +460,20 @@ class Category(CategoryMixin, Abstract, ModelView):
return template_category.category
class CategoryTimeseries(CategoryMixin, AbstractTimeseries, ModelView):
"Sale Reporting per Category"
__name__ = 'sale.reporting.category.time_series'
class ProductCategoryTimeseries(
ProductCategoryMixin, AbstractTimeseries, ModelView):
"Sale Reporting per Product Category"
__name__ = 'sale.reporting.product.category.time_series'
class CategoryTree(ModelSQL, ModelView):
"Sale Reporting per Category"
__name__ = 'sale.reporting.category.tree'
class ProductCategoryTree(ModelSQL, ModelView):
"Sale Reporting per Product Category"
__name__ = 'sale.reporting.product.category.tree'
name = fields.Function(fields.Char("Name"), 'get_name')
parent = fields.Many2One('sale.reporting.category.tree', "Parent")
parent = fields.Many2One('sale.reporting.product.category.tree', "Parent")
children = fields.One2Many(
'sale.reporting.category.tree', 'parent', "Children")
'sale.reporting.product.category.tree', 'parent', "Children")
revenue = fields.Function(
fields.Numeric("Revenue", digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits']), 'get_total')
@@ -517,9 +518,9 @@ class CategoryTree(ModelSQL, ModelView):
@classmethod
def get_total(cls, categories, names):
pool = Pool()
ReportingCategory = pool.get('sale.reporting.category')
ReportingProductCategory = pool.get('sale.reporting.product.category')
table = cls.__table__()
reporting_category = ReportingCategory.__table__()
reporting_product_category = ReportingProductCategory.__table__()
cursor = Transaction().connection.cursor()
categories = cls.search([
@@ -527,24 +528,26 @@ class CategoryTree(ModelSQL, ModelView):
])
ids = [c.id for c in categories]
parents = {}
reporting_categories = []
reporting_product_categories = []
for sub_ids in grouped_slice(ids):
sub_ids = list(sub_ids)
where = reduce_ids(table.id, sub_ids)
cursor.execute(*table.select(table.id, table.parent, where=where))
parents.update(cursor)
where = reduce_ids(reporting_category.id, sub_ids)
where = reduce_ids(reporting_product_category.id, sub_ids)
cursor.execute(
*reporting_category.select(reporting_category.id, where=where))
reporting_categories.extend(r for r, in cursor)
*reporting_product_category.select(
reporting_product_category.id, where=where))
reporting_product_categories.extend(r for r, in cursor)
result = {}
reporting_categories = ReportingCategory.browse(reporting_categories)
reporting_product_categories = ReportingProductCategory.browse(
reporting_product_categories)
for name in names:
values = dict.fromkeys(ids, 0)
values.update(
(c.id, getattr(c, name)) for c in reporting_categories)
(c.id, getattr(c, name)) for c in reporting_product_categories)
result[name] = cls._sum_tree(categories, values, parents)
return result
+73 -64
View File
@@ -197,6 +197,10 @@ this repository contains the full copyright notices and license terms. -->
<field name="name">Sales per Product</field>
<field name="res_model">sale.reporting.product</field>
<field name="context_model">sale.reporting.context</field>
<field
name="domain"
eval="If(Eval('active_model') == 'sale.reporting.product.category.tree', [('product', 'where', [('categories_all', 'child_of', Eval('active_ids', []), 'parent')])], [])"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_reporting_product_view1">
<field name="sequence" eval="10"/>
@@ -218,6 +222,11 @@ this repository contains the full copyright notices and license terms. -->
<field name="model" eval="'ir.ui.menu,%s' % ref('menu_reporting_sale')"/>
<field name="action" ref="act_reporting_product"/>
</record>
<record model="ir.action.keyword" id="act_reporting_product_keyword2">
<field name="keyword">tree_open</field>
<field name="model">sale.reporting.product.category.tree,-1</field>
<field name="action" ref="act_reporting_product"/>
</record>
<record model="ir.rule.group" id="rule_group_reporting_product_companies">
<field name="name">User in companies</field>
@@ -323,79 +332,79 @@ this repository contains the full copyright notices and license terms. -->
<field name="perm_delete" eval="False"/>
</record>
<!-- Category -->
<!-- Product Category -->
<record model="ir.ui.view" id="reporting_category_view_tree">
<field name="model">sale.reporting.category.tree</field>
<record model="ir.ui.view" id="reporting_product_category_view_tree">
<field name="model">sale.reporting.product.category.tree</field>
<field name="type">tree</field>
<field name="field_childs">children</field>
<field name="name">sale_reporting_category_tree</field>
<field name="name">sale_reporting_product_category_tree</field>
</record>
<record model="ir.action.act_window" id="act_reporting_category_tree">
<field name="name">Sales per Category</field>
<field name="res_model">sale.reporting.category.tree</field>
<record model="ir.action.act_window" id="act_reporting_product_category_tree">
<field name="name">Sales per Product Category</field>
<field name="res_model">sale.reporting.product.category.tree</field>
<field name="context_model">sale.reporting.context</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_reporting_category_tree_view1">
<record model="ir.action.act_window.view" id="act_reporting_product_category_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="reporting_category_view_tree"/>
<field name="act_window" ref="act_reporting_category_tree"/>
<field name="view" ref="reporting_product_category_view_tree"/>
<field name="act_window" ref="act_reporting_product_category_tree"/>
</record>
<record model="ir.action.keyword" id="act_reporting_category_tree_keyword1">
<record model="ir.action.keyword" id="act_reporting_product_category_tree_keyword1">
<field name="keyword">tree_open</field>
<field name="model" eval="'ir.ui.menu,%s' % ref('menu_reporting_sale')"/>
<field name="action" ref="act_reporting_category_tree"/>
<field name="action" ref="act_reporting_product_category_tree"/>
</record>
<record model="ir.ui.view" id="reporting_category_view_list">
<field name="model">sale.reporting.category</field>
<record model="ir.ui.view" id="reporting_product_category_view_list">
<field name="model">sale.reporting.product.category</field>
<field name="type">tree</field>
<field name="name">sale_reporting_category_list</field>
<field name="name">sale_reporting_product_category_list</field>
</record>
<record model="ir.action.act_window" id="act_reporting_category">
<field name="name">Sales per Category</field>
<field name="res_model">sale.reporting.category</field>
<record model="ir.action.act_window" id="act_reporting_product_category">
<field name="name">Sales per Product Category</field>
<field name="res_model">sale.reporting.product.category</field>
<field name="context_model">sale.reporting.context</field>
<field
name="domain"
eval="[('category', 'child_of', Eval('active_ids', []), 'parent')]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_reporting_category_view1">
<record model="ir.action.act_window.view" id="act_reporting_product_category_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="reporting_category_view_list"/>
<field name="act_window" ref="act_reporting_category"/>
<field name="view" ref="reporting_product_category_view_list"/>
<field name="act_window" ref="act_reporting_product_category"/>
</record>
<record model="ir.action.keyword" id="act_reporting_category_keyword1">
<record model="ir.action.keyword" id="act_reporting_product_category_keyword1">
<field name="keyword">tree_open</field>
<field name="model">sale.reporting.category.tree,-1</field>
<field name="action" ref="act_reporting_category"/>
<field name="model">sale.reporting.product.category.tree,-1</field>
<field name="action" ref="act_reporting_product_category"/>
</record>
<record model="ir.rule.group" id="rule_group_reporting_category_companies">
<record model="ir.rule.group" id="rule_group_reporting_product_category_companies">
<field name="name">User in companies</field>
<field name="model" search="[('model', '=', 'sale.reporting.category')]"/>
<field name="model" search="[('model', '=', 'sale.reporting.product.category')]"/>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_reporting_category_companies">
<record model="ir.rule" id="rule_reporting_product_category_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_reporting_category_companies"/>
<field name="rule_group" ref="rule_group_reporting_product_category_companies"/>
</record>
<record model="ir.model.access" id="access_reporting_category">
<field name="model" search="[('model', '=', 'sale.reporting.category')]"/>
<record model="ir.model.access" id="access_reporting_product_category">
<field name="model" search="[('model', '=', 'sale.reporting.product.category')]"/>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_reporting_category_sale">
<field name="model" search="[('model', '=', 'sale.reporting.category')]"/>
<record model="ir.model.access" id="access_reporting_product_category_sale">
<field name="model" search="[('model', '=', 'sale.reporting.product.category')]"/>
<field name="group" ref="group_sale"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
@@ -403,27 +412,27 @@ this repository contains the full copyright notices and license terms. -->
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.ui.view" id="reporting_category_time_series_view_list">
<field name="model">sale.reporting.category.time_series</field>
<record model="ir.ui.view" id="reporting_product_category_time_series_view_list">
<field name="model">sale.reporting.product.category.time_series</field>
<field name="type">tree</field>
<field name="name">sale_reporting_category_time_series_list</field>
<field name="name">sale_reporting_product_category_time_series_list</field>
</record>
<record model="ir.ui.view" id="reporting_category_time_series_view_graph_revenue">
<field name="model">sale.reporting.category.time_series</field>
<record model="ir.ui.view" id="reporting_product_category_time_series_view_graph_revenue">
<field name="model">sale.reporting.product.category.time_series</field>
<field name="type">graph</field>
<field name="name">sale_reporting_category_time_series_graph_revenue</field>
<field name="name">sale_reporting_product_category_time_series_graph_revenue</field>
</record>
<record model="ir.ui.view" id="reporting_category_time_series_view_graph_number">
<field name="model">sale.reporting.category.time_series</field>
<record model="ir.ui.view" id="reporting_product_category_time_series_view_graph_number">
<field name="model">sale.reporting.product.category.time_series</field>
<field name="type">graph</field>
<field name="name">sale_reporting_category_time_series_graph_number</field>
<field name="name">sale_reporting_product_category_time_series_graph_number</field>
</record>
<record model="ir.action.act_window" id="act_reporting_category_time_series">
<field name="name">Sales per Category</field>
<field name="res_model">sale.reporting.category.time_series</field>
<record model="ir.action.act_window" id="act_reporting_product_category_time_series">
<field name="name">Sales per Product Category</field>
<field name="res_model">sale.reporting.product.category.time_series</field>
<field name="context_model">sale.reporting.context</field>
<field
name="domain"
@@ -431,48 +440,48 @@ this repository contains the full copyright notices and license terms. -->
pyson="1"/>
<field name="order" eval="[('date', 'DESC')]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_reporting_category_time_series_list_view1">
<record model="ir.action.act_window.view" id="act_reporting_product_category_time_series_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="reporting_category_time_series_view_list"/>
<field name="act_window" ref="act_reporting_category_time_series"/>
<field name="view" ref="reporting_product_category_time_series_view_list"/>
<field name="act_window" ref="act_reporting_product_category_time_series"/>
</record>
<record model="ir.action.act_window.view" id="act_reporting_category_time_series_list_view2">
<record model="ir.action.act_window.view" id="act_reporting_product_category_time_series_list_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="reporting_category_time_series_view_graph_revenue"/>
<field name="act_window" ref="act_reporting_category_time_series"/>
<field name="view" ref="reporting_product_category_time_series_view_graph_revenue"/>
<field name="act_window" ref="act_reporting_product_category_time_series"/>
</record>
<record model="ir.action.act_window.view" id="act_reporting_category_time_series_list_view3">
<record model="ir.action.act_window.view" id="act_reporting_product_category_time_series_list_view3">
<field name="sequence" eval="30"/>
<field name="view" ref="reporting_category_time_series_view_graph_number"/>
<field name="act_window" ref="act_reporting_category_time_series"/>
<field name="view" ref="reporting_product_category_time_series_view_graph_number"/>
<field name="act_window" ref="act_reporting_product_category_time_series"/>
</record>
<record model="ir.action.keyword" id="act_reporting_category_time_series_list_keyword1">
<record model="ir.action.keyword" id="act_reporting_product_category_time_series_list_keyword1">
<field name="keyword">tree_open</field>
<field name="model">sale.reporting.category,-1</field>
<field name="action" ref="act_reporting_category_time_series"/>
<field name="model">sale.reporting.product.category,-1</field>
<field name="action" ref="act_reporting_product_category_time_series"/>
</record>
<record model="ir.rule.group" id="rule_group_reporting_category_time_series_companies">
<record model="ir.rule.group" id="rule_group_reporting_product_category_time_series_companies">
<field name="name">User in companies</field>
<field name="model" search="[('model', '=', 'sale.reporting.category.time_series')]"/>
<field name="model" search="[('model', '=', 'sale.reporting.product.category.time_series')]"/>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_reporting_category_time_series_companies">
<record model="ir.rule" id="rule_reporting_product_category_time_series_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_reporting_category_time_series_companies"/>
<field name="rule_group" ref="rule_group_reporting_product_category_time_series_companies"/>
</record>
<record model="ir.model.access" id="access_reporting_category_time_series">
<field name="model" search="[('model', '=', 'sale.reporting.category.time_series')]"/>
<record model="ir.model.access" id="access_reporting_product_category_time_series">
<field name="model" search="[('model', '=', 'sale.reporting.product.category.time_series')]"/>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_reporting_category_time_series_sale">
<field name="model" search="[('model', '=', 'sale.reporting.category.time_series')]"/>
<record model="ir.model.access" id="access_reporting_product_category_time_series_sale">
<field name="model" search="[('model', '=', 'sale.reporting.product.category.time_series')]"/>
<field name="group" ref="group_sale"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
+8 -7
View File
@@ -183,15 +183,16 @@ Check sale reporting per product::
... (product1.id, sale2.sale_date.replace(day=1), 1, Decimal('10'))])
True
Check sale reporting per categories::
Check sale reporting per product categories::
>>> Category = Model.get('sale.reporting.category')
>>> CategoryTimeseries = Model.get('sale.reporting.category.time_series')
>>> CategoryTree = Model.get('sale.reporting.category.tree')
>>> ProductCategory = Model.get('sale.reporting.product.category')
>>> ProductCategoryTimeseries = Model.get(
... 'sale.reporting.product.category.time_series')
>>> ProductCategoryTree = Model.get('sale.reporting.product.category.tree')
>>> with config.set_context(context=context):
... reports = Category.find([])
... time_series = CategoryTimeseries.find([])
... tree = CategoryTree.find([])
... reports = ProductCategory.find([])
... time_series = ProductCategoryTimeseries.find([])
... tree = ProductCategoryTree.find([])
>>> len(reports)
4
>>> with config.set_context(context=context):