add spreadsheet_dashboard_pos_cooperative & pos_dashboard_cooperative
This commit is contained in:
parent
86101218e9
commit
5247938b86
34 changed files with 7974 additions and 0 deletions
104
pos_dashboard_cooperative/views/dashboard_tiles.xml
Normal file
104
pos_dashboard_cooperative/views/dashboard_tiles.xml
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2026 Criptomart - License AGPL-3 -->
|
||||
<odoo noupdate="1">
|
||||
|
||||
<!--
|
||||
Tile categories shown in the dashboard.
|
||||
Two categories: a "members" one (members only) and a generic one
|
||||
for global sales KPIs.
|
||||
-->
|
||||
<record id="tile_category_cooperative" model="tile.category">
|
||||
<field name="name">Cooperative POS</field>
|
||||
<field name="sequence">100</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Tile: Total sales (excluding refunds).
|
||||
Sums price_total over the last 30 days. Uses paid/done/invoiced
|
||||
states to exclude drafts and cancellations.
|
||||
|
||||
NOTE on accuracy: tile.tile counts/aggregates records of the
|
||||
target model. report.pos.order is at line granularity, so:
|
||||
- SUM(price_total) is correctly the total amount sold.
|
||||
- COUNT() would count *lines*, not tickets. To count tickets we
|
||||
would need DISTINCT order_id which tile.tile does not support.
|
||||
Use the pivot views for ticket-accurate metrics; tiles are
|
||||
intentionally limited to monetary KPIs that aggregate by simple
|
||||
SUM over lines.
|
||||
-->
|
||||
<record id="tile_pos_sales_last_30_days" model="tile.tile">
|
||||
<field name="name">Sales last 30 days (€)</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="category_id" ref="tile_category_cooperative"/>
|
||||
<field name="model_id" ref="point_of_sale.model_report_pos_order"/>
|
||||
<field name="action_id" ref="action_pos_dashboard_overview"/>
|
||||
<field name="primary_function">sum</field>
|
||||
<field name="primary_field_id"
|
||||
ref="point_of_sale.field_report_pos_order__price_total"/>
|
||||
<field name="primary_format">{:,.2f} €</field>
|
||||
<field
|
||||
name="domain"
|
||||
>[('state', 'in', ['paid', 'done', 'invoiced']),
|
||||
('date', '>=', (context_today - relativedelta(days=30)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="background_color">#2E7D32</field>
|
||||
<field name="font_color">#FFFFFF</field>
|
||||
</record>
|
||||
|
||||
<record id="tile_pos_margin_last_30_days" model="tile.tile">
|
||||
<field name="name">Margin last 30 days (€)</field>
|
||||
<field name="sequence">20</field>
|
||||
<field name="category_id" ref="tile_category_cooperative"/>
|
||||
<field name="model_id" ref="point_of_sale.model_report_pos_order"/>
|
||||
<field name="action_id" ref="action_pos_dashboard_overview"/>
|
||||
<field name="primary_function">sum</field>
|
||||
<field name="primary_field_id"
|
||||
ref="point_of_sale.field_report_pos_order__margin"/>
|
||||
<field name="primary_format">{:,.2f} €</field>
|
||||
<field
|
||||
name="domain"
|
||||
>[('state', 'in', ['paid', 'done', 'invoiced']),
|
||||
('date', '>=', (context_today - relativedelta(days=30)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="background_color">#1565C0</field>
|
||||
<field name="font_color">#FFFFFF</field>
|
||||
</record>
|
||||
|
||||
<record id="tile_pos_sales_members_last_30_days" model="tile.tile">
|
||||
<field name="name">Members sales last 30 days (€)</field>
|
||||
<field name="sequence">30</field>
|
||||
<field name="category_id" ref="tile_category_cooperative"/>
|
||||
<field name="model_id" ref="point_of_sale.model_report_pos_order"/>
|
||||
<field name="action_id" ref="action_pos_dashboard_members"/>
|
||||
<field name="primary_function">sum</field>
|
||||
<field name="primary_field_id"
|
||||
ref="point_of_sale.field_report_pos_order__price_total"/>
|
||||
<field name="primary_format">{:,.2f} €</field>
|
||||
<field
|
||||
name="domain"
|
||||
>[('state', 'in', ['paid', 'done', 'invoiced']),
|
||||
('is_member_at_date', '=', True),
|
||||
('date', '>=', (context_today - relativedelta(days=30)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="background_color">#EF6C00</field>
|
||||
<field name="font_color">#FFFFFF</field>
|
||||
</record>
|
||||
|
||||
<record id="tile_pos_sales_non_members_last_30_days" model="tile.tile">
|
||||
<field name="name">Non-members sales last 30 days (€)</field>
|
||||
<field name="sequence">40</field>
|
||||
<field name="category_id" ref="tile_category_cooperative"/>
|
||||
<field name="model_id" ref="point_of_sale.model_report_pos_order"/>
|
||||
<field name="action_id" ref="action_pos_dashboard_members"/>
|
||||
<field name="primary_function">sum</field>
|
||||
<field name="primary_field_id"
|
||||
ref="point_of_sale.field_report_pos_order__price_total"/>
|
||||
<field name="primary_format">{:,.2f} €</field>
|
||||
<field
|
||||
name="domain"
|
||||
>[('state', 'in', ['paid', 'done', 'invoiced']),
|
||||
('is_member_at_date', '=', False),
|
||||
('date', '>=', (context_today - relativedelta(days=30)).strftime('%Y-%m-%d'))]</field>
|
||||
<field name="background_color">#6A1B9A</field>
|
||||
<field name="font_color">#FFFFFF</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
68
pos_dashboard_cooperative/views/menus.xml
Normal file
68
pos_dashboard_cooperative/views/menus.xml
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2026 Criptomart - License AGPL-3 -->
|
||||
<odoo>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_cooperative"
|
||||
name="Cooperative Dashboards"
|
||||
parent="point_of_sale.menu_point_rep"
|
||||
sequence="50"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_overview"
|
||||
name="Overview"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_overview"
|
||||
sequence="10"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_members"
|
||||
name="Members vs Non-members"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_members"
|
||||
sequence="20"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_top_members"
|
||||
name="Top Members"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_top_members"
|
||||
sequence="30"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_categories"
|
||||
name="By Category"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_categories"
|
||||
sequence="40"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_top_products"
|
||||
name="Top Products"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_top_products"
|
||||
sequence="50"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_by_day"
|
||||
name="By Day of Week"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_by_day_of_week"
|
||||
sequence="60"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_pos_dashboard_by_hour"
|
||||
name="By Hour of Day"
|
||||
parent="menu_pos_dashboard_cooperative"
|
||||
action="action_pos_dashboard_by_hour"
|
||||
sequence="70"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2026 Criptomart - License AGPL-3 -->
|
||||
<odoo>
|
||||
|
||||
<!--
|
||||
Category analysis: sales broken down by family (root), subfamily
|
||||
(parent of leaf), and leaf category. Designed to answer the
|
||||
"category traction" and "top families" questions from the BI brief.
|
||||
-->
|
||||
<record id="action_pos_dashboard_categories" model="ir.actions.act_window">
|
||||
<field name="name">Sales by Category</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_mode">pivot,graph,tree</field>
|
||||
<field name="search_view_id"
|
||||
ref="point_of_sale.view_report_pos_order_search"/>
|
||||
<field name="context">{
|
||||
'search_default_group_categ_root': 1,
|
||||
'search_default_order_month': 1,
|
||||
'group_by_no_leaf': 1,
|
||||
}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No data yet!
|
||||
</p><p>
|
||||
Add Subfamily or Product group-bys to drill down. Useful
|
||||
to detect tractor categories.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_pos_dashboard_top_products" model="ir.actions.act_window">
|
||||
<field name="name">Top Products</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_mode">pivot,tree,graph</field>
|
||||
<field name="search_view_id"
|
||||
ref="point_of_sale.view_report_pos_order_search"/>
|
||||
<field name="context">{
|
||||
'group_by': ['product_id'],
|
||||
'group_by_no_leaf': 1,
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2026 Criptomart - License AGPL-3 -->
|
||||
<odoo>
|
||||
|
||||
<!--
|
||||
Members vs non-members comparison.
|
||||
Opens the analysis pre-grouped by member flag and by month, with
|
||||
sales / orders / margin as primary measures.
|
||||
-->
|
||||
<record id="action_pos_dashboard_members" model="ir.actions.act_window">
|
||||
<field name="name">Members vs Non-members</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_mode">pivot,graph,tree</field>
|
||||
<field name="search_view_id"
|
||||
ref="point_of_sale.view_report_pos_order_search"/>
|
||||
<field name="context">{
|
||||
'search_default_group_member': 1,
|
||||
'search_default_order_month': 1,
|
||||
'group_by_no_leaf': 1,
|
||||
}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No data yet!
|
||||
</p><p>
|
||||
This view contrasts cooperative members and non-members on
|
||||
the same axes (sales, ticket count, margin).
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
Detail per member: top buyers, per-partner KPIs.
|
||||
Filters to members only and groups by partner.
|
||||
-->
|
||||
<record id="action_pos_dashboard_top_members" model="ir.actions.act_window">
|
||||
<field name="name">Top Member Buyers</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_mode">pivot,tree,graph</field>
|
||||
<field name="search_view_id"
|
||||
ref="point_of_sale.view_report_pos_order_search"/>
|
||||
<field name="domain">[('is_member_at_date', '=', True)]</field>
|
||||
<field name="context">{
|
||||
'search_default_members': 1,
|
||||
'group_by': ['partner_id'],
|
||||
'group_by_no_leaf': 1,
|
||||
}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No data yet!
|
||||
</p><p>
|
||||
Sales aggregated per cooperative member. Sort by total
|
||||
price to obtain the top buyers.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2026 Criptomart - License AGPL-3 -->
|
||||
<odoo>
|
||||
|
||||
<!--
|
||||
Time-based analyses: distribution of sales across days of the week
|
||||
and hours of the day, to size shifts and detect peaks.
|
||||
-->
|
||||
<record id="action_pos_dashboard_by_day_of_week" model="ir.actions.act_window">
|
||||
<field name="name">Sales by Day of Week</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_mode">graph,pivot,tree</field>
|
||||
<field name="search_view_id"
|
||||
ref="point_of_sale.view_report_pos_order_search"/>
|
||||
<field name="context">{
|
||||
'search_default_group_day_of_week': 1,
|
||||
'group_by_no_leaf': 1,
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
<record id="action_pos_dashboard_by_hour" model="ir.actions.act_window">
|
||||
<field name="name">Sales by Hour of Day</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_mode">graph,pivot,tree</field>
|
||||
<field name="search_view_id"
|
||||
ref="point_of_sale.view_report_pos_order_search"/>
|
||||
<field name="context">{
|
||||
'search_default_group_hour_of_day': 1,
|
||||
'group_by_no_leaf': 1,
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue