Skip to content
Extraits de code Groupes Projets
Valider be9022a0 rédigé par Benjamin's avatar Benjamin
Parcourir les fichiers

[add] dashboard year

parent 74bcdde7
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
'security/sapoval_dashboard_security.xml', 'security/sapoval_dashboard_security.xml',
'views/assets.xml', 'views/assets.xml',
'views/views.xml', 'views/views.xml',
'views/res_company_view.xml',
'views/schedule.xml', 'views/schedule.xml',
'security/ir.model.access.csv' 'security/ir.model.access.csv'
], ],
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sapoval_tdb import sapoval_tdb
import res_company
...@@ -150,3 +150,45 @@ class SapovalTdb(models.Model): ...@@ -150,3 +150,45 @@ class SapovalTdb(models.Model):
self.create({ 'date_tdb': str(datetime.now()) }) self.create({ 'date_tdb': str(datetime.now()) })
@api.model
def retrieve_datas_dashboard(self):
res = {
'facture': 0,
'commandes': 0,
'pipe': 0,
'pipe_n1': 0,
'pipe_win': 0,
'pipe_to_win': 0,
'target': 0,
'a_encaisser': 0,
}
self._cr.execute("""
SELECT
(select count(*) from account_invoice) as id,
(select sum(amount_untaxed) from account_invoice where state!='draft' and type='out_invoice' and date >= date_trunc('year', current_date) ) as facture,
(select sum(residual_company_signed) from account_invoice where state!='draft' and type='out_invoice' ) as a_encaisser,
(select sum(planned_revenue*probability/100) from crm_lead where active=True and (date_deadline < date_trunc('year', current_date + interval '1' year) or date_deadline is null) ) as pipe,
(select sum(planned_revenue*probability/100) from crm_lead where active=True and date_deadline >= date_trunc('year', current_date + interval '1' year) ) as pipe_n1,
(select sum(planned_revenue*probability/100) from crm_lead where active=True and probability=100) as pipe_win,
(select sum(planned_revenue*probability/100) from crm_lead where active=True and probability!=100) as pipe_to_win,
(select sum(price_subtotal-qty_invoiced*price_unit) from sale_order_line where invoice_status='to invoice') as commandes; """)
datas = self._cr.dictfetchall()
self._cr.execute("select ca_target from res_company;")
ca_target = self._cr.dictfetchall()
res['facture'] =+ datas[0]['facture']
res['a_encaisser'] =+ datas[0]['a_encaisser']
res['pipe'] =+ datas[0]['pipe']
if datas[0]['pipe_n1']:
res['pipe_n1'] =+ datas[0]['pipe_n1']
res['pipe_win'] =+ datas[0]['pipe_win']
res['pipe_to_win'] =+ datas[0]['pipe_to_win']
res['commandes'] =+ datas[0]['commandes']
if ca_target[0]['ca_target']:
res['target'] =+ ca_target[0]['ca_target']
return res
.tdb_form { margin: 20px 0; } .tdb_form { margin: 20px 0; }
.tdb_form hr { margin: 10px 0; } .tdb_form hr { margin: 10px 0; }
.content { width: calc(100% - 220px); padding: 10px 25px; } .content { width: calc(100% - 150px); padding: 10px 25px; background-color: #fff; }
.tableau { overflow: auto; margin-left: 150px; font-size: 11px; } .tableau { overflow: auto; margin-left: 150px; font-size: 11px; }
.table-sapoval > thead > tr > th:first-child, .table-sapoval > thead > tr > th:first-child,
...@@ -28,3 +28,41 @@ ...@@ -28,3 +28,41 @@
padding: 6px 10px; padding: 6px 10px;
text-transform: none; text-transform: none;
} }
#ca, #cmd, #pipe { cursor: pointer; }
.section-data { font-weight: 700; }
/*.section-data th { background-color: #F0F0F0; }
.table > tbody > tr.section-data > td, .table > tbody > tr.section-data th { border-top: 1px solid #000 !important; }*/
.yeardashboard { background-color: #F7F7F7; padding: 20px; min-height: 100%; }
.yeardashboard h3 { margin: 10px 15px; font-size: 20px; font-weight: 400; border-bottom: 1px solid #ddd; color: #5E6975; }
.card { background-color: #fff; color: #73879C; padding: 20px; margin: 10px 0; }
.card a { color: inherit; }
.card-half { float: left; width: 50%; }
.card-header { margin: 0!important; }
p.card-maj { margin: 0px; font-size: 10px; font-style: italic; font-weight: 300; }
.card-number { font-size: 30px; font-weight: 300; margin: 0!important; font-family: "Helvetica Neue", Helvetica, "Open Sans", Arial, sans-serif; }
.card-tab { background-color: #fff; color: #73879C; padding: 20px; margin: 0px 0 10px; }
.tresorerie .card-number { font-size: 20px; font-weight: 300; }
.nav-tabs > li > a { border-radius: 0; }
.dashboard-tab .nav-tabs { margin-top: 10px; border-bottom: none; }
.dashboard-tab .nav-tabs > li > a { border: none!important; color: #aaa;}
#commandes { cursor: pointer; }
#facture_non_encaisse { cursor: pointer; }
.ca_target { font-size: 18px; }
.btn-tdb { border: 1px solid #eee; border-radius: 0; font-size: 11px; padding: 6px 10px; text-transform: none; }
/*HIGHCHART*/
#hchart .highcharts-container { max-width: 100%; }
#hchart svg { max-width: 100%; }
.highcharts-title { font-family: "Helvetica Neue", Helvetica, "Open Sans"; }
.point { font-family: "Helvetica Neue", Helvetica, "Open Sans"; color: #73879C; text-align: center; }
.point_percent { font-size: 16px; font-weight: 400; }
/*Legend*/
.table-legend { width: 100%; max-width: 100%; margin: 10px 0; border-collapse: separate; border-spacing: 8px; font-size: 11px; }
.table-legend .nb { text-align: right; }
\ No newline at end of file
...@@ -92,3 +92,191 @@ odoo.define('sapoval_tdb.dashboard', function(require) { ...@@ -92,3 +92,191 @@ odoo.define('sapoval_tdb.dashboard', function(require) {
core.action_registry.add('sapoval_tdb.dashboard', SapovalDashboard); core.action_registry.add('sapoval_tdb.dashboard', SapovalDashboard);
}); });
odoo.define('lefilament_tdb.dashboard_year', function (require) {
"use strict";
var core = require('web.core');
var formats = require('web.formats');
var Model = require('web.Model');
var session = require('web.session');
var Widget = require('web.Widget');
var QWeb = core.qweb;
var _t = core._t;
var _lt = core._lt;
var YearDashboardView = Widget.extend({
template: 'YearDashboard',
events: {
'click .card': function() {
this.mychart.reflow();
},
'click #facture_non_encaisse': function() {
this.facture();
},
'click #commandes': function() {
this.commandes();
},
},
init: function() {
var result = this._super.apply(this, arguments);
return result;
},
willStart: function() {
var deferred = new jQuery.Deferred();
var self = this;
this.values = {};
this.progess = 0;
var dash_model = new Model('sapoval.dashboard');
dash_model.call('retrieve_datas_dashboard')
.then(function(results) {
self.values = results;
self.progress = results.facture / results.target;
deferred.resolve();
});
return jQuery.when(this._super.apply(this, arguments),deferred);
},
start: function() {
return this.render_chart();
},
render_chart: function(chart) {
self = this;
var pfact = (this.values.facture / this.values.target * 100).toFixed(0);
var pcomm = (this.values.commandes / this.values.target * 100).toFixed(0);
var ppipe_win = (this.values.pipe_win / this.values.target * 100).toFixed(0);
var ppipe_to_win = (this.values.pipe_to_win / this.values.target * 100).toFixed(0);
var ptarg = 100-pfact-pcomm-ppipe_win-ppipe_to_win;
var pfact2 = (this.values.facture);
var pcomm2 = (this.values.commandes);
var ppipe2_win = (this.values.pipe_win);
var ppipe2_to_win = (this.values.pipe_to_win);
var ptarg2 = this.values.target -pfact2-pcomm2-ppipe2_to_win-ppipe2_win;
var hchart = this.$el.find('#hchart')[0];
Highcharts.setOptions({ colors: ['#8ED8A2', '#F6DCA2', '#F6CCA2', '#F6ACA2', '#eee'], });
this.mychart = new Highcharts.chart({
chart: {
renderTo: hchart,
type: 'pie',
margin: 0
},
title: {
text: '<span class="ca_target">'+
self.values.target.toLocaleString('fr', { maximumFractionDigits: 0 }) + ' € </span><br />'
+'facturé '+ pfact + ' %<br />'
+'commandes '+ pcomm + ' %<br />'
+'gagné '+ ppipe_win + ' %<br />'
+'pipe '+ ppipe_to_win + ' %',
align: 'center',
verticalAlign: 'middle',
style: { 'color': '#73879C', 'font-size': '11px' },
y: -20,
},
plotOptions: {
pie: {
slicedOffset: 0,
size: '100%',
dataLabels: {
enabled: false
}
},
series: {
states: {
hover: {
enabled: false
}
}
}
},
tooltip: {
pointFormat: '<p class="point"><span class="point_percent">{point.percentage:.0f}% </span><br/> {point.y} €</p>',
backgroundColor: "rgba(255,255,255,0.85)",
borderColor: null,
borderRadius: 0,
borderWidth: 0,
useHTML: true,
shadow: false,
},
series: [{
type: 'pie',
innerSize: '85%',
data: [ ['Facturé', pfact2], ['Commandes', pcomm2], ['Gagné', ppipe2_win], ['Pipe', ppipe2_to_win], ['To Do', ptarg2], ],
slicedOffset: 0,
}],
});
this.mychart.reflow();
},
render_monetary: function(value) {
value = value.toLocaleString('fr', { maximumFractionDigits: 0 }) + '';
return value;
},
render_date: function(value) {
var dateFormat = new Date(value);
var new_value = moment(dateFormat).format('Do MMM YYYY');
return new_value;
},
render_monetary_color: function(value) {
if (value >= 0)
value = '<span class="positive">'+value.toLocaleString('fr', { maximumFractionDigits: 0 }) + ' €</span>';
else
value = '<span class="negative">'+value.toLocaleString('fr', { maximumFractionDigits: 0 }) + ' €</span>';
return value;
},
facture: function() {
var self = this;
var context = { 'user_id': this.session.uid, }
var action = ({
type: 'ir.actions.act_window',
res_model: 'account.invoice',
view_type: 'form',
view_mode: 'tree,form',
views: [[false, 'list'], [false, 'form']],
domain: [['state','=','open'],['type','=','out_invoice']],
target:'current',
name: 'Factures en cours',
context: context
})
this.do_action(action);
},
commandes: function() {
var self = this;
var context = { 'user_id': this.session.uid, }
var action = ({
type: 'ir.actions.act_window',
res_model: 'sale.order',
view_type: 'form',
view_mode: 'tree,form',
views: [[false, 'list'], [false, 'form']],
domain: [['invoice_status','=','to invoice']],
target:'current',
name: 'Commandes en cours',
context: context
})
this.do_action(action);
},
});
core.action_registry.add('lefilament_tdb.dashboard_year', YearDashboardView);
});
\ No newline at end of file
...@@ -164,4 +164,108 @@ ...@@ -164,4 +164,108 @@
</div> </div>
</t> </t>
<t t-name="YearDashboard">
<div class="yeardashboard">
<div class="row">
<!-- COLONNE 1 -->
<div class="col-xxs-12 col-xs-6">
<h3>En Cours</h3>
<div class="col-xs-12">
<div class="card">
<p class="card-header">Facturé</p>
<p class="card-number">
<t t-esc="widget.render_monetary(widget.values.facture)"></t>
</p>
</div>
</div>
<div class="col-xs-12">
<div class="card">
<p class="card-header">Commandes en cours</p>
<p class="card-number">
<a id="commandes">
<t t-esc="widget.render_monetary(widget.values.commandes)"></t>
</a>
</p>
</div>
</div>
<div class="col-xs-12 dashboard-tab">
<ul class="nav nav-tabs" id="myTab1">
<li class="active"><a data-toggle="tab" href="#pipe">Pipe</a></li>
<li><a data-toggle="tab" href="#pipe_n1">Pipe N+1</a></li>
</ul>
<div class="tab-content card-tab" id="myTab1Content">
<div id="pipe" class="tab-pane fade active in">
<p class="card-number">
<t t-esc="widget.render_monetary(widget.values.pipe)"></t>
</p>
</div>
<div id="pipe_n1" class="tab-pane fade">
<p class="card-number">
<t t-esc="widget.render_monetary(widget.values.pipe_n1)"></t>
</p>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="card">
<p class="card-header">Facturé non encaissé</p>
<p class="card-number">
<a id="facture_non_encaisse">
<t t-esc="widget.render_monetary(widget.values.a_encaisser)"></t>
</a>
</p>
</div>
</div>
</div>
<!-- COLONNE 2 -->
<div class="col-xxs-12 col-xs-6">
<h3>Objectif</h3>
<div class="col-xs-12">
<div class="card">
<p class="card-header">Target</p>
<p class="card-number">
<t t-esc="widget.render_monetary(widget.values.target)"></t>
</p>
<canvas id="target" width="auto" height="100"></canvas>
<div id="chart" class="chart-container"></div>
<!-- <div id="hchart" ></div> -->
<table class="table-legend">
<tr>
<td style="background-color: #8ED8A2; width: 20px;"></td>
<td>Facturé</td>
<td class="nb"><t t-esc="widget.render_percent(widget.pfact)"></t></td>
<td class="nb"><t t-esc="widget.render_keur(widget.pfact2)"></t></td>
</tr>
<tr>
<td style="background-color: #F6DCA2; width: 20px;"></td>
<td>Commandes</td>
<td class="nb"><t t-esc="widget.render_percent(widget.pcomm)"></t></td>
<td class="nb"><t t-esc="widget.render_keur(widget.pcomm2)"></t></td>
</tr>
<tr>
<td style="background-color: #F6CCA2; width: 20px;"></td>
<td>Pipe Gagné</td>
<td class="nb"><t t-esc="widget.render_percent(widget.ppipe_win)"></t></td>
<td class="nb"><t t-esc="widget.render_keur(widget.ppipe2_win)"></t></td>
</tr>
<tr>
<td style="background-color: #eee; width: 20px;"></td>
<td>To Do (sans pipe)</td>
<td class="nb"><t t-esc="widget.render_percent(widget.ptarg_sans_pipe)"></t></td>
<td class="nb"><t t-esc="widget.render_keur(widget.ptarg2_sans_pipe)"></t></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td>Pipe à transformer</td>
<td class="nb"><t t-esc="widget.render_percent(widget.ppipe_to_win)"></t></td>
<td class="nb"><t t-esc="widget.render_keur(widget.ppipe2_to_win)"></t></td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</t>
</templates> </templates>
\ No newline at end of file
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
<link href="/sapoval_tdb/static/src/css/sapoval_tdb.css" rel="stylesheet" /> <link href="/sapoval_tdb/static/src/css/sapoval_tdb.css" rel="stylesheet" />
<script type="text/javascript" src="/sapoval_tdb/static/src/lib/chart.js"></script>
<script type="text/javascript" src="/sapoval_tdb/static/src/lib/xlsx.core.min.js"></script> <script type="text/javascript" src="/sapoval_tdb/static/src/lib/xlsx.core.min.js"></script>
<script type="text/javascript" src="/sapoval_tdb/static/src/lib/FileSaver.min.js"></script> <script type="text/javascript" src="/sapoval_tdb/static/src/lib/FileSaver.min.js"></script>
<script type="text/javascript" src="/sapoval_tdb/static/src/lib/tableexport.js"></script> <script type="text/javascript" src="/sapoval_tdb/static/src/lib/tableexport.js"></script>
<script type="text/javascript" src="/sapoval_tdb/static/src/js/sapoval_tdb.js"></script> <script type="text/javascript" src="/sapoval_tdb/static/src/js/sapoval_tdb.js"></script>
<script type="text/javascript" src="/sapoval_tdb/static/src/js/dashboard_year.js"></script>
</xpath> </xpath>
</template> </template>
......
...@@ -4,15 +4,33 @@ ...@@ -4,15 +4,33 @@
<act_window id="sapoval_dashboard_action" name="Sapoval TdB" res_model="sapoval.dashboard" view_mode="tree,graph,form,pivot" /> <act_window id="sapoval_dashboard_action" name="Sapoval TdB" res_model="sapoval.dashboard" view_mode="tree,graph,form,pivot" />
<record id="sapoval_dashboard_variables_action" model="ir.actions.act_window" >
<field name="name">Variables Dashboard Sapoval</field>
<field name="res_model">res.company</field>
<field name="res_id">1</field>
<field name="view_mode">form</field>
</record>
<record id="action_home_page" model="ir.actions.client"> <record id="action_home_page" model="ir.actions.client">
<field name="name">Tableau de Bord - Sapoval</field> <field name="name">Tableau de Bord - Sapoval</field>
<field name="tag">sapoval_tdb.dashboard</field> <field name="tag">sapoval_tdb.dashboard</field>
</record> </record>
<menuitem id="sapoval_dashboard_menu" name="Tableau de Bord" sequence="100" groups="group_dashboard" action="action_home_page" /> <record id="action_year_page" model="ir.actions.client">
<menuitem id="sapoval_dashboard_report" parent="sapoval_dashboard_menu" name="Rapport" sequence="1" action="action_home_page"/> <field name="name">Rapport Annuel</field>
<menuitem id="sapoval_dashboard_datas" parent="sapoval_dashboard_menu" name="Données" action="sapoval_dashboard_action" sequence="10"/> <field name="tag">sapoval_tdb.dashboard_year</field>
</record>
<menuitem id="sapoval_dashboard_menu" name="Tableau de Bord" sequence="100" groups="group_dashboard" action="action_year_page" />
<menuitem id="sapoval_dashboard_report" parent="sapoval_dashboard_menu" name="Rapports" sequence="1"/>
<menuitem id="sapoval_dashboard_report_month" parent="sapoval_dashboard_report" name="Mensuel" sequence="2" action="action_home_page"/>
<menuitem id="sapoval_dashboard_report_year" parent="sapoval_dashboard_report" name="Annuel" sequence="1" action="action_year_page" />
<menuitem id="sapoval_dashboard_conf" parent="sapoval_dashboard_menu" name="Configuration" sequence="10"/>
<menuitem id="sapoval_dashboard_datas" parent="sapoval_dashboard_conf" name="Données" action="sapoval_dashboard_action" sequence="10"/>
<menuitem id="sapoval_dashboard_variables" parent="sapoval_dashboard_conf" name="Variables" action="sapoval_dashboard_variables_action" sequence="10"/>
<record id="sapoval_dashboard_tree" model="ir.ui.view"> <record id="sapoval_dashboard_tree" model="ir.ui.view">
<field name="name">Sapoval Dashboard Treeview</field> <field name="name">Sapoval Dashboard Treeview</field>
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter