db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME); $this->table = "Wohneinheit"; } protected function afterDelete() { foreach(ADBWohneinheitStatusflagValueModel::search(["wohneinheit_id" => $this->id]) as $flag_value) { $flag_value->delete(); } $this->refreshUnitCount(); } protected function afterSave($_params = []) { if(!$this->id) return true; if(!$this->hausnummer_id) return true; if(array_key_exists("no_aftersave", $_params) && $_params["no_aftersave"]) return true; $this->log->debug("[".$this->_ruid."] "."-----------------------------------------"); $this->log->debug("[".$this->_ruid."] ".__METHOD__.": wohneinheit_id: ".$this->id); // prevent potential infinite loop $nesting_level = mfValuecache::singleton()->get("adbwohneinheit-save-nesting-level-".$this->id); if(!$nesting_level) { $nesting_level = 1; } else { $nesting_level++; } mfValuecache::singleton()->set("adbwohneinheit-save-nesting-level-".$this->id, $nesting_level); if($nesting_level > 1) { $this->log->debug("[".$this->_ruid."] ".__METHOD__.": Preventing potential infinite loop"); return true; } $this->logChanges(); if(!array_key_exists("no_updates", $_params) || !$_params['no_updates']) { // Statuschange from Rimo statuschange AddressDB::handleRimoStatusUpdate($this->id); // Check if tuer has changed and sync to RIMO $this->syncTuerToRimo(); } $this->refreshUnitCount(); // reload self from database $this->fetch($this->id); return true; } private function syncTuerToRimo() { // Check if tuer field has changed $changes = $this->getChangedFields(); if(!in_array("tuer", $changes)) { return true; } // Check if we have a RIMO external ID if(!$this->extref) { $this->log->debug("[".$this->_ruid."] ".__METHOD__.": No extref set, skipping RIMO sync"); return true; } // Get the hausnummer to access network owner $hausnummer = $this->getProperty("hausnummer"); if(!$hausnummer || !$hausnummer->id) { $this->log->debug("[".$this->_ruid."] ".__METHOD__.": No hausnummer found, skipping RIMO sync"); return true; } if($hausnummer->netzgebiet->source == "citycom-oan-api") { return true; } if(!preg_match('/^SDIBuilding_\d+_\d+$/', $hausnummer->rimo_id)) { $this->log->info("[".$this->_ruid."] ".__METHOD__.": invalid rimo_id in Hausnummer ".$hausnummer->id); return true; } // Get RIMO API credentials $creds = $hausnummer->getNetownerRimoApiCredentials(); if(!$creds) { $this->log->warn("[".$this->_ruid."] ".__METHOD__.": No API credentials found for network owner"); return true; } // Get the API key (using prod environment) $apikey = $creds["prod"]["key"]; if(!$apikey) { $this->log->warn("[".$this->_ruid."] ".__METHOD__.": No API key found in credentials"); return true; } // Call RIMO API to update subAddress (tuer) $this->log->info("[".$this->_ruid."] ".__METHOD__.": Syncing tuer change to RIMO for home ".$this->extref.": '".$this->tuer."'"); $subaddress = ""; if($this->tuer) { $subaddress = "Top ".$this->tuer; } $result = Rimoapi::changeHomeSubAddress($apikey, $this->extref, $subaddress); if($result) { $this->log->info("[".$this->_ruid."] ".__METHOD__.": Successfully synced tuer to RIMO"); } else { $this->log->error("[".$this->_ruid."] ".__METHOD__.": Failed to sync tuer to RIMO"); } return $result; } public function refreshUnitCount() { // ADBWohneinheit_onSave_noAutoUnitCount can be defined if doing bulk // operations where unit count is calculated seperately if(!defined("ADBWohneinheit_onSave_noAutoUnitCount") || !ADBWohneinheit_onSave_noAutoUnitCount) { $unit_count = ADBWohneinheitModel::count(['hausnummer_id' => $this->hausnummer_id]); $hausnummer = $this->getProperty("hausnummer"); if($hausnummer->id) { $hausnummer->unit_count = $unit_count; $hausnummer->save(); } if($hausnummer->netzgebiet_id) { $netzgebiet = new ADBNetzgebiet($hausnummer->netzgebiet_id); if($netzgebiet->id) { $usable_unit_count = 0; $unit_count = ADBWohneinheitModel::count(['netzgebiet_id' => $hausnummer->netzgebiet_id]); if($unit_count) { $unit_count_gda = [ "sd" => 0, "md" => 0, ]; foreach(ADBHausnummerModel::search(["netzgebiet_id" => $hausnummer->netzgebiet_id]) as $hausnummer) { $gda_egenschaft = strtolower($hausnummer->gdaeigenschaft); if($hausnummer->rimo_type) { $gda_egenschaft = strtolower($hausnummer->rimo_type); } if(strtolower($gda_egenschaft) == "greenfield") continue; if(!$gda_egenschaft) { $unit_count_gda["sd"] += $hausnummer->unit_count; continue; } if($gda_egenschaft && array_key_exists($gda_egenschaft, TT_ADB_GDA_TYPES)) { $type = TT_ADB_GDA_TYPES[$gda_egenschaft]; if(!array_key_exists($type, $unit_count_gda)) { $unit_count_gda[$type] = 0; } $unit_count_gda[$type] += $hausnummer->unit_count; } } foreach($unit_count_gda as $type => $count) { $usable_unit_count += $count; $netzgebiet->{"unit_count_$type"} = $count; } } //var_dump($netzgebiet); $netzgebiet->unit_count = $usable_unit_count; $netzgebiet->save(); } } } } public function resetSaveNesting() { mfValuecache::singleton()->delete("adbwohneinheit-save-nesting-level-" . $this->id); } private function logChanges() { $changes = $this->getChangedFields(); if(!count($changes)) return true; $logstr = ""; foreach($changes as $key) { if($key == "status_id") { $old_status = new ADBStatus($this->_old_data->status_id); $new_status = new ADBStatus($this->data->status_id); $logstr .= "| '$key' => FROM '".$this->_old_data->$key."' TO '".$this->data->$key."' [".$old_status->code." => ".$new_status->code."]"; } elseif($key == "external_data" && $this->_old_data->external_data && $this->external_data) { $old_data = json_decode($this->_old_data->external_data); $new_data = json_decode($this->external_data); if(json_encode($old_data) !== json_encode($new_data)) { $logstr .= "| '$key' => FROM '".$this->_old_data->$key."' TO '".$this->data->$key."'"; } else { continue; } } else { $logstr .= "| '$key' => FROM '".$this->_old_data->$key."' TO '".$this->data->$key."'"; } } $me = new User(); $me->loadMe(); $this->log->info("[".$this->_ruid."] ".__CLASS__." Changes: User ".$me->username." $logstr"); return true; } public function setNewStatusCode($new_status_code) { if(!$new_status_code) return false; $new_status = ADBStatusModel::getFirst(["code" => $new_status_code]); if(!$new_status) return false; $old_status = $this->getProperty("status"); if($old_status->code < $new_status->code) { $this->status_id = $new_status->id; } return true; } public function setStatusflag($code, $value) { if(!$code || !$this->id) return false; $this->log->debug("[".$this->_ruid."] ".__METHOD__." (Wohneinheit $this->id) Setting $code to $value"); $sflag = ADBStatusflagModel::getFirst(["code" => $code]); $sflag->wohneinheit_id = $this->id; $sflag->value->value = $value ? 1 : 0; $sflag->value->save(); $this->log->ebug(print_r($sflag, true)); $this->log->ebug(print_r($sflag->value, true)); return true; } public static function parseHausnummerZusatz($text) { $data = []; $data['block'] = ""; $data['stock'] = ""; $data['stiege'] = ""; $data['tuer'] = ""; $data['zusatz'] = ""; $text = trim($text); if(!$text) return $data; $text = " ".$text; $m = []; if(preg_match('/(?:t(?:ü|ue)r|topp|door?)\s+(\d\d?|\w\w?)/i', $text, $m)) { $data['tuer'] = $m[1]; $text = str_replace($m[0], "", $text); } if(preg_match('/(\d+)\.\s+(?:stock|geschoss|etage|level|floor)/i', $text, $m)) { $data['stock'] = $m[1]; $text = str_replace($m[0], "", $text); } if(preg_match('/(?: stock(?:werk)?| geschoss| etage| level | floor)\s+(\d\d?|parterre|erdgescho(?:ss|ß))\.?/i', $text, $m)) { $data['stock'] = $m[1]; $text = str_replace($m[0], "", $text); } if(preg_match('/(parterre|erdgescho(?:ss|ß))/i', $text, $m)) { $data['stock'] = $m[1]; $text = str_replace($m[0], "", $text); } $text = trim(preg_replace('/\s{2,}/', "", $text)); if($text) { $data['zusatz'] = $text; } return $data; } public function getNewOAID() { if(!$this->hausnummer_id) { return false; } $bcode = $this->getProperty("hausnummer")->oaid; //var_dump($bcode); if(!$bcode) { $hausnummer = $this->getProperty("hausnummer"); $hausnummer->oaid = $hausnummer->getNewOAID(); if(!$hausnummer->oaid) { return false; } if(!$hausnummer->save()) { return false; } $bcode = $hausnummer->oaid; } $codes = []; // get existing codes $res = $this->db->select("Wohneinheit", "oaid", "oaid like '$bcode.%'"); if($this->db->num_rows($res)) { while($data = $this->db->fetch_object($res)) { $codes[] = $data->oaid; } } else { return $bcode.".001"; } if(count($codes)) { sort($codes); } $last_code = end($codes); $m = []; if(preg_match('/\.(\d+)$/', $last_code, $m)) { if($m[1]) { $last_num = $m[1]; } } else { return false; } $new_num = ++$last_num; $code = $bcode.".".sprintf("%03d", $new_num); return $code; } public function getExternalData() { if(!$this->external_data) return []; $extdata = json_decode($this->external_data, true); if(is_array($extdata) && count($extdata)) { return $extdata; } return false; } public function getExternalRimoData() { $extdata = $this->getExternalData(); if(!is_array($extdata) || !count($extdata)) { return false; } //var_dump($extdata);exit; if(array_key_exists("rimo", $extdata) && count($extdata['rimo'])) { $rimo_data = $extdata['rimo']; if(is_array($extdata['rimo']) && count($extdata['rimo'])) { return $rimo_data; } } return false; } public function getPatchEqString() { $patch = ""; if($this->patch_shelf) $patch .= $this->patch_shelf."-"; if($this->patch_module) $patch .= $this->patch_module; if($patch) { if($this->patch_cluster) { $patch = $this->patch_cluster."-".$patch; } else { $patch = $this->getProperty("hausnummer")->netzgebiet->extref."-".$patch; } } return $patch; } public function getProperty($name) { if($this->$name == null) { if($name == "hausnummer") { $this->hausnummer = new ADBHausnummer($this->hausnummer_id); return $this->hausnummer; } if($name == "rimo_workorder") { $this->rimo_workorder = new RimoWorkorder(); if($this->id) { $this->rimo_workorder = RimoWorkorderModel::getFirst(['adb_wohneinheit_id' => $this->id]); } return $this->rimo_workorder; } if($name == "rimo_workorders") { if(!$this->id) return null; $rimo_workorders = RimoWorkorderModel::search(["adb_wohneinheit_id" => $this->id]); if(count($rimo_workorders)) { $this->rimo_workorders = $rimo_workorders; } return $this->rimo_workorders; } if($name == "preorders") { if(!$this->id) return []; $preorders = PreorderModel::search(["adb_wohneinheit_id" => $this->id]); if(!count($preorders)) { return []; } $this->preorders = $preorders; return $this->preorders; } if($name == "active_preorders") { if(!$this->id) return []; $preorders = PreorderModel::searchActive(["adb_wohneinheit_id" => $this->id]); if(!count($preorders)) { return []; } $this->preorders = $preorders; return $this->preorders; } if($name == "ftu_data") { $rimo_data = $this->getExternalRimoData(); if(!is_array($rimo_data) || !count($rimo_data)) { return ['id' => "", 'name' => ""]; } if(array_key_exists("ftu", $rimo_data)) { $ftu_data = $rimo_data['ftu']; if($ftu_data['id'] || $ftu_data['name']) { $this->ftu_data = $ftu_data; return $this->ftu_data; } } return ['id' => "", 'name' => ""]; } if($name == "status") { $this->status = new ADBStatus($this->status_id); return $this->status; } if($name == "statusflags") { $flags = []; foreach(ADBStatusflagModel::getAll() as $flag) { $flag->wohneinheit_id = $this->id; $flags[$flag->id] = $flag; } if(count($flags)) { $this->statusflags = $flags; } return $this->statusflags; } $classname = ucfirst($name); $idfield = $name."_id"; $this->$name = new $classname($this->$idfield); if($this->$name->id) { return $this->$name; } else { return null; } } return $this->$name; } public function __toString() { $parts = []; if($this->block) { $parts[] = "Block ".$this->block; } if($this->stiege) { $parts[] = "Stiege ".$this->stiege; } if($this->stock) { if(is_numeric($this->stock)) { $parts[] = $this->stock.". Stock"; } elseif(preg_match('/^(erdgescho(ss|ß)|parterre)$/i', $this->stock)) { $parts[] = "Erdgeschoss"; } else { $parts[] = "Stock ".$this->stock; } } if($this->tuer) { $parts[] = "Tür ".$this->tuer; } if($this->zusatz) { $parts[] = $this->zusatz; } return implode(" ", $parts); } }