[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:
committed by
Yannick Tivisse
parent
c9b74a047c
commit
bf9cbcc8d8
@@ -2,3 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
from . import report
|
||||
@@ -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())
|
||||
@@ -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',
|
||||
|
||||
@@ -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','>=',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>
|
||||
@@ -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,2 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
||||
|
||||
Reference in New Issue
Block a user