WIP RTR Reporting

This commit is contained in:
Frank Schubert
2024-12-06 13:45:20 +01:00
parent 3a7b356b30
commit 33d7a4e5f1
12 changed files with 604 additions and 10 deletions

View File

@@ -24,6 +24,9 @@
<div class="row col-12">
<div><a href="<?=self::getUrl("Admin", "customerStatistics")?>">Kundenstatistiken</a></div>
</div>
<div class="row col-12">
<div><a href="<?=self::getUrl("Admin", "RtrReporting")?>">RTR Reporting</a></div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,42 @@
<?php include(realpath(dirname(__FILE__)."/../../../$mfLayoutPackage")."/header.php"); ?>
<!-- start page title -->
<div class="row">
<div class="col-12">
<div class="page-title-box">
<div class="page-title-right">
<ol class="breadcrumb m-0">
<li class="breadcrumb-item"><a href="<?=self::getUrl("Dashboard")?>"><?=MFAPPNAME_SLUG?></a></li>
<li class="breadcrumb-item"><a href="<?=self::getUrl("Admin")?>">Admin</a></li>
<li class="breadcrumb-item active">RTR Reporting</li>
</ol>
</div>
<h4 class="page-title">RTR Reporting</h4>
</div>
</div>
</div>
<!-- end page title -->
<div class="row">
<div class="col-12 col-xl-10">
<h3>RTR Reporting CSVs herunterladen</h3>
<div class="card">
<div class="card-body">
<div class="row col mb-3">
<a class="btn btn-primary" href="<?=self::getUrl("Admin", "rtrReporting", ["do" => "a10report"])?>"><i class="fas fa-fw fa-download"></i> A10</a>
</div>
<div class="row col mb-3">
<a class="btn btn-primary" href="<?=self::getUrl("Admin", "rtrReporting", ["do" => "b10report"])?>"><i class="fas fa-fw fa-download"></i> B10</a>
</div>
<div class="row col mb-3">
<a class="btn btn-primary" href="<?=self::getUrl("Admin", "rtrReporting", ["do" => "c10report"])?>"><i class="fas fa-fw fa-download"></i> C10</a>
</div>
</div>
</div>
</div>
</div>
<?php include(realpath(dirname(__FILE__)."/../../../$mfLayoutPackage")."/footer.php"); ?>

View File

@@ -27,11 +27,54 @@ class Address extends mfBaseModel {
$this->generateFibuAccountNumber();
$this->syncToFibuMerge();
$this->getCoords();
$this->in_after_save--;
}
public function getCoords() {
$update_needed = false;
if($this->id) {
$changes = $this->getChangedFields();
foreach($changes as $key => $change) {
if($key == "street" || $key == "zip" || $key == "city") {
$update_needed = true;
}
}
} else {
$update_needed = true;
}
if(!$this->gps_lat || !$this->gps_long || !$this->laea) {
$update_needed = true;
}
if(!$update_needed) return true;
$gps_search = [
'country' => $this->getProperty("country")->isocode,
'city' => $this->city,
'zip' => $this->zip,
'street' => $this->street
];
$gps = Gmaps_Geocoding::getCoords($gps_search);
if(!is_array($gps) || !count($gps) == 2) return false;
$this->gps_lat = $gps[0];
$this->gps_long = $gps[1];
$this->laea = (new Building())->getLaeaCoordinates($this->gps_lat, $this->gps_long);
$this->save();
return true;
}
public function generateFibuAccountNumber() {
if($this->fibu_account_number) {
return true;

View File

@@ -47,6 +47,37 @@ class AdminController extends mfBaseController {
$this->layout()->set("xinon_active_customers_total", $xinon_active_customers_total);
}
protected function rtrReporting() {
require_once(realpath(dirname(__FILE__)."/functions")."/RtrReporting.php");
$this->layout()->setTemplate("Admin/RtrReporting/Index");
$rtrreporting = new Admin_RtrReporting($this->request);
$response = $rtrreporting->runRequest();
foreach(["info", "success", "warning", "error"] as $level) {
if(array_key_exists($level, $response) && $response[$level]) {
$this->layout()->setFlash($response[$level], $level);
}
}
if($response["redirect"]) {
$this->redirect($response["redirect"]);
}
if($response["template"]) {
$this->layout()->setTemplate($response["template"]);
}
if(is_array($response["templateVars"]) && count($response["templateVars"])) {
foreach($response["templateVars"] as $key => $value) {
$this->layout()->set($key, $value);
}
}
}
protected function createNetworkAddressForNetowner() {

View File

@@ -0,0 +1,143 @@
<?php
class Admin_RtrReporting {
private $request;
private $db;
private $log;
private $flash = [];
public function __construct($request = false) {
$this->request = $request;
$this->db = FronkDB::singleton();
$this->log = mfLoghandler::singleton();
}
public function runRequest() {
$action = $this->request->do;
if(!$action) {
return $this->indexAction();
} else {
$method = $action."Action";
if(method_exists($this, $method)) {
return $this->$method();
} else {
throw new Exception("Method not found", "404");
}
}
}
public function indexAction() {
return [
"template" => "Admin/RtrReporting/Index",
"redirect" => "",
"templateVars" => []
];
}
public function a10reportAction() {
// alle anschlüsse
$rasterpunkte = [];
foreach(BuildingModel::getAll() as $building) {
$raster = $building->laea;
$prod_code = 14310;
$bb = "1000,00"; // glas = 1000, funk = 50
$user_count = TerminationModel::count(["building_id" => $building->id]);
if(!array_key_exists($raster, $rasterpunkte)) {
$rasterpunkte[$raster] = [];
}
if(!array_key_exists($prod_code, $rasterpunkte[$raster])) {
$rasterpunkte[$raster][$prod_code] = [
"bb" => $bb,
"user_count" => 0
];
}
$rasterpunkte[$raster][$prod_code]["user_count"] += $user_count;
}
$building = new Building();
$eigen_product_ids = $this->getEigenProductIds();
foreach(ContractModel::search(["product_id" => $eigen_product_ids]) as $contract) {
if($contract->termination_id) continue;
$address = $contract->owner;
if(!$address->gps_lat || !$address->gps_long || !$address->laea) {
//$address->getCoords();
$address->save();
}
$raster = $address->laea;
$rtr_code = $contract->product->attributes["rtr_tech_code"]->value;
if(substr($rtr_code, 0, 4) == 1431) {
$prod_code = 14310;
$bb = "1000,00";
} elseif(substr($rtr_code, 0, 4) == 1042) {
$prod_code = 10420;
$bb = "50,00";
} else {
continue; // incompatible product
}
$user_count = 1;
// get laea
if(!array_key_exists($raster, $rasterpunkte)) {
$rasterpunkte[$raster] = [];
}
if(!array_key_exists($prod_code, $rasterpunkte[$raster])) {
$rasterpunkte[$raster][$prod_code] = [
"bb" => $bb,
"user_count" => 0
];
}
$rasterpunkte[$raster][$prod_code]["user_count"] += $user_count;
}
$csv_header = "rasterid;code;dl_min_max_bb;dl_q25_max_bb;dl_avg_max_bb;dl_max_max_bb;ul_min_max_bb;ul_q25_max_bb;ul_avg_max_bb;ul_max_max_bb;dl_min_n_bb;dl_q25_n_bb;dl_avg_n_bb;dl_avg_n_bb;ul_min_n_bb;ul_q25_n_bb;ul_avg_n_bb;ul_avg_n_bb;anz_anschl_cov";
$csv = $csv_header."\n";
foreach($rasterpunkte as $rastercode => $raster) {
foreach($raster as $prod_code => $data) {
$csv .= $rastercode . ";";
$csv .= $prod_code . ";";
for($i = 0; $i < 16; $i++) {
$csv .= $data["bb"] . ";";
}
$csv .= $data["user_count"];
$csv .= "\n";
}
}
header("Content-type: text/csv; charset=utf-8");
header('Content-disposition: attachment; filename="rtr-A10-report-'.date('Y-m-d_H-i-s').'.csv"');
echo $csv;
exit;
}
/*
* 1042% = radio
* 1431% = fiber
*/
private function getEigenProductIds() {
$product_ids = [];
$sql = "SELECT product_id FROM `ProductAttribute`
LEFT JOIN ProducttechAttribute ON (ProductAttribute.producttechattribute_id = ProducttechAttribute.id)
WHERE ProducttechAttribute.name='rtr_tech_code'
AND (ProductAttribute.value LIKE '1042%' OR ProductAttribute.value LIKE '1431%')";
$res = $this->db->query($sql);
while($data = $this->db->fetch_object($res)) {
$product_ids[] = $data->product_id;
}
return $product_ids;
}
}

View File

@@ -200,9 +200,15 @@ class Building extends mfBaseModel {
return null;
}
public function getLaeaCoordinates() {
if(!$this->gps_lat || !$this->gps_lat) {
return false;
public function getLaeaCoordinates($gps_lat = 0, $gps_long = 0) {
if(!$gps_lat || !$gps_long) {
$gps_lat = $this->gps_lat;
$gps_long = $this->gps_long;
}
if(!$gps_lat || !$gps_long) {
return false;
}
// Elipsenparameter der Erdoberfläche
@@ -221,8 +227,8 @@ class Building extends mfBaseModel {
$PI = M_PI;
// Umrechnung der Eingabekoordinaten in rad
$Lat = $this->gps_lat * $PI / 180;
$Lon = $this->gps_long * $PI / 180;
$Lat = $gps_lat * $PI / 180;
$Lon = $gps_long * $PI / 180;
// Berechnungen
$q = (1 - $e ** 2) * ((sin($Lat) / (1 - $e ** 2 * sin($Lat) ** 2)) - ((1 / (2 * $e)) * log((1 - $e * sin($Lat)) / (1 + $e * sin($Lat)))));

View File

@@ -0,0 +1,167 @@
<?php
class Rtr100mRaster extends mfBaseModel {
public function getProperty($name) {
if($this->$name == null) {
$classname = ucfirst($name);
$idfield = $name."_id";
$this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield);
if(!$this->$name) {
$this->$name = new $classname($this->$idfield);
}
if($this->$name->id) {
mfValuecache::singleton()->set("mfObjectmodel-$name-".$this->$name->id, $this->$name);
return $this->$name;
} else {
return null;
}
}
return $this->$name;
}
/********************************
* Begin static Model functions
*/
public static function create(Array $data) {
$model = new Rtr100mRaster();
$table_fields = [
"raster", "unit_count",
"create_by","edit_by","create","edit"
];
foreach($data as $field => $value) {
if(in_array($field, $table_fields)) {
$model->$field = $value;
}
}
$me = new User();
$me->loadMe();
if($model->create_by === null) {
$model->create_by = $me->id;
}
if($model->edit_by === null) {
$model->edit_by = $me->id;
}
return $model;
}
public static function getAll() {
$items = [];
$db = FronkDB::singleton();
$res = $db->select("Rtr100mRaster", "*",);
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[] = new Rtr100mRaster($data);
}
}
return $items;
}
public static function getFirst($filter) {
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$sql = "SELECT * FROM Rtr100mRaster
WHERE $where
LIMIT 1";
//var_dump($sql);exit;
$res = $db->query($sql);
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new Rtr100mRaster($data);
if($item->id) {
return $item;
} else {
return null;
}
}
return null;
}
public static function count($filter) {
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$sql = "SELECT COUNT(*) as cnt FROM Rtr100mRaster
WHERE $where";
//mfLoghandler::singleton()->debug($sql);
$res = $db->query($sql);
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
return $data->cnt;
}
return 0;
}
public static function search($filter, $limit = false, $order = false) {
//var_dump($filter);exit;
$items = [];
if(!$order) {
$order = "";
} else {
$order = "ORDER BY $order";
}
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$sql = "SELECT * FROM Rtr100mRaster
WHERE $where
$order";
if(is_array($limit) && count($limit)) {
if(is_numeric($limit['start']) && is_numeric($limit['count'])) {
$sql .= " LIMIT ".$limit['start'].", ".$limit['count'];
} elseif(is_numeric($limit['count'])) {
$sql .= " LIMIT ".$limit['count'];
}
}
mfLoghandler::singleton()->debug($sql);
$res = $db->query($sql);
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[$data->id] = new Rtr100mRaster($data);
}
}
return $items;
}
private static function getSqlFilter($filter) {
$where = "1=1 ";
if(array_key_exists("raster", $filter)) {
$raster = FronkDB::singleton()->escape($filter["raster"]);
if($raster) {
$where .= " AND raster='$raster'";
}
}
if(array_key_exists("add-where", $filter)) {
$where .= " ".$filter['add-where'];
}
//var_dump($filter, $where);exit;
return $where;
}
}

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class AddressAddGpsAndLaea extends AbstractMigration
{
public function up(): void
{
if($this->getEnvironment() == "thetool") {
$table = $this->table("Address");
$table->addColumn("gps_lat", "decimal", ["null" => true, "default" => null, "precision" => 15, "scale" => 10, "after" => "country_id"]);
$table->addColumn("gps_long", "decimal", ["null" => true, "default" => null, "precision" => 15, "scale" => 10, "after" => "gps_lat"]);
$table->addColumn("laea", "string", ["null" => true, "default" => null, "limit" => 64, "after" => "gps_long"]);
$table->update();
}
if($this->getEnvironment() == "addressdb") {
}
}
public function down(): void
{
if($this->getEnvironment() == "thetool") {
$this->table("Address")
->removeColumn("laea")
->removeColumn("gps_long")
->removeColumn("gps_lat")
->update();
}
if($this->getEnvironment() == "addressdb") {
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class CreateRtr100mRaster extends AbstractMigration
{
public function up(): void
{
if($this->getEnvironment() == "thetool") {
$table = $this->table("Rtr100mRaster");
$table->addColumn("raster", "string", ["null" => false, "limit" => 32]);
$table->addColumn("unit_count", "integer", ["null" => false]);
$table->addColumn("create_by", "integer", ["null" => false]);
$table->addColumn("edit_by", "integer", ["null" => false]);
$table->addColumn("create", "integer", ["null" => false]);
$table->addColumn("edit", "integer", ["null" => false]);
$table->create();
}
if($this->getEnvironment() == "addressdb") {
}
}
public function down(): void
{
if($this->getEnvironment() == "thetool") {
$this->table("Rtr100mRaster")->drop()->save();
}
if($this->getEnvironment() == "addressdb") {
}
}
}

View File

@@ -41,10 +41,10 @@ class Gmaps_Geocoding {
return false;
}
$results = $json->results;
if(count($results) > 1) {
/*if(count($results) > 1) {
$log->warn(__FILE__.": Got more then 1 result. Aborting. ($url)");
return false;
}
}*/
$lat = $results[0]->geometry->location->lat;
$long = $results[0]->geometry->location->lng;

4
scripts/import/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*
!.gitignore
!100mraster
!100mraster/*

View File

@@ -0,0 +1,80 @@
#!/usr/bin/php
<?php
//require 'vendor/autoload.php';
require("../../../config/config.php");
define('FRONKDB_SQLDEBUG',false);
error_reporting(E_ALL & ~(E_NOTICE | E_STRICT | E_DEPRECATED));
require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php");
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseModel.php");
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseController.php");
$me = new User(1);
define("INTERNAL_USER_ID", $me->id);
define("INTERNAL_USER_USERNAME", $me->username);
$bundeslaender = [
"Burgenland",
"Kaernten",
"Niederoesterreich",
"Oberoesterreich",
"Salzburg",
"Steiermark",
"Tirol",
"Vorarlberg",
"Wien"
];
$db = FronkDB::singleton();
$log = mfLoghandler::singleton();
foreach($bundeslaender as $bland) {
$filename = __DIR__ . "/csv/StatistikAustria_100mRaster_Anschlusspotential2022_$bland.csv";
if(!file_exists($filename)) {
die("File $filename not found!\n");
}
$input = fopen($filename, "r");
$bom = "\xef\xbb\xbf";
if(fgets($input, 4) !== $bom) {
// BOM not found - rewind pointer to start of file.
rewind($input);
}
$headers = [];
$i = 0;
while($csv = fgetcsv($input, 0, ";")) {
$i++;
if($i == 1) {
foreach($csv as $key => $name) {
$headers[$name] = $key;
}
continue;
}
if(!trim($csv[0])) {
continue;
}
$raster = trim($csv[$headers["rasterid"]]);
$unit_count = trim($csv[$headers["anschlusspotential"]]);
$sql = "INSERT INTO `Rtr100mRaster` (`raster`,`unit_count`,`create_by`,`edit_by`,`create`,`edit`) VALUES('$raster',$unit_count,1,1,1733431100,1733431100)";
$db->query($sql);
/*
$rtr100mraster = Rtr100mRaster::create([
"raster" => $raster,
"unit_count" => $unit_count,
]);
$rtr100mraster->save()*/
}
}