Merge branch 'fronkdev' of code.fronk.at:fronk/thetool into fronkdev

This commit is contained in:
Frank Schubert
2025-09-30 14:42:39 +02:00
12 changed files with 403 additions and 20 deletions

View File

@@ -318,6 +318,14 @@
<td><?=$address->rollout?></td>
<td><?=$address->rollout_info?></td>
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
<?php if($me->is("Admin")): ?>
<a href="<?=self::getUrl("AddressDB", "syncAddressToRimo", ["id" => $address->id])?>" title="Adressdaten nach Rimo exportieren">
<sup><span class="" style="margin-right: -16px;"><i class="fas fa-cloud-arrow-up text-success"></i></span></sup><i class="fal fa-r"></i>
</a>
<!--a href="<?=self::getUrl("AddressDB", "syncAddressFromRimo", ["id" => $address->id])?>" title="Adressdaten von Rimo holen">
<sup><span class="" style="margin-right: -16px;"><i class="fas fa-cloud-arrow-down text-danger"></i></span></sup><i class="fal fa-r"></i>
</a-->
<?php endif; ?>
<a href="<?=self::getUrl("AddressDB", "view", ["id" => $address->id])?>"><i class="far fa-fw fa-eye" title="Adresse Anzeigen"></i></a>
<a href="<?=self::getUrl("AddressDB", "edit", ["id" => $address->id])?>" class="pl-1"><i class="far fa-fw fa-edit" title="Adresse Bearbeiten"></i></a>
<a href="<?=self::getUrl("AddressDB", "delete", ["id" => $address->id])?>" onclick="if(!confirm('Addresse und alle Wohneinheiten wirklich löschen?')) return false;"><i class="far fa-fw fa-trash-alt text-danger" title="Adresse Löschen"></i></a>

View File

@@ -599,8 +599,14 @@ $pagination_entity_name = "Vorbestellungen";
<span class="text-pink"><?=$preorder->oaid?></span>
</td>
<td>
<?=($preorder->company) ? $preorder->company : $preorder->firstname." ".$preorder->lastname?><br />
<?=$preorder->street?><?=($preorder->housenumber) ? " ".$preorder->housenumber : ""?><br />
<?=($preorder->company) ? $preorder->company."<br />" : ""?>
<?=($preorder->firstname || $preorder->lastname ) ? $preorder->firstname." ".$preorder->lastname."<br />" : ""?>
<?=$preorder->street?><?=($preorder->housenumber) ? " ".$preorder->housenumber : ""?>
<?=($preorder->block) ? "Block ".$preorder->block : ""?>
<?=($preorder->stiege) ? "Stiege ".$preorder->stiege : ""?>
<?=($preorder->stock) ? "Stock ".$preorder->stock : ""?>
<?=($preorder->tuer) ? "Tür ".$preorder->tuer : ""?>
<br />
<?=$preorder->zip?> <?=$preorder->city?>
</td>
<td>

View File

@@ -57,7 +57,7 @@ class ADBHausnummer extends mfBaseModel {
return true;
}
private function updateAddressInRimo() {
public function updateAddressInRimo() {
if(!$this->rimo_id) return false;
$creds = $this->getNetownerRimoApiCredentials();
if(!$creds) {
@@ -65,8 +65,11 @@ class ADBHausnummer extends mfBaseModel {
}
$update_data = [];
if($this->strasse_id && $this->getProperty("strasse")->name) $update_data["address"] = $this->getProperty("strasse")->name;
if($this->ortschaft_id && $this->getProperty("ort")->name) $update_data["city"] = $this->getProperty("ort")->name;
if($this->strasse_id && $this->getProperty("strasse")->name) {
$update_data["address"] = $this->getProperty("strasse")->name;
if(strlen($this->hausnummer)) $update_data["address"] .= " ".$this->hausnummer;
}
if($this->ortschaft_id && $this->getProperty("ortschaft")->name) $update_data["city"] = $this->getProperty("ortschaft")->name;
if($this->plz_id && $this->getProperty("plz")->plz) $update_data["zipCode"] = $this->getProperty("plz")->plz;
if($this->strasse_id && $this->getProperty("strasse")->gemeinde_id && $this->getProperty("strasse")->gemeinde->name) $update_data["district"] = $this->getProperty("strasse")->gemeinde->name;

View File

@@ -149,7 +149,11 @@ class AddressDB {
$log = mfLoghandler::singleton();
$log->debug(__METHOD__.": =============================== in handleRimoStatusUpdate");
$wohneinheit = new ADBWohneinheit($wohneinheit_id);
$wohneinheit = mfValuecache::singleton()->get("mfObjectmodel-adb_wohneinheit-$wohneinheit_id");
if(!$wohneinheit) {
$wohneinheit = new ADBWohneinheit($wohneinheit_id);
if($wohneinheit->id) mfValuecache::singleton()->set("mfObjectmodel-adb_wohneinheit-$wohneinheit_id", $wohneinheit);
}
if(!$wohneinheit->id) {
//echo "no wohneinheit\n";
return false;

View File

@@ -783,6 +783,32 @@ class AddressDBController extends mfBaseController {
}
}*/
protected function syncAddressToRimoAction() {
if(!$this->me->is("Admin")) {
$this->redirect("AddressDB");
}
$hausnummer_id = $this->request->id;
if(!$hausnummer_id) {
$this->layout()->setFlash("Adresse nicht gefunden", "error");
$this->redirect("AddressDB");
}
$hausnummer = new ADBHausnummer($hausnummer_id);
if(!$hausnummer->id) {
$this->layout()->setFlash("Adresse nicht gefunden", "error");
}
if(!$hausnummer->updateAddressInRimo()) {
$this->layout()->setFlash("Fehler beim updaten der Adresse in Rimo", "error");
$this->redirect("AddressDB");
}
$this->layout()->setFlash("Adresse erfolgreich nach Rimo synchronisiert", "success");
$this->redirect("AddressDB");
}
protected function saveBulkupdateAction() {
if(!$this->me->is("Admin")) {
$this->redirect("AddressDB");
@@ -811,7 +837,7 @@ class AddressDBController extends mfBaseController {
$u = 0;
if(ADBHausnummerModel::count($filter, true) > 1000) {
$this->layout()->setFlas("Bissi viel auf einmal");
$this->layout()->setFlash("Bissi viel auf einmal");
}
$cache = [];
@@ -908,7 +934,7 @@ class AddressDBController extends mfBaseController {
$hausnummer->strasse_id = $strasse->id;
$updated = true;
}
if($plz_search && $hausnummer->plz != $plz->id) {
if($plz_search && $hausnummer->plz_id != $plz->id) {
$hausnummer->plz_id = $plz->id;
$updated = true;
}
@@ -973,6 +999,9 @@ class AddressDBController extends mfBaseController {
case 'findBuildings':
$return = $this->findBuildingsApi();
break;
case 'countWithFilter':
$return = $this->countWithFilter();
break;
case 'getUnit':
$return = $this->getUnitApi();
break;
@@ -994,6 +1023,14 @@ class AddressDBController extends mfBaseController {
$this->returnJson($data);
}
private function countWithFilter() {
$filter = $this->getPreparedFilter($this->request->filter);
$filter["netzgebiet_id"] = true;
return ["count" => ADBHausnummerModel::count($filter)];
}
private function updateAddressStatusApi() {
$address_id = $this->request->id;

View File

@@ -53,6 +53,7 @@ class PreorderApicontroller extends mfBaseApicontroller {
$this->addRoute("/preorder/:code/clientInstallationFinished", [$modules["Cif"], "providerSetCif"], "POST");
$this->addRoute("/preorder/:code/serviceActivated", [$modules["Activation"], "setServiceActive"], "POST");
$this->addRoute("/preorder/:code", "getPreorder", "GET");
$this->addRoute("/preorder/:code", "updatePreorder", "PUT");
$this->addRoute("/preorder/:code", "cancelPreorder", "DELETE");
@@ -331,6 +332,70 @@ class PreorderApicontroller extends mfBaseApicontroller {
}
protected function updatePreorder($code) {
$code = trim($code);
if(!$code) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
$preorder = PreorderModel::getFirst(['ucode' => strtoupper($code), 'partner_id' => $this->me->address_id]);
if(!$preorder) {
// try as extref
$preorder = PreorderModel::getFirst(['extref' => $code, 'partner_id' => $this->me->address_id]);
}
if(!$preorder) {
// try oan id
$preorder = PreorderModel::getFirst(['oaid' => strtolower($code), 'partner_id' => $this->me->address_id], "`create` DESC");
}
if(!$preorder) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
if($preorder->partner_id != $this->me->address_id) {
return mfResponse::NotFound(["message" => "Preorder not found"]);
}
$updates = [];
foreach(["contact_type","company","uid","firstname","lastname","street","housenumber","block","stock","stiege","tuer","unit_string","zip","city","phone","email"] as $type) {
if(array_key_exists($type, $this->post)) {
$updates[$type] = trim($this->post[$type]);
}
}
if(!count($updates)) {
return mfResponse::BadRequest(["message" => "No updates provided"]);
}
if(array_key_exists("contact_type", $updates)) {
if($updates["contact_type"] != "tenant" && $updates["contact_type"] != "owner") {
return mfResponse::BadRequest(["message" => "Invalid contact type. Must be 'owner' or 'tenant'"]);
}
}
$updates["edit_by"] = $this->me->id;
$preorder->update($updates);
// sanity checks
if(!$preorder->company && (!$preorder->firstname || !$preorder->lastname)) {
return mfResponse::BadRequest(["message" => "Cannot leave company or first- and lastname empty"]);
}
if(!$preorder->email) {
return mfResponse::BadRequest(["message" => "Cannot leave email empty"]);
}
if(!$preorder->street || !$preorder->zip || !$preorder->city) {
return mfResponse::BadRequest(["message" => "Cannot leave address fields empty"]);
}
if(!$preorder->save()) {
return mfResponse::InternalServerError();
}
return mfResponse::Ok(["message" => "Contact successfully updated"]);
}
protected function cancelPreorder($code) {
if($this->me->is("Preorderreadonly")) return \mfResponse::Forbidden();
/*

View File

@@ -41,6 +41,11 @@ class Preorder extends mfBaseModel {
if($this->uid === "string") {
$this->uid = "";
}
if($this->id) {
//echo "[{$this->_ruid}] preorder::afterload: adding to cache\n";
mfValuecache::singleton()->set("mfObjectmodel-preorder-" . $this->id, $this);
}
}
public function beforeSave($_params = []) {
@@ -57,6 +62,7 @@ class Preorder extends mfBaseModel {
$this->building = null;
$this->adb_hausnummer = null;
$this->adb_wohneinheit = null;
$this->attribute = null;
$this->services = null;
$this->ordered_services = null;
$this->creator = null;
@@ -475,7 +481,11 @@ class Preorder extends mfBaseModel {
return true;
}
$hausnummer = new ADBHausnummer($this->adb_hausnummer_id);
$hausnummer = mfValuecache::singleton()->get("mfObjectmodel-adb_hausnummer-" . $this->adb_hausnummer_id);
if(!$hausnummer) {
$hausnummer = new ADBHausnummer($this->adb_hausnummer_id);
if($hausnummer->id) mfValuecache::singleton()->set("mfObjectmodel-adb_hausnummer-".$this->adb_hausnummer_id, $hausnummer);
}
if(!$hausnummer->id) {
$this->log->warning("[".$this->_ruid."] ".__METHOD__ . ": hausnummer " . $this->adb_hausnummer_id . " not found!");
return true;
@@ -519,7 +529,11 @@ class Preorder extends mfBaseModel {
return true;
}
$wohneinheit = new ADBWohneinheit($this->adb_wohneinheit_id);
$wohneinheit = mfValuecache::singleton()->get("mfObjectmodel-adb_wohneinheit-" . $this->adb_wohneinheit_id);
if(!$wohneinheit) {
$wohneinheit = new ADBwohneinheit($this->adb_wohneinheit_id);
if($wohneinheit->id) mfValuecache::singleton()->set("mfObjectmodel-adb_wohneinheit-".$this->adb_wohneinheit_id, $wohneinheit);
}
if(!$wohneinheit->id) return true;
$this->log->debug("[".$this->_ruid."] ".__METHOD__ . ": new wohneinheit status code " . $new_wohneinheit_status->code);
@@ -536,6 +550,24 @@ class Preorder extends mfBaseModel {
if(is_array($flags) && count($flags)) {
foreach($flags as $flag) {
if(strlen($flag->value->value) && array_key_exists($flag->code, TT_PREORDER_STATUS_FLAG_MATRIX)) {
if($flag->code == "145") {
//echo "flag 145\n";
$attribs = $this->getProperty("attribute");
if(!is_array($attribs)) {
$attribs = [];
}
if(!array_key_exists("inhouse_cabling_supplied", $attribs) || $attribs["inhouse_cabling_supplied"] != $flag->value->value) {
$attribs["inhouse_cabling_supplied"] = (int)$flag->value->value;
//echo "[{$this->_ruid}] preorder::aftersave: updating attrib to ".(int)$flag->value->value."\n";
$this->attributes = json_encode($attribs);
$this->save(["no_aftersave" => true]);
//print_r($this->attributes);echo "\n";
}
}
$flag_matrix_item = TT_PREORDER_STATUS_FLAG_MATRIX[$flag->code];
if(!$flag_matrix_item["flag"]) continue;
@@ -548,7 +580,7 @@ class Preorder extends mfBaseModel {
//var_dump($hflag);exit;
$hflag->hausnummer_id = $hausnummer->id;
$hflag->value->value = $flag->value->value;
$hflag->save();
$hflag->value->save();
$this->log->debug("[" . $this->_ruid . "] " . __METHOD__ . ": Hausnummer flag " . $hflag->code . " value '" . $hflag->value->value . "' gespeichert");
}
}
@@ -1051,7 +1083,7 @@ class Preorder extends mfBaseModel {
public function setStatusFlag($code, $value = 1) {
if(!$code) return false;
$sflag = PreorderstatusflagModel::getFirst(["code" => $code]);
$sflag = PreorderStatusflagModel::getFirst(["code" => $code]);
if(!$sflag) return false;
$sflag->preorder_id = $this->id;
@@ -1503,13 +1535,31 @@ class Preorder extends mfBaseModel {
}
if($name == "adb_hausnummer") {
$this->adb_hausnummer = new ADBHausnummer($this->adb_hausnummer_id);
return $this->adb_hausnummer;
$hausnummer = mfValuecache::singleton()->get("mfObjectmodel-adb_hausnummer-" . $this->adb_hausnummer_id);
if(!$hausnummer) {
$hausnummer = new ADBHausnummer($this->adb_hausnummer_id);
}
if($hausnummer && $hausnummer->id) {
mfValuecache::singleton()->set("mfObjectmodel-adb_hausnummer-" . $this->adb_hausnummer_id, $hausnummer);
$this->adb_hausnummer = $hausnummer;
return $this->adb_hausnummer;
}
return new ADBHausnummer();
}
if($name == "adb_wohneinheit") {
$this->adb_wohneinheit = new ADBWohneinheit($this->adb_wohneinheit_id);
return $this->adb_wohneinheit;
$wohneinheit = mfValuecache::singleton()->get("mfObjectmodel-adb_wohneinheit-" . $this->adb_wohneinheit_id);
if(!$wohneinheit) {
$wohneinheit = new ADBWohneinheit($this->adb_wohneinheit_id);
}
if($wohneinheit && $wohneinheit->id) {
mfValuecache::singleton()->set("mfObjectmodel-adb_wohneinheit-" . $this->adb_wohneinheit_id, $wohneinheit);
$this->adb_wohneinheit = $wohneinheit;
return $this->adb_wohneinheit;
}
return new ADBWohneinheit();
}
if($name == "services") {

View File

@@ -267,6 +267,13 @@ class PreorderModel
if ($db->num_rows($res)) {
$data = $db->fetch_object($res);
// search in cache
$item = mfValuecache::singleton()->get("mfObjectmodel-preorder-".$data->id);
if($item) {
return $item;
}
// if not in cache, load regularly
$item = new Preorder($data);
if ($item->id) {
return $item;
@@ -559,7 +566,12 @@ class PreorderModel
if ($returnArray) {
$items[] = $data;
} else {
$items[] = new Preorder($data);
$item = mfValuecache::singleton()->get("mfObjectmodel-preorder-".$data->id);
if($item) {
$items[] = $item;
} else {
$items[] = new Preorder($data);
}
}
}
}

View File

@@ -4,6 +4,7 @@ class PreorderStatusflagValue extends mfBaseModel {
private $preorder;
protected function afterSave() {
//echo __METHOD__."\n";
if(!property_exists($this->_old_data, "value") || $this->_old_data->value != $this->data->value) {
$history = PreorderHistoryModel::create([
"preorder_id" => $this->data->preorder_id,
@@ -15,7 +16,10 @@ class PreorderStatusflagValue extends mfBaseModel {
$history->save();
}
$this->getProperty("preorder")->afterSave();
$preorder = $this->getProperty("preorder");
//echo "[{$preorder->_ruid}] flagvalue aftersave: loaded preorder\n";
$preorder->afterSave();
}
public function getProperty($name) {
@@ -23,6 +27,7 @@ class PreorderStatusflagValue extends mfBaseModel {
$classname = ucfirst($name);
$idfield = $name."_id";
//var_dump(mfValuecache::singleton()->cache["mfObjectmodel-$name-".$this->$idfield]);exit;
$this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield);
if(!$this->$name) {
$this->$name = new $classname($this->$idfield);

View File

@@ -36,14 +36,16 @@ class Rimoapi {
$createOrderEp = RIMO_API_JSON_URL.RIMO_API_JSON_EP_CHANGE_BUILDING_ADDRESS;
$put_url = $createOrderEp."?".$qs;
$ctx = stream_context_create($ctx_opts);
$log->debug(__METHOD__.": Creating OAID in Rimo: $put_url");
$log->debug(__METHOD__.": Address Change in Rimo: $put_url");
$response = file_get_contents($put_url, false, $ctx);
//var_dump($response);exit;
$log->debug(__METHOD__.": response: ".print_r($response,true));
if($response === false) {
$log->error("Fehler beim Update der Adresse in RIMO ".$building_external_id);
return false;
}
$resp_data = json_decode($response);
if(!$resp_data->id) return false;

View File

@@ -185,7 +185,7 @@ class mfBaseApicontroller {
// POST Request
$post = [];
if($this->http_method == "POST") {
if($this->http_method == "POST" || $this->http_method == "PUT") {
$post = $this->getPostRequest();
if($post === false) {
$post = [];
@@ -234,6 +234,11 @@ class mfBaseApicontroller {
return $request_body;
}
if($this->http_method == "PUT") {
// PUT requests in application/x-www-form-urlencoded format need special handling
parse_str(file_get_contents("php://input"), $_POST);
}
// Request body is urlencoded or multipart-formdata
if(array_key_exists("CONTENT_TYPE", $_SERVER) && preg_match('#charset\s*=\s*["\']?([^ "\']+)["\']?\s*;?#i', $_SERVER["CONTENT_TYPE"], $m)) {
$request_charset = strtolower($m[1]);

View File

@@ -820,6 +820,192 @@ paths:
description: Unauthorized
'404':
description: Vorbestellung nicht gefunden
put:
tags:
- preorder
summary: Kontaktdaten bearbeiten
description: Zum Bearbeiten der Kontaktdaten einer Bestellung. Ein oder mehrere Parameter benötigt.
operationId: updatePreorderContact
parameters:
- name: id
in: path
description: Automatisch generierter **code** der Vorbestellung, **OAID** der Wohneinheit oder providereigene ID (**extref**)
required: true
schema:
type: string
requestBody:
description: zu ändernde Kontaktdaten
required: true
content:
'application/json':
schema:
type: object
description: Vertragsinhaber
properties:
type:
type: string
enum: [ "owner","tenant" ]
description: |
Ist diese Adresse Besitzer oder Bewohner der Wohneinheit. Optional, aber kann je nach Kampagne ein Pflichtfeld sein.
| type | Description |
|--------|-------------|
| owner | Ist Besitzer |
| tenant | Ist Bewohner|
company:
type: string
description: Firmenname Kunde
example:
uid:
type: string
description: UID (wenn Firmenkunde)
example:
firstname:
type: string
description: Vorname Kunde
example: Vor
lastname:
type: string
description: Nachname Kunde
example: Nachname
street:
type: string
description: Straße Kunde
example: Beispielstraße
housenumber:
type: string
description: Hausnummer Kunde
example: 42
zip:
type: string
description: PLZ Kunde
example: 9999
city:
type: string
description: Ort Kunde
example: Beispielhausen
block:
type: string
description: Adresszusatz
example: null
stiege:
type: string
description: Adresszusatz
example: null
stock:
type: string
description: Adresszusatz
example: null
tuer:
type: string
description: Adresszusatz
example: null
phone:
type: string
description: Telefonnummer Kunde
example: "01 1234 567 89"
email:
type: string
description: Emailadresse Kunde
example: this.email@does-not.exist
'application/x-www-form-urlencoded':
schema:
type: object
description: Vertragsinhaber
properties:
type:
type: string
enum: [ "owner","tenant" ]
description: |
Ist diese Adresse Besitzer oder Bewohner der Wohneinheit. Optional, aber kann je nach Kampagne ein Pflichtfeld sein.
| type | Description |
|--------|-------------|
| owner | Ist Besitzer |
| tenant | Ist Bewohner|
company:
type: string
description: Firmenname Kunde
example:
uid:
type: string
description: UID (wenn Firmenkunde)
example:
firstname:
type: string
description: Vorname Kunde
example: Vor
lastname:
type: string
description: Nachname Kunde
example: Nachname
street:
type: string
description: Straße Kunde
example: Beispielstraße
housenumber:
type: string
description: Hausnummer Kunde
example: 42
zip:
type: string
description: PLZ Kunde
example: 9999
city:
type: string
description: Ort Kunde
example: Beispielhausen
block:
type: string
description: Adresszusatz
example: null
stiege:
type: string
description: Adresszusatz
example: null
stock:
type: string
description: Adresszusatz
example: null
tuer:
type: string
description: Adresszusatz
example: null
phone:
type: string
description: Telefonnummer Kunde
example: "01 1234 567 89"
email:
type: string
description: Emailadresse Kunde
example: this.email@does-not.exist
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
properties:
status:
type: string
description: Status string
example: OK
result:
type: object
properties:
message:
type: string
description: Statustext
example: Contact successfully updated
'400':
description: Fehler in Eingabedaten
'401':
description: Api key fehlt oder ungültig
'403':
description: Keine Berechtigung
'404':
description: Bestellung nicht gefunden oder bereits storniert
delete:
tags:
- preorder