[IMP] pos_sale: Add analysis report about total sales from pos, eCommerce and sale

Purpose
=======

Create one report where we can see all sales (sales from sales, eCommerce, POS) grouped by channels

Specification
=============

New Report Sales > Reports , the name should be "All Channels Sales Orders"
This report contains the following fields :

   name
   date
   product_id
   partner_id
   company_id
   user_id
   price_total
   pricelist_id
   categ_id = product_categ_id
   invoiced = amount to invoice
   analytic_account_id
   team_name
   country_id

We thought about doing a kind of sale_order_common report, but we cannot re-use sale.report because of some field (qty_delivered, ...) that we cannot compute on pos orders.
This commit is contained in:
Akash Bhavsar
2017-07-11 15:31:04 +02:00
committed by Yannick Tivisse
parent c9b74a047c
commit bf9cbcc8d8
9 changed files with 186 additions and 0 deletions
+1
View File
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import report
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import report_all_channels_sales
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
class PosSaleReport(models.Model):
_inherit = "report.all.channels.sales"
def _pos(self):
pos_str = """
SELECT
(-1) * pol.id AS id,
pos.name AS name,
pos.partner_id AS partner_id,
pol.product_id AS product_id,
pro.product_tmpl_id AS product_tmpl_id,
pos.date_order AS date_order,
pos.user_id AS user_id,
pt.categ_id AS categ_id,
pos.company_id AS company_id,
((pol.qty * pol.price_unit) * (100 - pol.discount) / 100) AS price_total,
pos.pricelist_id AS pricelist_id,
rp.country_id AS country_id,
(pol.qty * pol.price_unit) AS price_subtotal,
(pol.qty * u.factor) AS product_qty,
NULL AS analytic_account_id,
config.crm_team_id AS team_id
FROM pos_order_line AS pol
JOIN pos_order pos ON (pos.id = pol.order_id)
LEFT JOIN pos_session session ON (session.id = pos.session_id)
LEFT JOIN pos_config config ON (config.id = session.config_id)
LEFT JOIN product_product pro ON (pol.product_id = pro.id)
LEFT JOIN product_template pt ON (pro.product_tmpl_id = pt.id)
LEFT JOIN product_category AS pc ON (pt.categ_id = pc.id)
LEFT JOIN res_company AS rc ON (pos.company_id = rc.id)
LEFT JOIN res_partner rp ON (rc.partner_id = rp.id)
LEFT JOIN product_uom u ON (u.id=pt.uom_id)
"""
return pos_str
def _from(self):
return """(%s UNION ALL %s)""" % (self._so(), self._pos())
+1
View File
@@ -18,6 +18,7 @@ This module contains all the common features of Sales Management and eCommerce.
'report/sale_report_views.xml',
'report/sale_report_templates.xml',
'report/invoice_report_templates.xml',
'report/report_all_channels_sales_views.xml',
'security/sale_security.xml',
'security/ir.model.access.csv',
'wizard/sale_make_invoice_advance_views.xml',
+1
View File
@@ -3,3 +3,4 @@
from . import sale_report
from . import invoice_report
from . import report_all_channels_sales
@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, tools
class PosSaleReport(models.Model):
_name = "report.all.channels.sales"
_description = "All sales orders grouped by sales channels"
_auto = False
name = fields.Char('Order Reference', readonly=True)
partner_id = fields.Many2one('res.partner', 'Partner', readonly=True)
product_id = fields.Many2one('product.product', string='Product', readonly=True)
product_tmpl_id = fields.Many2one('product.template', 'Product Template', readonly=True)
date_order = fields.Datetime(string='Date Order', readonly=True)
user_id = fields.Many2one('res.users', 'Salesperson', readonly=True)
categ_id = fields.Many2one('product.category', 'Product Category', readonly=True)
company_id = fields.Many2one('res.company', 'Company', readonly=True)
price_total = fields.Float('Total', readonly=True)
pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', readonly=True)
country_id = fields.Many2one('res.country', 'Partner Country', readonly=True)
price_subtotal = fields.Float(string='Price Subtotal', readonly=True)
product_qty = fields.Float('Product Quantity', readonly=True)
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True)
team_id = fields.Many2one('crm.team', 'Sales Channel', readonly=True)
def _so(self):
so_str = """
WITH currency_rate as (%s)
SELECT sol.id AS id,
so.name AS name,
so.partner_id AS partner_id,
sol.product_id AS product_id,
pro.product_tmpl_id AS product_tmpl_id,
so.date_order AS date_order,
so.user_id AS user_id,
pt.categ_id AS categ_id,
so.company_id AS company_id,
sol.price_total / COALESCE(cr.rate, 1.0) AS price_total,
so.pricelist_id AS pricelist_id,
rp.country_id AS country_id,
sol.price_subtotal / COALESCE (cr.rate, 1.0) AS price_subtotal,
(sol.product_uom_qty / u.factor * u2.factor) as product_qty,
so.project_id AS analytic_account_id,
so.team_id AS team_id
FROM sale_order_line sol
JOIN sale_order so ON (sol.order_id = so.id)
LEFT JOIN product_product pro ON (sol.product_id = pro.id)
JOIN res_partner rp ON (so.partner_id = rp.id)
LEFT JOIN product_template pt ON (pro.product_tmpl_id = pt.id)
LEFT JOIN product_pricelist pp ON (so.pricelist_id = pp.id)
LEFT JOIN currency_rate cr ON (cr.currency_id = pp.currency_id AND
cr.company_id = so.company_id AND
cr.date_start <= COALESCE(so.date_order, now()) AND
(cr.date_end IS NULL OR cr.date_end > COALESCE(so.date_order, now())))
LEFT JOIN product_uom u on (u.id=sol.product_uom)
LEFT JOIN product_uom u2 on (u2.id=pt.uom_id)
""" % self.env['res.currency']._select_companies_rates()
return so_str
def _from(self):
return """(%s)""" % (self._so())
def get_main_request(self):
request = """
CREATE or REPLACE VIEW %s AS
SELECT id AS id,
name,
partner_id,
product_id,
product_tmpl_id,
date_order,
user_id,
categ_id,
company_id,
price_total,
pricelist_id,
analytic_account_id,
country_id,
team_id,
price_subtotal,
product_qty
FROM %s
AS foo""" % (self._table, self._from())
return request
@api.model_cr
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute(self.get_main_request())
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="report_all_channels_sales_view_pivot" model="ir.ui.view">
<field name="name">report.all.channels.sales.pivot</field>
<field name="model">report.all.channels.sales</field>
<field name="arch" type="xml">
<pivot string="All Channels Sales Orders Analysis">
<field name="name" type="row"/>
<field name="price_total" string="Total Price" type="measure"/>
</pivot>
</field>
</record>
<record id="report_all_channels_sales_view_search" model="ir.ui.view">
<field name="name">report.all.channels.sales.search</field>
<field name="model">report.all.channels.sales</field>
<field name="arch" type="xml">
<search string="All Channels Sales Orders Analysis">
<field name="date_order"/>
<filter string="Current Year Sales" name="current_year" domain="[('date_order','&gt;=',time.strftime('%%Y-01-01'))]"/>
<group expand="1" string="Group By">
<filter string="Sales Channel" name="team_id" context="{'group_by':'team_id'}"/>
</group>
</search>
</field>
</record>
<record id="report_all_channels_sales_action" model="ir.actions.act_window">
<field name="name">All Channels Sales Orders</field>
<field name="res_model">report.all.channels.sales</field>
<field name="view_mode">pivot</field>
<field name="view_id" ref="report_all_channels_sales_view_pivot"/>
<field name="search_view_id" ref="report_all_channels_sales_view_search"/>
<field name="context">{'search_default_team_id': 1, 'search_default_current_year': 1}</field>
</record>
<menuitem action="report_all_channels_sales_action" id="report_all_channels_sales" name="All Channels Sales Orders" parent="sales_team.menu_sale_report"/>
</odoo>
+2
View File
@@ -51,3 +51,5 @@ access_account_journal_sale_manager,account.journal sale manager,account.model_a
access_account_invoice_tax_sale_manager,account.invoice.tax sale manager,account.model_account_invoice_tax,sales_team.group_sale_salesman,1,0,0,0
access_account_tax_group_sale_manager,account.tax.group sale manager,account.model_account_tax_group,sales_team.group_sale_salesman,1,0,0,0
access_account_account_sale_manager,account.account sale manager,account.model_account_account,sales_team.group_sale_manager,1,0,0,0
access_report_all_channels_sales_salesman,report.all.channels.sales,model_report_all_channels_sales,sales_team.group_sale_salesman,1,1,1,0
access_report_all_channels_sales_manager,report.all.channels.sales,model_report_all_channels_sales,sales_team.group_sale_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
51 access_account_invoice_tax_sale_manager account.invoice.tax sale manager account.model_account_invoice_tax sales_team.group_sale_salesman 1 0 0 0
52 access_account_tax_group_sale_manager account.tax.group sale manager account.model_account_tax_group sales_team.group_sale_salesman 1 0 0 0
53 access_account_account_sale_manager account.account sale manager account.model_account_account sales_team.group_sale_manager 1 0 0 0
54 access_report_all_channels_sales_salesman report.all.channels.sales model_report_all_channels_sales sales_team.group_sale_salesman 1 1 1 0
55 access_report_all_channels_sales_manager report.all.channels.sales model_report_all_channels_sales sales_team.group_sale_manager 1 1 1 1
+3
View File
@@ -1,2 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import controllers
from . import models