[REF] website_sale_slides: improve integration into eLeaning application
PURPOSE
eLearning should have its own application in manager. Indeed this is becoming
a big application and having it embedded inside Website application is not
enough anymore. It should also hold updated and easy-to-use menus,
navigation, actions and views in backend.
SPECIFICATIONS
Improve course form view: add a revenue stat button displaying the total
of sale order linked to the course's product.
Add in slide.channel kanban card
* Add "Sales 150.00$" below "Watch Time" if type "on payment". Same
info than the smart/stat button on the course itself. Click on the amount
sends to Reporting Revenues (same than on the stat btn)
Add menu entry inside Reporting
* Revenues: graph view on sale.report model showing revenues of eLearning
courses.
Area chart, X: month Y: €, Color: course
LINKS
Task 1978729
PR #35061
Co-Authored-By: Thibault Delavallée <tde@odoo.com>
Co-Authored-By: Jérémy Hennecart <jeh@odoo.com>
This commit is contained in:
committed by
Thibault Delavallée
co-authored by
Thibault Delavallée
parent
2e707935f1
commit
ee10b19f67
@@ -10,7 +10,9 @@
|
||||
'depends': ['website_slides', 'website_sale'],
|
||||
'installable': True,
|
||||
'data': [
|
||||
'report/sale_report_views.xml',
|
||||
'views/assets.xml',
|
||||
'views/website_slides_menu_views.xml',
|
||||
'views/slide_channel_views.xml',
|
||||
'views/website_slides_templates.xml',
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import product_product
|
||||
from . import slide_channel
|
||||
from . import sale_order
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class Product(models.Model):
|
||||
_inherit = "product.product"
|
||||
|
||||
channel_ids = fields.One2many('slide.channel', 'product_id', string='Courses')
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class Channel(models.Model):
|
||||
@@ -9,11 +9,32 @@ class Channel(models.Model):
|
||||
|
||||
enroll = fields.Selection(selection_add=[('payment', 'On payment')])
|
||||
product_id = fields.Many2one('product.product', 'Product', index=True)
|
||||
product_sale_revenues = fields.Float(
|
||||
string='Total revenues', compute='_compute_product_sale_revenues',
|
||||
groups="sales_team.group_sale_salesman")
|
||||
|
||||
_sql_constraints = [
|
||||
('product_id_check', "CHECK( enroll!='payment' OR product_id IS NOT NULL )", "Product is required for on payment channels.")
|
||||
]
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_product_sale_revenues(self):
|
||||
domain = [
|
||||
('state', 'in', self.env['sale.report']._get_done_states()),
|
||||
('product_id', 'in', self.product_id.ids),
|
||||
]
|
||||
rg_data = dict(
|
||||
(item['product_id'][0], item['price_total'])
|
||||
for item in self.env['sale.report'].read_group(domain, ['product_id', 'price_total'], ['product_id'])
|
||||
)
|
||||
for channel in self:
|
||||
channel.product_sale_revenues = rg_data.get(channel.product_id.id, 0)
|
||||
|
||||
def action_view_sales(self):
|
||||
action = self.env.ref('website_sale_slides.sale_report_action_slides').read()[0]
|
||||
action['domain'] = [('product_id', 'in', self.product_id.ids)]
|
||||
return action
|
||||
|
||||
def _filter_add_members(self, target_partners, **member_values):
|
||||
""" Overridden to add 'payment' channels to the filtered channels. People
|
||||
that can write on payment-based channels can add members. """
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="sale_report_view_graph_slides" model="ir.ui.view">
|
||||
<field name="name">sale.report.view.graph.slides</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="eLearning Sales Analysis" type="line">
|
||||
<field name="confirmation_date" type="row" interval="day"/>
|
||||
<field name="price_subtotal" type="measure"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_slides" model="ir.actions.act_window">
|
||||
<field name="name">eLearning Revenues</field>
|
||||
<field name="res_model">sale.report</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_mode">graph,pivot</field>
|
||||
<field name="domain">[("product_id.channel_ids", "!=", False)]</field>
|
||||
<field name="context">{'group_by': ['confirmation_date', 'product_id']}</field>
|
||||
<field name="view_id" ref="sale_report_view_graph_slides"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,16 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="slide_channel_view_form" model="ir.ui.view">
|
||||
<field name="name">slide.channel.view.form.inherit.sale</field>
|
||||
<field name="model">slide.channel</field>
|
||||
<field name="inherit_id" ref="website_slides.view_slide_channel_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='enroll']" position="after">
|
||||
<field name="product_id"
|
||||
attrs="{'invisible': [('enroll', '!=', 'payment')], 'required': [('enroll', '=', 'payment')]}" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
<odoo><data>
|
||||
<record id="slide_channel_view_form" model="ir.ui.view">
|
||||
<field name="name">slide.channel.view.form.inherit.sale</field>
|
||||
<field name="model">slide.channel</field>
|
||||
<field name="inherit_id" ref="website_slides.view_slide_channel_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='enroll']" position="after">
|
||||
<field name="product_id"
|
||||
attrs="{'invisible': [('enroll', '!=', 'payment')], 'required': [('enroll', '=', 'payment')]}" />
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='action_redirect_to_members']" position="after">
|
||||
<button name="action_view_sales"
|
||||
type="object"
|
||||
icon="fa-signal"
|
||||
class="oe_stat_button"
|
||||
groups="sales_team.group_sale_salesman">
|
||||
<field name="product_sale_revenues" string="Sales" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="slide_channel_view_kanban" model="ir.ui.view">
|
||||
<field name="name">slide.channel.view.kanban.inherit.sale</field>
|
||||
<field name="model">slide.channel</field>
|
||||
<field name="inherit_id" ref="website_slides.slide_channel_view_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='website_published']" position="before">
|
||||
<field name="enroll"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='info_total_time']" position="after">
|
||||
<div class="d-flex" attrs="{'invisible': [('enroll', '!=', 'payment')]}">
|
||||
<span class="mr-auto"><label for="product_sale_revenues" class="mb0">Sales</label></span>
|
||||
<field name="product_sale_revenues"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//a[@name='action_channel_invite']" position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('enroll', '=', 'payment')]}</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data></odoo>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<menuitem name="Revenues"
|
||||
id="website_slides_menu_report_revenues"
|
||||
parent="website_slides.website_slides_menu_report"
|
||||
sequence="3"
|
||||
action="sale_report_action_slides"/>
|
||||
</odoo>
|
||||
@@ -276,7 +276,7 @@
|
||||
<span class="mr-auto"><label for="total_views" class="mb0">Views</label></span>
|
||||
<field name="total_views"/>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<div class="d-flex" name="info_total_time">
|
||||
<span class="mr-auto"><label for="total_time" class="mb0">Watch Time</label></span>
|
||||
<field name="total_time" widget="float_time"/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user