diff --git a/Layout/default/Preorder/Index.php b/Layout/default/Preorder/Index.php
index 8f7a09285..7a205493b 100644
--- a/Layout/default/Preorder/Index.php
+++ b/Layout/default/Preorder/Index.php
@@ -1076,20 +1076,73 @@ $pagination_entity_name = "Vorbestellungen";
}
async function getFCPs(map) {
- var fcp = await $.get("=self::getUrl("Preorder", "Api")?>", {
+ const fcpResponse = await $.get("=self::getUrl("Preorder", "Api")?>", {
do: "getFCPsForCampaign",
campaign_id: "=$campaign->id?>"
});
- if(fcp.status == "OK") {
- fcp.result.forEach((fcp) => {
- var icon = L.MakiMarkers.icon({icon: "viewpoint", color: "yellow", size: "m"});
- var marker = L.marker([fcp.lat, fcp.lng], {icon: icon}).addTo(map);
- var google_maps_link = "https://www.google.com/maps/search/?api=1&query=" + fcp.lat + "," + fcp.lng;
- var popup_content = "Google Maps
" + fcp.text;
- marker.bindPopup(popup_content);
- });
- }
+ if (fcpResponse.status !== "OK" || !fcpResponse.result?.length) return;
+
+ const fcpIds = fcpResponse.result.map(fcp => fcp.real_id);
+ const statsResponse = await $.ajax({
+ url: "=self::getUrl("Preorder", "Api")?>?do=getRimoFcpStats",
+ type: 'POST',
+ contentType: 'application/json', // 1. Set the content type to JSON
+ data: JSON.stringify({ fcp_ids: fcpIds }) // 2. Stringify the data object
+ });
+ const stats = statsResponse.status === "OK" ? statsResponse.result : [];
+
+ fcpResponse.result.forEach(fcp => {
+ const icon = L.MakiMarkers.icon({ icon: "viewpoint", color: "yellow", size: "m" });
+ const marker = L.marker([fcp.lat, fcp.lng], { icon }).addTo(map);
+ const fcpStat = stats.find(s => parseInt(s.fcp_id) === parseInt(fcp.real_id));
+
+ const googleMapsLink = `https://www.google.com/maps/search/?api=1&query=${fcp.lat},${fcp.lng}`;
+
+ const statsHtml = !fcpStat ? `
Keine Statistiken gefunden.
` : `
+
+ Zusammenfassung:
+ Hausnummern Gesamt: ${fcpStat.total_hausnummer_count}
+ Wohneinheiten Gesamt: ${fcpStat.total_wohneinheit_count}
+ Aktive Vorbestellungen: ${fcpStat.total_active_preorders}
+
+ Details nach RIMO-Typ:
+
+
+
+ | Typ |
+ HN |
+ WE |
+ VB |
+
+
+
+ ${Object.entries(fcpStat.counts_by_rimo_type || {}).length ?
+ Object.entries(fcpStat.counts_by_rimo_type).map(([type, counts], index) => `
+
+ | ${type} |
+ ${counts.hausnummer_count} |
+ ${counts.wohneinheit_count} |
+ ${counts.preorder_count} |
+
+ `).join('') :
+ '| Keine detaillierten Statistiken verfügbar. |
'
+ }
+
+
+`;
+
+ const popupContent = `
+
+`;
+ marker.bindPopup(popupContent);
+ });
}
function centerMap() {
diff --git a/application/ADBRimoFcp/ADBRimoFcp.php b/application/ADBRimoFcp/ADBRimoFcp.php
index 148aafd65..c5bce7d2c 100644
--- a/application/ADBRimoFcp/ADBRimoFcp.php
+++ b/application/ADBRimoFcp/ADBRimoFcp.php
@@ -1,6 +1,7 @@
query($sql);
+ return $result ? $result->fetch_all(MYSQLI_ASSOC) : [];
+ }
}
\ No newline at end of file
diff --git a/application/ADBRimoFcp/ADBRimoFcpController.php b/application/ADBRimoFcp/ADBRimoFcpController.php
index 9c4804714..2c4ab51e9 100644
--- a/application/ADBRimoFcp/ADBRimoFcpController.php
+++ b/application/ADBRimoFcp/ADBRimoFcpController.php
@@ -136,14 +136,10 @@ class ADBRimoFcpController extends TTCrud {
public function getAllFCPsAction() {
- $input = json_decode(file_get_contents('php://input'), true);
-
$fcpList = ADBRimoFcp::getAll();
$fcpData = array_map(function ($fcp) {
return [
'id' => $fcp->id,
-// 'rimo_ex_state' => $fcp->rimo_ex_state,
-// 'rimo_op_state' => $fcp->rimo_op_state,
'gps_lat' => $fcp->gps_lat,
'gps_long' => $fcp->gps_long
];
@@ -151,4 +147,20 @@ class ADBRimoFcpController extends TTCrud {
self::returnJson(['success' => true, 'data' => $fcpData]);
}
+
+ public function getRimoFcpStatsAction() {
+ $stats = ADBRimoFcp::getRimoFcpStatistics();
+
+ if (!empty($this->postData->fcp_ids)) {
+ $fcpIds = (array) $this->postData->fcp_ids;
+ $stats = array_filter($stats, fn($item) => in_array($item['fcp_id'], $fcpIds));
+ }
+
+ foreach ($stats as &$item)
+ if (isset($item['counts_by_rimo_type']) && is_string($item['counts_by_rimo_type']))
+ $item['counts_by_rimo_type'] = json_decode($item['counts_by_rimo_type']);
+ unset($item);
+
+ self::returnJson(array_values($stats));
+ }
}
\ No newline at end of file
diff --git a/application/Preorder/PreorderController.php b/application/Preorder/PreorderController.php
index e9f470219..9b69e5f73 100644
--- a/application/Preorder/PreorderController.php
+++ b/application/Preorder/PreorderController.php
@@ -1090,6 +1090,9 @@ class PreorderController extends mfBaseController {
case "saveStatusJournal":
$return = $this->saveStatusJournalApi();
break;
+ case "getRimoFcpStats":
+ $return = $this->getRimoFcpStatsApi();
+ break;
default:
$return = false;
}
@@ -1221,11 +1224,28 @@ class PreorderController extends mfBaseController {
if (!$campaign->id) return [];
return array_map(
- fn($fcp) => ["id" => $fcp->name ?? null, "text" => $fcp->name ?? null, 'lat' => $fcp->gps_lat ?? null, 'lng' => $fcp->gps_long ?? null],
+ fn($fcp) => ["real_id" => $fcp->id, "id" => $fcp->name ?? null, "text" => $fcp->name ?? null, 'lat' => $fcp->gps_lat ?? null, 'lng' => $fcp->gps_long ?? null],
ADBRimoFcp::getAll(["netzgebiet_id" => intval($campaign->network->adb_netzgebiet_id)]) ?? []
);
}
+ public function getRimoFcpStatsApi() {
+ $this->postData = json_decode(file_get_contents("php://input"));
+ $stats = ADBRimoFcp::getRimoFcpStatistics();
+
+ if (!empty($this->postData->fcp_ids)) {
+ $fcpIds = (array) $this->postData->fcp_ids;
+ $stats = array_filter($stats, fn($item) => in_array($item['fcp_id'], $fcpIds));
+ }
+
+ foreach ($stats as &$item)
+ if (isset($item['counts_by_rimo_type']) && is_string($item['counts_by_rimo_type']))
+ $item['counts_by_rimo_type'] = json_decode($item['counts_by_rimo_type']);
+ unset($item);
+
+ return array_values($stats);
+ }
+
private function setBilledApi() {
$preorder_id = $this->request->id;
diff --git a/db/migrations/20250912080000_add_rimo_fcp_index.php b/db/migrations/20250912080000_add_rimo_fcp_index.php
new file mode 100644
index 000000000..b3fc46db9
--- /dev/null
+++ b/db/migrations/20250912080000_add_rimo_fcp_index.php
@@ -0,0 +1,53 @@
+getEnvironment() == "addressdb") {
+ $table = $this->table('Hausnummer');
+ if (!$table->hasIndexByName('idx_fcp_id_rimo_type')) {
+ $table->addIndex(['fcp_id', 'rimo_type'], ['name' => 'idx_fcp_id_rimo_type'])
+ ->update();
+ }
+ }
+
+ if ($this->getEnvironment() == "thetool") {
+ $table = $this->table('Preorder');
+ if (!$table->hasIndexByName('idx_adb_hausnummer_id')) {
+ $table->addIndex(['adb_hausnummer_id'], ['name' => 'idx_adb_hausnummer_id']);
+ }
+ if (!$table->hasIndexByName('idx_status_id')) {
+ $table->addIndex(['status_id'], ['name' => 'idx_status_id']);
+ }
+ $table->update();
+ }
+ }
+
+ public function down(): void
+ {
+ if ($this->getEnvironment() == "addressdb") {
+ $table = $this->table('Hausnummer');
+ if ($table->hasIndexByName('idx_fcp_id_rimo_type')) {
+ $table->removeIndexByName('idx_fcp_id_rimo_type')
+ ->update();
+ }
+ }
+
+ if ($this->getEnvironment() == "thetool") {
+ $table = $this->table('Preorder');
+ if ($table->hasIndexByName('idx_adb_hausnummer_id')) {
+ $table->removeIndexByName('idx_adb_hausnummer_id');
+ }
+ if ($table->hasIndexByName('idx_status_id')) {
+ $table->removeIndexByName('idx_status_id');
+ }
+ $table->update();
+ }
+ }
+}
+