diff --git a/Layout/default/ConstructionConsentProject/Form.php b/Layout/default/ConstructionConsentProject/Form.php index 610ced431..2dc324781 100644 --- a/Layout/default/ConstructionConsentProject/Form.php +++ b/Layout/default/ConstructionConsentProject/Form.php @@ -90,6 +90,21 @@
+

Berechtigungen

+ +
+ +
+ +
+
+ +
+
@@ -120,12 +135,6 @@ closeOnSelect: false }); - $('#adb_hausnummer_id').on('select2:close', function(e) { - if(!$('#adb_hausnummer_id').val()) { - $('#new-address-toggle').show(); - } - - }); \ No newline at end of file diff --git a/application/ConstructionConsentProject/ConstructionConsentProject.php b/application/ConstructionConsentProject/ConstructionConsentProject.php index d80a96606..00d4ac2ed 100644 --- a/application/ConstructionConsentProject/ConstructionConsentProject.php +++ b/application/ConstructionConsentProject/ConstructionConsentProject.php @@ -4,6 +4,7 @@ class ConstructionConsentProject extends mfBaseModel { private $consents; private $networks; private $adb_networks; + private $addresses; protected function beforeUpdate($data) { if(!array_key_exists("edit_by", $data)) { @@ -18,11 +19,21 @@ class ConstructionConsentProject extends mfBaseModel { public function getProperty($name) { if($this->$name == null) { + if($name == "addresses") { + $addresses = ConstructionConsentProjectAddress::search(["constructionconsentproject_id" => $this->id]); + if(!count($addresses)) { + return []; + } + foreach($addresses as $address) { + $this->addresses[$address->address->id] = $address; + } + return $this->addresses; + } + if($name == "consents") { $consents = ConstructionConsent::search(["constructionconsentproject_id" => $this->id]); if(!$consents) { return []; - } $this->consents = $consents; return $this->consents; diff --git a/application/ConstructionConsentProject/ConstructionConsentProjectController.php b/application/ConstructionConsentProject/ConstructionConsentProjectController.php index 2c6aa0afd..fa6b13769 100644 --- a/application/ConstructionConsentProject/ConstructionConsentProjectController.php +++ b/application/ConstructionConsentProject/ConstructionConsentProjectController.php @@ -133,30 +133,21 @@ class ConstructionConsentProjectController extends mfBaseController { return $this->addAction(); } - $netzgebiete = []; if(!$project->save()) { $this->layout()->setFlash("Fehler beim Speichern", "error"); return $this->addAction(); } + + // save networks + $netzgebiete = []; foreach($r->adb_netzgebiet_id as $netzgebiet_id) { $netzgebiet = new ADBNetzgebiet($netzgebiet_id); if(!$netzgebiet->id) continue; $netzgebiete[] = $netzgebiet_id; } - - /* - if($mode == "add") { - $project = ConstructionConsentProject::create($data); - } else { - $project->update($data); - }*/ - - - - //save networks foreach($netzgebiete as $netzgebiet_id) { $ccn = ConstructionConsentNetwork::getFirst(["constructionconsentproject_id" => $project->id, "adb_netzgebiet_id" => $netzgebiet_id]); if(!$ccn) { @@ -167,17 +158,40 @@ class ConstructionConsentProjectController extends mfBaseController { $ccn->save(); } } - foreach(ConstructionConsentNetwork::search(["constructionconsentproject_id" => $project->id]) as $ccn) { if(!in_array($ccn->adb_netzgebiet_id, $netzgebiete)) { $ccn->delete(); } } + //var_dump($r->get());exit; + // save addresses + $addresses = []; + foreach($r->address_id as $address_id) { + $address = new Address($address_id); + if(!$address->id) continue; + + $addresses[] = $address_id; + } + foreach($addresses as $address_id) { + $cca = ConstructionConsentProjectAddress::getFirst(["constructionconsentproject_id" => $project->id, "address_id" => $address_id]); + if(!$cca) { + $cca = ConstructionConsentProjectAddress::create([ + "constructionconsentproject_id" => $project->id, + "address_id" => $address_id + ]); + $cca->save(); + } + } + foreach(ConstructionConsentProjectAddress::search(["constructionconsentproject_id" => $project->id]) as $cca) { + if(!in_array($cca->address_id, $addresses)) { + $cca->delete(); + } + } + + $this->layout()->setFlash("Zustimmungserklärungsprojekt erfolgreich gespeichert", "success"); $this->redirect("ConstructionConsentProject"); - - } diff --git a/db/migrations/20250205150003_create_construction_consent_project_address.php b/db/migrations/20250205150003_create_construction_consent_project_address.php new file mode 100644 index 000000000..836f5361f --- /dev/null +++ b/db/migrations/20250205150003_create_construction_consent_project_address.php @@ -0,0 +1,36 @@ +getEnvironment() == "thetool") { + $table = $this->table("ConstructionConsentProjectAddress"); + $table->addColumn("constructionconsentproject_id", "integer", ["null" => false]); + $table->addColumn("address_id", "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("ConstructionConsentProjectAddress")->drop()->save(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } +} diff --git a/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php b/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php index f08c8d242..dfaa0fec4 100644 --- a/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php +++ b/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php @@ -71,13 +71,13 @@ class AddressHelper if (array_key_exists(3, $m)) { $addresszusatz = trim($m[3]); } - } elseif (preg_match('/^(\D+)\s+(\d+[a-z0-9\/&#._-]*)(?:\s+((?:gesch(?:ae|ä)ft|werkstatt|schmiede|[^ ]*garage|betrieb und wohnungen|stg|paketlogistik|cafe|pavillon|pfarrheim|[^ ]*haus|[^ ]*geb(?:ae|ä)ude|[^ ]*halle|[^ ]*schule|Öhlmühle)(?:\s+[a-z0-9]+)?))?/i', $strasse_hausnummer, $m)) { + } elseif (preg_match('/^(.+)\s+(\d+[a-z0-9\/&#._-]*)(.+)?/i', $strasse_hausnummer, $m)) { $strasse_name = trim($m[1]); $hausnummer_name = trim($m[2]); if (array_key_exists(3, $m)) { $addresszusatz = trim($m[3]); } - } elseif (preg_match('/^(.+)\s+(\d+[a-z0-9\/&#._-]*)(.+)?/i', $strasse_hausnummer, $m)) { + } elseif (preg_match('/^(\D+)\s+(\d+[a-z0-9\/&#._-]*)(?:\s+((?:gesch(?:ae|ä)ft|werkstatt|schmiede|[^ ]*garage|betrieb und wohnungen|stg|paketlogistik|cafe|pavillon|pfarrheim|[^ ]*haus|[^ ]*geb(?:ae|ä)ude|[^ ]*halle|[^ ]*schule|Öhlmühle)(?:\s+[a-z0-9]+)?))?/i', $strasse_hausnummer, $m)) { $strasse_name = trim($m[1]); $hausnummer_name = trim($m[2]); if (array_key_exists(3, $m)) { diff --git a/scripts/adb-rimo-import/adb-rimo-import-broker.php b/scripts/adb-rimo-import/adb-rimo-import-broker.php new file mode 100644 index 000000000..c66e3296a --- /dev/null +++ b/scripts/adb-rimo-import/adb-rimo-import-broker.php @@ -0,0 +1,353 @@ +#!/usr/bin/php +id); +define("INTERNAL_USER_USERNAME", $me->username); + +$request = array(); + +// Put commandline arguments into $request +if(count($argv)) { + $args=$argv; + array_shift($args); // shift scriptname off of args array + foreach($args as $i => $arg) { + if(preg_match('/^--(.+)/',$arg,$m)) { + if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) { + $request[$m[1]] = $args[$i+1]; + } else { + $request[$m[1]] = true; + } + } elseif(preg_match('/^-([a-zA-Z])(.+)/', $arg, $m)) { + $request[$m[1]] = $m[2]; + } elseif(preg_match('/^-([^-])/', $arg, $m)) { + if(isset($args[$i+1]) && !preg_match('/^-/',$args[$i+1])) { + $request[$m[1]] = $args[$i + 1]; + } else { + $request[$m[1]] = true; + } + } + } +} + +require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php"); +$log = mfLoghandler::singleton(); + +cli_set_process_title("thetool-adb-rimo-import-broker"); +pcntl_async_signals(true); +pcntl_signal(SIGTERM, 'signalHandler'); + +$forkcount = 0; +$childpids = []; + +if(pidislocked()) { + echo "ADB Rimo Import Broker läuft bereits (pidfile vorhanden)\n"; + exit; +} +if(!lockpid()) { + $log->error(__FILE__.": Error creating lock file!"); + die("Error creating lock file!\n"); +} + +$max_processes = 10; + +$all_pids = []; +$jobs = []; + +$clusters = loadClusters(); + + +foreach($clusters as $cluster) { + $proc = [ + "cluster" => $cluster["cluster"], + "cluster_id" => $cluster["cluster"]->id, + "apiOwner" => $cluster["apiOwner"], + "apiUrl" => $cluster["apiUrl"], + "apiToken" => $cluster["apiKey"], + //"pid" => false, + "processtitle" => "ADB Import ".$cluster["cluster"]->name, + "start" => false, + ]; + $jobs[$cluster["cluster"]->id] = $proc; +} + +$all_procs = $jobs; +$fork_delay = 0; + +while(1) { + //echo "while\n"; + //sleep(5); + + $processes = []; + + $idle_proc_count = 0; + foreach($jobs as $proc) { + if($proc["start"]) { + continue; + } + $idle_proc_count++; + $processes[] = [ + "cluster_id" => $proc["cluster_id"], + "pid" => false, + "processtitle" => "ADB Import ".$proc["cluster_id"], + ]; + } + + //echo "[parent] $idle_proc_count processes to be started\n"; + // if no running processes remain -> exit + if(!$idle_proc_count && !count($all_pids)) { + echo "No more idle or running processes. Exiting.\n"; + break; + } + + //var_dump($processes); + foreach($processes as $key => $proc) { + if($proc["pid"]) { + // process is running already, nothing to do here + echo "[parent] ".$proc["cluster_id"]." pid exists (".$proc["pid"].")\n"; + continue; + } + + $cluster_id = $proc["cluster_id"]; + + if(isset($childpids[$cluster_id])) { + echo "[parent] job for ".$proc["cluster_id"]." exists\n"; + //echo "cannot start new $taskname job, because another one is running already\n"; + continue; + } + + // delay for 10 minutes before forking new process + if($fork_delay) { + echo "[parent] fork delay: $fork_delay\n"; + $fork_delay--; + sleep(1); + break; + } + + if(count($all_pids) >= $max_processes) { + echo "[parent] max processes reached. Currently ".count($all_pids)." running processes.\n"; + $fork_delay = 10; + sleep(1); + break; + } + + echo "[parent] forking for $cluster_id\n"; + $pid = pcntl_fork(); + + $fork_delay = 10; + + + if($pid === -1) { + $log->debug("error forking"); + exit; + } elseif($pid > 0) { + // in parent + $forkcount++; + $childpids[$cluster_id] = $pid; + $proc["pid"] = $pid; + $all_pids[$pid] = $proc; + + $jobs[$key]["start"] = date("d.m.Y H:i:s"); + } else { + // in child + $mypid = getmypid(); + + echo "[$mypid] Starting import for ".$proc["cluster_id"]."\n"; + + try { + cli_set_process_title($proc["processtitle"]); + + $script_name = __DIR__ . "/rimo-import.php"; + if(!file_exists($script_name)) { + echo "[$mypid] Runner $script_name not found\n"; + } + + echo "[$mypid] executing $script_name ".$proc["cluster_id"]."\n"; + + pcntl_exec($script_name, [$proc["cluster_id"]]); + + //only reachable on error + echo "[$mypid] Error exec()'ing ".$proc["processtitle"]."!\n"; + + } catch(\Exception $e) { + // exit child process on error + echo "$mypid caught exception: " . $e->getMessage(); + echo $e->getTraceAsString()."\n"; + exit; + } + exit; // make sure child exits when done + } + + //sleep(5); + } + + if(count($all_pids)) { + $status = false; + $return_pid = pcntl_wait($status, WNOHANG); + if($return_pid) { + echo "child $return_pid returned\n"; + $pid_proc = $all_pids[$return_pid]; + $pid_task = $pid_proc["cluster_id"]; + $childpids[$pid_task] = null; + unset($all_pids[$return_pid]); + unset($jobs[$pid_task]); + } + } + /*echo "No more PIDs, exiting loop\n"; + break;*/ + //sleep(5); +} + +unlockpid(); + +function loadClusters() { + $clusters = []; + + $netowners = ["estmk", "rml"]; + $apiEdition = "prod"; + + foreach ($netowners as $apiOwner) { + $apiData = TT_RIMO_API_CREDS[$apiOwner][$apiEdition]; + + $apiUrl = $apiData["url"]; + $apiToken = $apiData["key"]; + + if (!$apiUrl || !$apiToken) { + echo "Api Daten für $apiOwner unvollständig\n"; + } + + $epGetClusters = $apiUrl . RIMO_API_JSON_EP_GET_CLUSTERS; + + $baseParams = ['apiKey' => $apiToken]; + $ctxOptsGet = [ + 'http' => [ + 'method' => 'GET', + 'header' => 'accept: application/json' + ] + ]; + + /* + * Get RIMO Sales Clusters + */ + $params = $baseParams; + $qs = http_build_query($params); + + $req_url = $epGetClusters . "?" . $qs; + $req_ctx = stream_context_create($ctxOptsGet); + + //echo $req_url."\n"; + $responseText = file_get_contents($req_url, false, $req_ctx); + if ($responseText === false) { + echo "($apiOwner) Error fetching clusters\n"; + exit; + } + + $clustersResponse = json_decode($responseText); + //var_dump($clustersResponse); + //exit; + if (!is_object($clustersResponse) || !property_exists($clustersResponse, "item") || !is_array($clustersResponse->item) || !count($clustersResponse->item)) { + die("($apiOwner) Invalid GetClusters Response\n"); + } + + foreach ($clustersResponse->item as $cluster) { + $cluster_data = ["apiOwner" => $apiOwner, "apiKey" => $apiToken, "apiUrl" => $apiUrl, "cluster" => $cluster]; + $clusters[] = $cluster_data; + } + } + + return $clusters; +} + + +function signalHandler($sig) { + //global $continue; + global $childpids; + global $invoice_job_lock; + + //$continue = false; + //echo "in signal handler\n"; + + if(count($childpids)) { + foreach($childpids as $taskname => $pids) { + foreach($pids as $childpid) { + posix_kill($childpid, SIGTERM); + } + + } + } + unlockpid(); + exit; +} + +function client_log($pid, $text, $severity = "notice") { + global $log; + global $is_daemon; + + if($is_daemon) { + echo "[".date('Y-m-d H:i:s')."] [$pid] $text\n"; + } + $log->$severity($text); + + return true; +} + +function pidislocked() { + $pidfile = __DIR__."/.adb-rimo-import-broker.lock"; + if(file_exists($pidfile)) { + return true; + } + return false; +} +function lockpid() { + $pid = getmypid(); + $pidfile = __DIR__."/.adb-rimo-import-broker.lock"; + file_put_contents($pidfile, $pid); + if(file_exists($pidfile)) { + return true; + } + return false; +} + +function unlockpid() { + $pidfile = __DIR__."/.adb-rimo-import-broker.lock"; + if(file_exists($pidfile)) { + unlink($pidfile); + return true; + } + return false; +} \ No newline at end of file diff --git a/scripts/adb-rimo-import/rimo-import.php b/scripts/adb-rimo-import/rimo-import.php index 5f6663bf2..9705d9c16 100755 --- a/scripts/adb-rimo-import/rimo-import.php +++ b/scripts/adb-rimo-import/rimo-import.php @@ -45,11 +45,12 @@ if ($argc > 1) { } //$netowners = ["estmk", "rml"]; -//$netowners = ["estmk", "rml"]; -$netowners = ["sbidi"]; +$netowners = ["estmk", "rml"]; +//$netowners = ["sbidi"]; //$netowners = ["rml"]; $apiEdition = "prod"; +$startdate = date("Y-m-d"); $starttime = date("Y-m-d.H-i"); $clusters = []; @@ -700,8 +701,8 @@ foreach ($clusters as $cluster_data) { //echo "Updating Workorder $rimo_workorder_id ($workorder_home_id)\n"; if ($workorder_status != $wo->rimo_status) { - \mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0); - \mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$unit->id, 0); + //\mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0); + \mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$wo_home->id, 0); $wo->rimo_status = $workorder_status ?: ""; $wo->save(); } @@ -723,8 +724,8 @@ foreach ($clusters as $cluster_data) { //if(($option_wo_ignore_status == "Documented" && $workorder_status == "Documented") || $workorder_status == "Cancelled") continue; // dont import status > Executed - \mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0); - \mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$unit->id, 0); + //\mfValuecache::singleton()->set("adbhausnummer-save-nesting-level-".$hausnummer->id, 0); + \mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$wo_home->id, 0); //echo "Creating Workorder $rimo_workorder_id ($workorder_home_id)\n"; $wo = \RimoWorkorderModel::create([ "adb_wohneinheit_id" => $wo_home->id, @@ -745,7 +746,7 @@ foreach ($clusters as $cluster_data) { if ($addressErrors) { $netzname = preg_replace('/[^a-z0-9.-]/i', "_", $adb_netzgebiet->name); - $out_folder = dirname(__FILE__) . "/output/$starttime"; + $out_folder = dirname(__FILE__) . "/output/$startdate"; if (!file_exists($out_folder)) { mkdir($out_folder); }