mirror of
https://github.com/SARL-PACIFIC-ERP/odoo-sh-test.git
synced 2025-06-25 17:42:22 +00:00
Compare commits
No commits in common. "7aa696f174d59e3c1eba94b6f0c896cf108461df" and "5ebc65e0966cc9f8699f670b6531c682ed73245a" have entirely different histories.
7aa696f174
...
5ebc65e096
|
@ -1,3 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import controllers
|
|
|
@ -1,34 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
{
|
|
||||||
'name': "Awesome Dashboard",
|
|
||||||
|
|
||||||
'summary': """
|
|
||||||
Starting module for "Discover the JS framework, chapter 2: Build a dashboard"
|
|
||||||
""",
|
|
||||||
|
|
||||||
'description': """
|
|
||||||
Starting module for "Discover the JS framework, chapter 2: Build a dashboard"
|
|
||||||
""",
|
|
||||||
|
|
||||||
'author': "Odoo",
|
|
||||||
'website': "https://www.odoo.com/",
|
|
||||||
'category': 'Tutorials/AwesomeDashboard',
|
|
||||||
'version': '0.1',
|
|
||||||
'application': True,
|
|
||||||
'installable': True,
|
|
||||||
'depends': ['base', 'web', 'mail', 'crm'],
|
|
||||||
|
|
||||||
'data': [
|
|
||||||
'views/views.xml',
|
|
||||||
],
|
|
||||||
'assets': {
|
|
||||||
'web.assets_backend': [
|
|
||||||
'awesome_dashboard/static/src/**/*',
|
|
||||||
('remove', 'awesome_dashboard/static/src/dashboard/**/*'),
|
|
||||||
],
|
|
||||||
'awesome_dashboard.dashboard': [
|
|
||||||
'awesome_dashboard/static/src/dashboard/**/*'
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'license': 'AGPL-3'
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from . import controllers
|
|
|
@ -1,36 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import random
|
|
||||||
|
|
||||||
from odoo import http
|
|
||||||
from odoo.http import request
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class AwesomeDashboard(http.Controller):
|
|
||||||
@http.route('/awesome_dashboard/statistics', type='json', auth='user')
|
|
||||||
def get_statistics(self):
|
|
||||||
"""
|
|
||||||
Returns a dict of statistics about the orders:
|
|
||||||
'average_quantity': the average number of t-shirts by order
|
|
||||||
'average_time': the average time (in hours) elapsed between the
|
|
||||||
moment an order is created, and the moment is it sent
|
|
||||||
'nb_cancelled_orders': the number of cancelled orders, this month
|
|
||||||
'nb_new_orders': the number of new orders, this month
|
|
||||||
'total_amount': the total amount of orders, this month
|
|
||||||
"""
|
|
||||||
|
|
||||||
return {
|
|
||||||
'average_quantity': random.randint(4, 12),
|
|
||||||
'average_time': random.randint(4, 123),
|
|
||||||
'nb_cancelled_orders': random.randint(0, 50),
|
|
||||||
'nb_new_orders': random.randint(10, 200),
|
|
||||||
'orders_by_size': {
|
|
||||||
'm': random.randint(0, 150),
|
|
||||||
's': random.randint(0, 150),
|
|
||||||
'xl': random.randint(0, 150),
|
|
||||||
},
|
|
||||||
'total_amount': random.randint(100, 1000)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
|
|
||||||
import { Component, useState } from "@odoo/owl";
|
|
||||||
import { registry } from "@web/core/registry";
|
|
||||||
import { Layout } from "@web/search/layout";
|
|
||||||
import { useService } from "@web/core/utils/hooks"
|
|
||||||
import { DashboardItem } from "./dashboard_item/dashboard_item";
|
|
||||||
import { Piechart } from "./piechart/piechart";
|
|
||||||
|
|
||||||
class AwesomeDashboard extends Component {
|
|
||||||
static template = "awesome_dashboard.AwesomeDashboard";
|
|
||||||
static components = { Layout, DashboardItem, Piechart};
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
this.display = {
|
|
||||||
controlPanel: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
this.action = useService("action");
|
|
||||||
|
|
||||||
this.stats = useState(useService('awesome_dashboard.statistics'));
|
|
||||||
}
|
|
||||||
|
|
||||||
openCustomers() {
|
|
||||||
this.action.doAction("base.action_partner_form");
|
|
||||||
}
|
|
||||||
|
|
||||||
openLeads() {
|
|
||||||
this.action.doAction({
|
|
||||||
type: 'ir.actions.act_window',
|
|
||||||
name: 'Leads',
|
|
||||||
res_model: 'crm.lead',
|
|
||||||
views: [[false, 'tree'],[false, 'form']],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard);
|
|
|
@ -1,3 +0,0 @@
|
||||||
.o_dashboard {
|
|
||||||
background-color:rgb(0, 116, 151);
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<templates xml:space="preserve">
|
|
||||||
|
|
||||||
<t t-name="awesome_dashboard.AwesomeDashboard">
|
|
||||||
<Layout display="display" className="'o_dashboard h-100'">
|
|
||||||
<t t-set-slot="layout-buttons">
|
|
||||||
<button class="btn btn-primary" t-on-click="openCustomers">Customers</button>
|
|
||||||
<button class="btn btn-primary" t-on-click="openLeads">Leads</button>
|
|
||||||
</t>
|
|
||||||
<div class="d-flex flex-wrap" t-if="stats.isReady">
|
|
||||||
<DashboardItem>
|
|
||||||
Number of new orders this month
|
|
||||||
<div class="fs-1 fw-bold text-success text-center">
|
|
||||||
<t t-out="stats.nb_new_orders"/>
|
|
||||||
</div>
|
|
||||||
</DashboardItem>
|
|
||||||
<DashboardItem>
|
|
||||||
Total amount of new orders this month
|
|
||||||
<div class="fs-1 fw-bold text-success text-center">
|
|
||||||
<t t-out="stats.total_amount"/>
|
|
||||||
</div>
|
|
||||||
</DashboardItem>
|
|
||||||
<DashboardItem>
|
|
||||||
Average amount of t-shirt by order this month
|
|
||||||
<div class="fs-1 fw-bold text-success text-center">
|
|
||||||
<t t-out="stats.average_quantity"/>
|
|
||||||
</div>
|
|
||||||
</DashboardItem>
|
|
||||||
<DashboardItem>
|
|
||||||
Number of cancelled orders this month
|
|
||||||
<div class="fs-1 fw-bold text-success text-center">
|
|
||||||
<t t-out="stats.nb_cancelled_orders"/>
|
|
||||||
</div>
|
|
||||||
</DashboardItem>
|
|
||||||
<DashboardItem>
|
|
||||||
Average time for an order to go from ‘new’ to ‘sent’ or ‘cancelled’
|
|
||||||
<div class="fs-1 fw-bold text-success text-center">
|
|
||||||
<t t-out="stats.average_time"/>
|
|
||||||
</div>
|
|
||||||
</DashboardItem>
|
|
||||||
<DashboardItem size='4'>
|
|
||||||
Shirt orders by size
|
|
||||||
<Piechart data="stats.orders_by_size" label="'Shirt orders by size'"/>
|
|
||||||
</DashboardItem>
|
|
||||||
</div>
|
|
||||||
</Layout>
|
|
||||||
</t>
|
|
||||||
|
|
||||||
</templates>
|
|
|
@ -1,20 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
|
|
||||||
import { Component } from "@odoo/owl";
|
|
||||||
|
|
||||||
export class DashboardItem extends Component {
|
|
||||||
static template = "awesome_dashboard.DashboardItem";
|
|
||||||
static props = {
|
|
||||||
size: {
|
|
||||||
type: Number,
|
|
||||||
default: 1,
|
|
||||||
optional: true,
|
|
||||||
},
|
|
||||||
slots: {
|
|
||||||
type: Object,
|
|
||||||
shape: {
|
|
||||||
default: Object
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<templates xml:space="preserve">
|
|
||||||
|
|
||||||
<t t-name="awesome_dashboard.DashboardItem">
|
|
||||||
<section>
|
|
||||||
<div class="card d-inline-block m-2" t-attf-style="width:{{18*props.size}}rem;">
|
|
||||||
<div class="card-body">
|
|
||||||
<t t-slot="default">some content</t>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</t>
|
|
||||||
|
|
||||||
</templates>
|
|
|
@ -1,45 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
|
|
||||||
import { loadJS } from "@web/core/assets";
|
|
||||||
import { getColor } from "@web/core/colors/colors";
|
|
||||||
import { Component, onWillStart, useRef, onMounted, onWillUnmount } from "@odoo/owl";
|
|
||||||
|
|
||||||
export class Piechart extends Component {
|
|
||||||
static template = "awesome_dashboard.Piechart";
|
|
||||||
static props = {
|
|
||||||
label: String,
|
|
||||||
data: Object,
|
|
||||||
};
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
this.canvasRef = useRef("canvas");
|
|
||||||
onWillStart(() => loadJS(["/web/static/lib/Chart/Chart.js"]));
|
|
||||||
onMounted(() => {
|
|
||||||
this.renderChart();
|
|
||||||
});
|
|
||||||
onWillUnmount(() => {
|
|
||||||
this.chart.destroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderChart() {
|
|
||||||
const labels = Object.keys(this.props.data);
|
|
||||||
const data = Object.values(this.props.data);
|
|
||||||
const color = labels.map((_, index) => getColor(index));
|
|
||||||
this.chart = new Chart(this.canvasRef.el, {
|
|
||||||
type: "pie",
|
|
||||||
data: {
|
|
||||||
labels: labels,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: this.props.label,
|
|
||||||
data: data,
|
|
||||||
backgroundColor: color,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<templates xml:space="preserve">
|
|
||||||
|
|
||||||
<t t-name="awesome_dashboard.Piechart">
|
|
||||||
<div t-att-class="'h-100 ' + props.class" t-ref="root">
|
|
||||||
<div class="h-100 position-relative" t-ref="container">
|
|
||||||
<canvas t-ref="canvas" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
</templates>
|
|
|
@ -1,21 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
|
|
||||||
import { registry } from "@web/core/registry";
|
|
||||||
import { reactive } from "@odoo/owl";
|
|
||||||
|
|
||||||
const statisticsService = {
|
|
||||||
dependencies: ["rpc"],
|
|
||||||
start(env, { rpc }) {
|
|
||||||
const statistics = reactive({ isReady: false });
|
|
||||||
async function loadData() {
|
|
||||||
const updates = await rpc("/awesome_dashboard/statistics");
|
|
||||||
Object.assign(statistics, updates, { isReady: true });
|
|
||||||
}
|
|
||||||
setInterval(loadData, 10*60*1000);
|
|
||||||
loadData();
|
|
||||||
return statistics;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
registry.category("services").add("awesome_dashboard.statistics", statisticsService);
|
|
|
@ -1,15 +0,0 @@
|
||||||
/** @odoo-module */
|
|
||||||
|
|
||||||
import { registry } from "@web/core/registry";
|
|
||||||
import { LazyComponent } from "@web/core/assets";
|
|
||||||
import { Component, xml } from "@odoo/owl";
|
|
||||||
|
|
||||||
class AwesomeDashboardLoader extends Component {
|
|
||||||
|
|
||||||
static components = { LazyComponent };
|
|
||||||
static template = xml`
|
|
||||||
<LazyComponent bundle="'awesome_dashboard.dashboard'" Component="'AwesomeDashboard'" props="props"/>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboardLoader);
|
|
|
@ -1,11 +0,0 @@
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record model="ir.actions.client" id="dashboard">
|
|
||||||
<field name="name">Dashboard</field>
|
|
||||||
<field name="tag">awesome_dashboard.dashboard</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<menuitem name="Awesome Dashboard" id="awesome_dashboard.menu_root" groups="base.group_user" web_icon="awesome_dashboard,static/description/icon.png"/>
|
|
||||||
<menuitem name="Dashboard" id="awesome_dashboard.dashboard_menu" parent="awesome_dashboard.menu_root" action="awesome_dashboard.dashboard" sequence="1"/>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
Loading…
Reference in a new issue