diff --git a/application/DashboardNew/DashboardNewController.php b/application/DashboardNew/DashboardNewController.php index f0cdeebeb..5210ffc40 100644 --- a/application/DashboardNew/DashboardNewController.php +++ b/application/DashboardNew/DashboardNewController.php @@ -12,7 +12,7 @@ class DashboardNewController extends mfBaseController { } protected function indexAction() { -// $this->layout()->set('additionalJS', ["plugins/chart.js/chart.4.4.6.js", "plugins/chart.js/chartjs-adapter-moment.min.js"]); + $this->layout()->set('additionalJS', ["plugins/chart.js/chart.4.4.6.js", "plugins/chart.js/chartjs-adapter-moment.min.js"]); Helper::renderVue($this, "DashboardNew", $this->mod, []); } @@ -177,9 +177,44 @@ class DashboardNewController extends mfBaseController { 'vollanschluss_dokumentiert_350' => $countFunction(["status_code" => ["350","500"], "type" => "order"]), 'vorsorge_dokumentiert_351' => $countFunction(["status_code" => ["351","500"], "type" => "provision"]), 'provider_bestellt_500' => $countFunction(["status_code" => "500"]), + 'timeline' => $this->getTimeline('weekly-orders', $campaign_ids, $gemeinde_ids) ]); } + private function getTimeline($type, $campaign_ids, $gemeinde_ids) { + $timeline = []; + $baseParams = ["preordercampaign_id" => $campaign_ids]; + if (!empty($gemeinde_ids)) { + foreach ($gemeinde_ids as $gemeinde_id) { + $baseParams["gemeinde_id"] = $gemeinde_id; + $timeline[] = $this->getTimelineData($type, $baseParams); + } + } else { + $timeline[] = $this->getTimelineData($type, $baseParams); + } + + return $timeline; + } + + private function getTimelineData($type, $params) { + $timeline = []; + $start = strtotime('-1 year'); + $end = strtotime('today'); + $interval = new DateInterval('P1W'); + $daterange = new DatePeriod(date_create(date('Y-m-d', $start)), $interval, date_create(date('Y-m-d', $end))); + + foreach ($daterange as $date) { + $date = $date->format('Y-m-d'); + $params['add-where'] = " AND tt_preorder.`create` >= UNIX_TIMESTAMP('" . $date . " 00:00:00') AND tt_preorder.`create` <= UNIX_TIMESTAMP('" . $date . " 23:59:59')"; + $timeline[] = [ + 'date' => date(DATE_ATOM, strtotime($date)), + 'value' => PreorderModel::countActive($params) + ]; + } + + return $timeline; + +} private function getTotalHomes(array $preordercampaign_id = [], array $gemeinde_id = []) { $baseSQL = "SELECT COUNT(adb_wohneinheit.id) as cnt FROM `" . ADDRESSDB_DBNAME . "`.Wohneinheit adb_wohneinheit diff --git a/public/js/pages/DashboardNew/DashboardNew.css b/public/js/pages/DashboardNew/DashboardNew.css index 886371a4f..bb78cd3d4 100644 --- a/public/js/pages/DashboardNew/DashboardNew.css +++ b/public/js/pages/DashboardNew/DashboardNew.css @@ -21,6 +21,10 @@ gap: 1rem; } +.dashboard-chart { + height: 400px; + margin-top: 20px; +} @media (min-width: 768px) { diff --git a/public/js/pages/DashboardNew/DashboardNew.js b/public/js/pages/DashboardNew/DashboardNew.js index a746b0d15..b3d194def 100644 --- a/public/js/pages/DashboardNew/DashboardNew.js +++ b/public/js/pages/DashboardNew/DashboardNew.js @@ -78,6 +78,128 @@ Vue.component('tt-dashboard-display-card', { ` }); +Vue.component('tt-timeline-chart', { + props: { + chartData: { + type: Array, + required: true + }, + label: { + type: String, + default: '' + }, + dataColor: { + type: String, + default: 'rgb(75, 192, 192)' + }, + fillColor: { + type: Boolean, + default: true + }, + showGrid: { + type: Boolean, + default: true + } + }, + template: '', + data() { + return { + chart: null + }; + }, + mounted() { + this.renderChart(); + }, + methods: { + renderChart() { + const ctx = this.$refs.chart.getContext('2d'); + this.chart = new Chart(ctx, { + type: 'line', + data: { + labels: this.chartData.map(item => item.date), + datasets: [{ + label: 'Bestellungen', + data: this.chartData.map(item => item.value), + borderColor: this.dataColor, + backgroundColor: this.fillColor ? this.dataColor : 'transparent', + tension: 0.1, + fill: this.fillColor + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + x: { + type: 'time', + time: { + unit: 'week', + displayFormats: { + week: 'DD.MM' + } + }, + title: { + display: true, + text: 'Datum' + }, + grid: { + display: this.showGrid + }, + ticks: { + callback: (value, index, values) => { + const date = moment(value); + if (this.label === 'KW') { + return `KW ${date.isoWeek()}`; + } else { + return date.format('DD.MM'); + } + } + } + }, + y: { + beginAtZero: true, + title: { + display: true, + text: 'Anzahl der Bestellungen' + }, + grid: { + display: this.showGrid + } + } + }, + plugins: { + legend: { + display: false + }, + tooltip: { + callbacks: { + title: (context) => { + const date = moment(context[0].label); + if (this.label === 'KW') { + return `KW ${date.isoWeek()}`; + } else { + return date.format('DD.MM'); + } } + } + } + } + } + }); + } + }, + watch: { + chartData() { + if (this.chart) { + this.chart.data.labels = this.chartData.map(item => item.date); + this.chart.data.datasets[0].data = this.chartData.map(item => item.value); + this.chart.update(); + } + } + } +}); + + + Vue.component('dashboard-new', { template: ` @@ -204,6 +326,19 @@ Vue.component('dashboard-new', { color="#0bb36c" /> + +
+

Bestellverlauf

+
+ +
`, @@ -227,7 +362,8 @@ Vue.component('dashboard-new', { ont_installiert_300: "0", vollanschluss_dokumentiert_350: "0", vorsorge_dokumentiert_351: "0", - provider_bestellt_500: "0" + provider_bestellt_500: "0", + timeline: [] }, selectedNetworkOwner: 'all', selectedCampaign: 'all',