345 lines
15 KiB
PHP
345 lines
15 KiB
PHP
<?php
|
|
|
|
//TODO: interessen
|
|
class DashboardNewController extends mfBaseController {
|
|
private User $me;
|
|
|
|
protected function init(): void {
|
|
$this->needlogin=true;
|
|
$me = new User();
|
|
$me->loadMe();
|
|
$this->layout()->set("me", $me);
|
|
$this->me = $me;
|
|
}
|
|
|
|
protected function indexAction() {
|
|
if (!$this->me->can("Statistics") || !$this->me->is(["Admin", "netowner", "salespartner"])) {
|
|
$this->redirect("Dashboard");
|
|
}
|
|
|
|
$this->layout()->set('additionalJS', ["plugins/chart.js/chart.4.4.6.js", "plugins/chart.js/chartjs-adapter-moment.min.js"]);
|
|
Helper::renderVue($this, $this->mod, "Dashboard", ["IS_ADMIN" => $this->me->is("Admin") ? "true" : "false"]);
|
|
}
|
|
|
|
|
|
protected function getNetOwnerFilterOptionsAction() {
|
|
$allPreorderCampaigns = PreordercampaignModel::getAll();
|
|
$netowners = [];
|
|
|
|
foreach ($allPreorderCampaigns as $campaign) {
|
|
$network = new Network($campaign->network_id);
|
|
|
|
if (!$this->me->is("Admin") && $network->owner_id != $this->me->address_id) continue;
|
|
|
|
$networkOwner = new Address($network->owner_id);
|
|
$ownerName = $networkOwner->getCompanyOrName();
|
|
|
|
if (!in_array($network->owner_id, array_column($netowners, 'value'))) {
|
|
$netowners[] = ['text' => $ownerName, 'value' => $network->owner_id];
|
|
}
|
|
}
|
|
|
|
self::returnJson($netowners);
|
|
}
|
|
|
|
protected function getCampaignFilterOptionsAction() {
|
|
$post = json_decode(file_get_contents('php://input'), true);
|
|
$netowner_ids = isset($post['netOwners']) ? [$post['netOwners']] : [];
|
|
$campaigns = [];
|
|
|
|
$all_campaigns = $this->me->is("Admin") ? PreordercampaignModel::getAll() : PreordercampaignModel::search(["owner_id" => $this->me->address_id]);
|
|
|
|
if (!empty($netowner_ids)) {
|
|
foreach ($all_campaigns as $campaign) {
|
|
$networkOwner = $campaign->network->owner_id;
|
|
if (!in_array($networkOwner, $netowner_ids)) continue;
|
|
if (!in_array($campaign->id, array_column($campaigns, 'value'))) {
|
|
$campaigns[] = ['text' => $campaign->name, 'value' => $campaign->id];
|
|
}
|
|
}
|
|
} else {
|
|
foreach ($all_campaigns as $campaign) {
|
|
if (!in_array($campaign->id, array_column($campaigns, 'value'))) {
|
|
$campaigns[] = ['text' => $campaign->name, 'value' => $campaign->id];
|
|
}
|
|
}
|
|
}
|
|
|
|
self::returnJson($campaigns);
|
|
}
|
|
|
|
protected function getCampaignGemeindeFilterOptionsAction() {
|
|
$post = json_decode(file_get_contents('php://input'), true);
|
|
$netowner_ids = isset($post['netOwners']) ? [$post['netOwners']] : [];
|
|
$campaign_ids = isset($post['campaigns']) ? [$post['campaigns']] : [];
|
|
$campaigns = [];
|
|
|
|
$all_campaigns = $this->me->is("Admin") ? PreordercampaignModel::getAll() : PreordercampaignModel::search(["owner_id" => $this->me->address_id]);
|
|
|
|
if (!empty($netowner_ids)) {
|
|
foreach ($all_campaigns as $campaign) {
|
|
$networkOwner = $campaign->network->owner_id;
|
|
if (!in_array($networkOwner, $netowner_ids)) continue;
|
|
if (in_array($campaign->id, $campaign_ids)) continue;
|
|
$campaigns[] = $campaign->id;
|
|
}
|
|
} else {
|
|
foreach ($all_campaigns as $campaign) {
|
|
if (in_array($campaign->id, $campaign_ids)) continue;
|
|
$campaigns[] = $campaign->id;
|
|
}
|
|
}
|
|
|
|
if (!empty($campaign_ids)) {
|
|
self::returnJson($this->getGemeindenFromCampaigns($campaign_ids));
|
|
return;
|
|
}
|
|
|
|
self::returnJson($this->getGemeindenFromCampaigns($campaigns));
|
|
}
|
|
|
|
private function checkParameterAuthorization($campaign_ids = []) {
|
|
// $campaigns = PreordercampaignModel::search(["owner_id" => $this->me->address_id]);
|
|
// $campaign_filter = ["preordercampaign_id" => $campaign_ids];
|
|
// if(!$campaign_ids) {
|
|
// foreach(PreordercampaignModel::search(["owner_id" => $this->me->address_id]) as $campaign) {
|
|
// $campaign_ids[] = $campaign->id;
|
|
// }
|
|
// }
|
|
// we need to use this if the user is not a admin to only show his campaigns
|
|
// we will pass the campaign_ids to the function and check if the user is allowed to see the data
|
|
// if the user is not allowed to see the data we will return an empty array
|
|
|
|
$campaigns = PreordercampaignModel::search(["owner_id" => $this->me->address_id]);
|
|
// loop through the campaigns and check if the user is allowed to see the data
|
|
foreach ($campaigns as $campaign) {
|
|
if (!in_array($campaign->id, $campaign_ids)) {
|
|
$key = array_search($campaign->id, $campaign_ids);
|
|
unset($campaign_ids[$key]);
|
|
}
|
|
}
|
|
|
|
return $campaign_ids;
|
|
}
|
|
|
|
private function getGemeindenFromCampaigns($campaignids = []) {
|
|
$gemeinden = [];
|
|
|
|
foreach ($campaignids as $campaign_id) {
|
|
$campaign = new Preordercampaign($campaign_id);
|
|
if (!$campaign || !$campaign->network_id || !$campaign->network->adb_netzgebiet_id) continue;
|
|
|
|
$gems = $campaign->network->adb_netzgebiet->gemeinden;
|
|
|
|
if (!is_array($gems)) continue;
|
|
|
|
foreach ($gems as $gem) {
|
|
if (!in_array($gem->id, array_column($gemeinden, 'value'))) $gemeinden[] = ['text' => $gem->name, 'value' => $gem->id];
|
|
}
|
|
}
|
|
ksort($gemeinden);
|
|
|
|
return $gemeinden;
|
|
}
|
|
|
|
|
|
protected function getDashboardDataAction() {
|
|
$post = json_decode(file_get_contents('php://input'), true);
|
|
$netowner_ids = $post['netOwners'] === '' ? [] : [$post['netOwners']] ?? [];
|
|
$campaign_ids = $post['campaigns'] === '' ? [] : [$post['campaigns']] ?? [];
|
|
$gemeinde_ids = $post['gemeinden'] === '' ? [] : [$post['gemeinden']] ?? [];
|
|
|
|
if (!empty($netowner_ids)) {
|
|
$campaign_ids = empty($campaign_ids) ?
|
|
array_map(fn($campaign) => $campaign->id, PreordercampaignModel::getAll()) :
|
|
$campaign_ids;
|
|
|
|
$campaign_ids = array_filter($campaign_ids, function ($campaign_id) use ($netowner_ids) {
|
|
$campaign = new Preordercampaign($campaign_id);
|
|
return in_array($campaign->network->owner_id, $netowner_ids);
|
|
});
|
|
}
|
|
|
|
$order_max_homes = $this->getTotalHomes($campaign_ids, $gemeinde_ids);
|
|
|
|
$efh_connection_types = ["single-dwelling", "business"];
|
|
$mph_connection_types = ["apartment-building", "apartment", "multi-dwelling"];
|
|
|
|
$countFunction = function($params, $statusFlag = null) use ($campaign_ids, $gemeinde_ids) {
|
|
$baseParams = ["preordercampaign_id" => $campaign_ids, "gemeinde_id" => $gemeinde_ids];
|
|
$params = array_merge($baseParams, $params);
|
|
return $statusFlag ?
|
|
PreorderModel::countStatusFlagsActive($params, $statusFlag) :
|
|
PreorderModel::countActive($params);
|
|
};
|
|
|
|
|
|
$baufortschritt_140 = $countFunction([">status_code" => "139", "<status_code" => "899"]);
|
|
$timeline_baufortschritt_140 = $this->getTimeline('weekly-leerrohr', $campaign_ids, $gemeinde_ids);
|
|
|
|
$ont_installiert_300 = $countFunction([">status_code" => "299", "<status_code" => "899"]);
|
|
$timeline_ont_installiert_300 = $this->getTimeline('weekly-ont-installed', $campaign_ids, $gemeinde_ids);
|
|
|
|
$baufortschritt_140_base_value_before_history = $baufortschritt_140 - $timeline_baufortschritt_140[0][count($timeline_baufortschritt_140[0]) - 1]['value'];
|
|
|
|
foreach ($timeline_baufortschritt_140[0] as $key => $value) {
|
|
$timeline_baufortschritt_140[0][$key]['value'] += $baufortschritt_140_base_value_before_history;
|
|
}
|
|
|
|
$ont_installiert_300_base_value_before_history = $ont_installiert_300 - $timeline_ont_installiert_300[0][count($timeline_ont_installiert_300[0]) - 1]['value'];
|
|
|
|
foreach ($timeline_ont_installiert_300[0] as $key => $value) {
|
|
$timeline_ont_installiert_300[0][$key]['value'] += $ont_installiert_300_base_value_before_history;
|
|
}
|
|
|
|
|
|
self::returnJson([
|
|
'order_max_home_addrdb' => $order_max_homes,
|
|
'order_actual_order' => $countFunction([]),
|
|
'order_efh' => $countFunction(["connection_type" => $efh_connection_types]),
|
|
'order_efh_vorsorge' => $countFunction(["connection_type" => $efh_connection_types, "type" => "provision"]),
|
|
'order_efh_vollanschluss' => $countFunction(["connection_type" => $efh_connection_types, "type" => "order"]),
|
|
'order_mph' => $countFunction(["connection_type" => $mph_connection_types]),
|
|
'order_mph_vorsorge' => $countFunction(["connection_type" => $mph_connection_types, "type" => "provision"]),
|
|
'order_mph_vollanschluss' => $countFunction(["connection_type" => $mph_connection_types, "type" => "order"]),
|
|
'baufortschritt_140' => $baufortschritt_140,
|
|
'installationspaket_erhalten' => $countFunction(["connection_type" => $efh_connection_types], 145),
|
|
'lehrrohr_im_haus' => $countFunction(["connection_type" => $efh_connection_types], 200),
|
|
'inhouse_kabel_verlegt_efh' => $countFunction(["connection_type" => $efh_connection_types], 242),
|
|
'inhouse_kabel_verlegt_mph' => $countFunction(["connection_type" => $mph_connection_types], 242),
|
|
'installationsfortschritt_245' => $countFunction([">status_code" => "244", "<status_code" => "899"]),
|
|
'ont_installiert_300' => $ont_installiert_300,
|
|
'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),
|
|
'timeline_leerrohr' => $timeline_baufortschritt_140,
|
|
'timeline_ont_installed' => $timeline_ont_installiert_300
|
|
]);
|
|
}
|
|
|
|
private function getTimeline($type, $campaign_ids, $gemeinde_ids) { //TODO: fix gemeinde
|
|
$timeline = [];
|
|
$baseParams = ["preordercampaign_id" => $campaign_ids, "gemeinde_id" => $gemeinde_ids];
|
|
$timeline[] = $this->getTimelineData($type, $baseParams);
|
|
return $timeline;
|
|
}
|
|
|
|
|
|
|
|
// add Leerrohr to timeline
|
|
// add ont installed to 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)));
|
|
|
|
// Generate a unique cache key based on the function parameters
|
|
$cacheKey = md5($type . serialize($params));
|
|
$cacheFile = TEMP_DIR . "/Dashboard/" . $cacheKey . ".json";
|
|
|
|
// Ensure the cache directory exists
|
|
if (!is_dir(TEMP_DIR . "/Dashboard/")) {
|
|
mkdir(TEMP_DIR . "/Dashboard/", 0755, true);
|
|
}
|
|
|
|
// Load cached data if it exists
|
|
if (file_exists($cacheFile) && false) {
|
|
$cachedData = json_decode(file_get_contents($cacheFile), true);
|
|
$lastCachedDate = end($cachedData)['date'];
|
|
$lastCachedTimestamp = strtotime($lastCachedDate);
|
|
|
|
// Only process the last 5 weeks
|
|
$daterange = new DatePeriod(
|
|
date_create(date('Y-m-d', max($lastCachedTimestamp, strtotime('-5 weeks')))),
|
|
$interval,
|
|
date_create(date('Y-m-d', $end))
|
|
);
|
|
|
|
$timeline = $cachedData;
|
|
}
|
|
|
|
foreach ($daterange as $date) {
|
|
$date = $date->format('Y-m-d');
|
|
$value = 0;
|
|
|
|
switch ($type) {
|
|
case 'weekly-orders':
|
|
$params['add-where'] = " AND tt_preorder.`create` <= UNIX_TIMESTAMP('" . $date . " 23:59:59')";
|
|
$value = PreorderModel::countActive($params);
|
|
break;
|
|
case 'weekly-leerrohr':
|
|
$params['add-where'] = " AND ph.`create` <= UNIX_TIMESTAMP('" . $date . " 23:59:59')";
|
|
$value = PreorderModel::countHistoryStatus($params, 140);
|
|
break;
|
|
case 'weekly-ont-installed':
|
|
$params['add-where'] = " AND ph.`create` <= UNIX_TIMESTAMP('" . $date . " 23:59:59')";
|
|
$value = PreorderModel::countHistoryStatus($params, 300);
|
|
break;
|
|
}
|
|
|
|
$newData = [
|
|
'date' => date(DATE_ATOM, strtotime($date)),
|
|
'value' => $value
|
|
];
|
|
|
|
// Update existing data or add new data
|
|
$existingIndex = array_search($newData['date'], array_column($timeline, 'date'));
|
|
if ($existingIndex !== false) {
|
|
$timeline[$existingIndex] = $newData;
|
|
} else {
|
|
$timeline[] = $newData;
|
|
}
|
|
}
|
|
|
|
// Sort the timeline by date
|
|
usort($timeline, function($a, $b) {
|
|
return strtotime($a['date']) - strtotime($b['date']);
|
|
});
|
|
|
|
// Cache the updated data
|
|
file_put_contents($cacheFile, json_encode($timeline));
|
|
|
|
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
|
|
LEFT JOIN `" . ADDRESSDB_DBNAME . "`.Hausnummer adb_hausnummer ON (adb_wohneinheit.hausnummer_id = adb_hausnummer.id)
|
|
LEFT JOIN `" . ADDRESSDB_DBNAME . "`.Strasse adb_strasse ON (adb_hausnummer.strasse_id = adb_strasse.id)
|
|
WHERE 1=1";
|
|
|
|
$where = "";
|
|
|
|
if (!empty($preordercampaign_id)) {
|
|
$netzgebiet_ids = [];
|
|
foreach ($preordercampaign_id as $campaign_id) {
|
|
$campaign = new Preordercampaign($campaign_id);
|
|
if ($campaign->network_id) {
|
|
$network = new Network($campaign->network_id);
|
|
$netzgebiet_ids[] = $network->adb_netzgebiet_id;
|
|
}
|
|
}
|
|
|
|
$where .= " AND adb_hausnummer.netzgebiet_id IN (" . implode(',', array_map('intval', $netzgebiet_ids)) . ")";
|
|
}
|
|
|
|
if (!empty($gemeinde_id)) {
|
|
$where .= " AND adb_strasse.gemeinde_id IN (" . implode(',', array_map('intval', $gemeinde_id)) . ")";
|
|
}
|
|
|
|
$sql = $baseSQL . $where;
|
|
|
|
$res = $this->db()->query($sql);
|
|
if ($this->db()->num_rows($res)) {
|
|
$data = $this->db()->fetch_object($res);
|
|
return $data->cnt;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
} |