diff --git a/Layout/default/AddressDB/View.php b/Layout/default/AddressDB/View.php
index 55c9dad4f..9c2bd6448 100644
--- a/Layout/default/AddressDB/View.php
+++ b/Layout/default/AddressDB/View.php
@@ -72,7 +72,15 @@
| Rimo Operational State |
=$address->rimo_op_state?> |
-
+
+ vlan_stag): ?>
+
+ | VLAN s-tag |
+ =$address->vlan_stag?> |
+
+
+
+
Status |
| Status |
diff --git a/application/Api/v1/Modules/Operationaldata/SnoppCitycom.php b/application/Api/v1/Modules/Operationaldata/SnoppCitycom.php
new file mode 100644
index 000000000..a63b35a51
--- /dev/null
+++ b/application/Api/v1/Modules/Operationaldata/SnoppCitycom.php
@@ -0,0 +1,85 @@
+ "id missing"]);
+ }
+
+ $bb_up = $this->post["bb_up"];
+ $bb_down = $this->post["bb_down"];
+ $execution_date = false;
+
+ if($this->post["execution_date"]) {
+ try {
+ $execution_date = new DateTime($this->post["execution_date"]);
+ } catch(\Exception $e) {
+ return mfResponse::BadRequest(["message" => "Invalid Timestamp format"]);
+ }
+ }
+
+
+ if(!is_numeric($bb_down) || !$bb_down || !is_numeric($bb_up) || !$bb_up || !$bb_down > 10000 || $bb_up > 10000) {
+ return \mfResponse::BadRequest(["message" => "Invalid bandwidth"]);
+ }
+
+ $wohneinheit = false;
+ if(is_numeric($req_id)) {
+ $id = $req_id;
+ $wohneinheit = new \ADBWohneinheit($id);
+ }
+ if(!$wohneinheit || !$wohneinheit->id) {
+ $oaid = $req_id;
+ $wohneinheit = \ADBWohneinheitModel::getFirst(["oaid" => $oaid]);
+ if (!$wohneinheit) {
+ return \mfResponse::NotFound(["message" => "Home not found"]);
+ }
+ }
+
+ $preorder = \PreorderModel::getFirstActive(["adb_wohneinheit_id" => $wohneinheit->id]);
+ if(!$preorder) {
+ return \mfResponse::NotFound(["message" => "Home not found"]);
+ }
+
+ $cc_home_id = \Citycom_OanApiHelper::hausnummerExtrefToCitycomId($wohneinheit->extref);
+ $data["bb_up"] = $bb_up;
+ $data["bb_down"] = $bb_down;
+ $data["product_name"] = false;
+ $data["execution_date"] = ($execution_date) ? $execution_date->format("Y-m-d") : false;
+ $data["services"] = CITYCOM_OAN_API_SERVICES_FOR_ORDER;
+
+ if($preorder->campaign->name == "Citycom - Graz") {
+ $data["product_name"] = "Estmk OAN $bb_down/$bb_up";
+ }
+
+
+
+ $cc_api_client = new \Citycom_OanApiClient(CITYCOM_OAN_API_USER, CITYCOM_OAN_API_PASS);
+ $cc_api = new \Citycom_OanApiHelper($cc_api_client);
+
+ if(!$cc_api->orderServices($preorder, $cc_home_id, $data)) {
+ return \mfResponse::InternalServerError(["message" => "Error activating service"]);
+ }
+
+
+
+ return false;
+
+ }
+
+}
\ No newline at end of file
diff --git a/application/Api/v1/OperationaldataApicontroller.php b/application/Api/v1/OperationaldataApicontroller.php
index f8314f2bf..5c75ea992 100644
--- a/application/Api/v1/OperationaldataApicontroller.php
+++ b/application/Api/v1/OperationaldataApicontroller.php
@@ -49,6 +49,8 @@ class OperationaldataApicontroller extends mfBaseApicontroller
$this->addRoute("/operationaldata/home/:id/connected", [$modules["Snopp"], "setPreorderConnected"], "POST");
$this->addRoute("/operationaldata/home/:id/active", [$modules["Snopp"], "setPreorderActive"], "POST");
+ $this->addRoute("/operationaldata/preorder/:id/orderService", [$modules["SnoppCitycom"], "orderService"], "POST");
+
}
/*
@@ -132,8 +134,12 @@ class OperationaldataApicontroller extends mfBaseApicontroller
$name = $network->name;
if($network->adb_netzgebiet_id) {
- $cityname = preg_replace('/^Liezen\s+-\s+/', '', $network->adb_netzgebiet->name);
- $name = "ROC_".$network->adb_netzgebiet->extref."_".$cityname;
+ if($network->adb_netzgebiet->source == "citycom-oan-api") {
+ $name = "OC ".$network->adb_netzgebiet->name;
+ } else {
+ $cityname = preg_replace('/^Liezen\s+-\s+/', '', $network->adb_netzgebiet->name);
+ $name = "ROC_" . $network->adb_netzgebiet->extref . "_" . $cityname;
+ }
}
$net = [];
@@ -224,7 +230,13 @@ class OperationaldataApicontroller extends mfBaseApicontroller
$woStateNameToId["Cancelled"] = 99;
- foreach(PreorderModel::searchActive(["preordercampaign_id" => $campaign_id, "partner_id" => $isp_ids]) as $preorder) {
+ $preorder_search = ["preordercampaign_id" => $campaign_id];
+ if(count($isp_ids)) {
+ $preorder_search["partner_id"] = $isp_ids;
+ }
+
+
+ foreach(PreorderModel::searchActive($preorder_search) as $preorder) {
$hausnummer_id = $preorder->adb_hausnummer_id;
$wohneinheit_id = $preorder->adb_wohneinheit_id;
diff --git a/db/migrations/20250722132925_adb_hausnummer_add_stag.php b/db/migrations/20250722132925_adb_hausnummer_add_stag.php
new file mode 100644
index 000000000..3dda4536d
--- /dev/null
+++ b/db/migrations/20250722132925_adb_hausnummer_add_stag.php
@@ -0,0 +1,31 @@
+getEnvironment() == "thetool") {
+
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+ $table = $this->table("Hausnummer");
+ $table->addColumn("vlan_stag", "integer", ["null" => true, "default" => null, "after" => "rimo_fcp_name"]);
+ $table->update();
+ }
+ }
+
+ public function down(): void
+ {
+ if($this->getEnvironment() == "thetool") {
+
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+ $this->table("Hausnummer")->removeColumn("vlan_stag")->update();
+ }
+ }
+}
diff --git a/lib/Citycom/OanApi.php b/lib/Citycom/OanApiClient.php
similarity index 75%
rename from lib/Citycom/OanApi.php
rename to lib/Citycom/OanApiClient.php
index 874c07b21..9b4d8eb0f 100644
--- a/lib/Citycom/OanApi.php
+++ b/lib/Citycom/OanApiClient.php
@@ -1,6 +1,6 @@
sendGetRequest($url, $ctx_options);
+ $locations = $this->runApiRequest($url, $ctx_options);
return $locations;
}
@@ -60,7 +60,7 @@ class Citycom_OanApi {
]
];
- $homes = $this->sendGetRequest($url, $ctx_options);
+ $homes = $this->runApiRequest($url, $ctx_options);
return $homes;
}
@@ -74,7 +74,23 @@ class Citycom_OanApi {
}
$url = $this->baseurl.CITYCOM_OAN_API_EP_GET_PRODUCTS;
- echo $url;
+ echo "$url\n";
+
+ $url = $this->baseurl.CITYCOM_OAN_API_EP_GET_PRODUCTS;
+
+ $ctx_options = [
+ "http" => [
+ "ignore_errors" => true,
+ "method" => "GET",
+ "header" => [
+ "Accept: application/json",
+ "Authorization: Bearer ".$this->token,
+ ],
+ ]
+ ];
+
+ $products = $this->runApiRequest($url, $ctx_options);
+ return $products;
}
@@ -86,9 +102,29 @@ class Citycom_OanApi {
}
}
+ if(!array_key_exists("name", $data) || !array_key_exists("bb_down", $data) || !array_key_exists("bb_up", $data)) {
+ return false;
+ }
+
$url = $this->baseurl.CITYCOM_OAN_API_EP_CREATE_PRODUCT;
echo "$url\n";
+ $ctx_options = [
+ "http" => [
+ "ignore_errors" => true,
+ "method" => "POST",
+ "content" => json_encode($data),
+ "header" => [
+ "Accept: application/json",
+ "Content-Type: application/json",
+ "Authorization: Bearer ".$this->token,
+ ],
+ ]
+ ];
+
+ $new_product = $this->runApiRequest($url, $ctx_options);
+ return $new_product;
+
}
public function updateProduct($product_id, $data) {
@@ -129,6 +165,20 @@ class Citycom_OanApi {
$url = $this->baseurl.CITYCOM_OAN_API_EP_GET_SERVICES;
echo "$url\n";
+ $ctx_options = [
+ "http" => [
+ "ignore_errors" => true,
+ "method" => "GET",
+ "header" => [
+ "Accept: application/json",
+ "Authorization: Bearer ".$this->token,
+ ],
+ ]
+ ];
+
+ $services = $this->runApiRequest($url, $ctx_options);
+ return $services;
+
}
public function createService($home_id, $data) {
@@ -142,6 +192,20 @@ class Citycom_OanApi {
$url = $this->baseurl.CITYCOM_OAN_API_EP_CREATE_SERVICES;
echo "$url\n";
+ $ctx_options = [
+ "http" => [
+ "ignore_errors" => true,
+ "method" => "POST",
+ "header" => [
+ "Accept: application/json",
+ "Content-type: application/json",
+ "Authorization: Bearer ".$this->token,
+ ],
+ ]
+ ];
+
+ $new_service = $this->runApiRequest($url, $ctx_options);
+ return $new_service;
}
public function updateService($service_id, $data) {
@@ -248,7 +312,7 @@ class Citycom_OanApi {
return true;
}
- private function sendGetRequest($url, $ctx_opts, $url_params = [], $page_num = 1) {
+ private function runApiRequest($url, $ctx_opts, $url_params = [], $page_num = 1) {
$current_page = $page_num;
$return_data = [];
@@ -273,7 +337,7 @@ class Citycom_OanApi {
$resp = json_decode($output);
//var_dump($resp);
- if(!is_object($resp) || !property_exists($resp, "success") || !$resp->success) {
+ if(!is_object($resp) || (property_exists($resp, "success") && !$resp->success)) {
return false;
}
@@ -287,7 +351,7 @@ class Citycom_OanApi {
if(property_exists($response, "last_page") && $response->last_page > 1) {
if($current_page < $response->last_page) {
$next_page = $current_page + 1;
- $next_data = $this->sendGetRequest($url, $ctx_opts, $url_params, $next_page);
+ $next_data = $this->runApiRequest($url, $ctx_opts, $url_params, $next_page);
if(!$next_data) {
return $return_data;
}
@@ -302,6 +366,4 @@ class Citycom_OanApi {
}
-
-
}
\ No newline at end of file
diff --git a/lib/Citycom/OanApiHelper.php b/lib/Citycom/OanApiHelper.php
new file mode 100644
index 000000000..a5bde04e3
--- /dev/null
+++ b/lib/Citycom/OanApiHelper.php
@@ -0,0 +1,122 @@
+api = $apiClient;
+ }
+
+ public function findOrCreateProduct($specs = []) {
+ if(!array_key_exists("up", $specs) || !array_key_exists("down", $specs) || !is_numeric($specs["up"]) || !is_numeric($specs["down"])) {
+ return false;
+ }
+
+ $up = $specs["up"];
+ $down = $specs["down"];
+
+ $search_name = false;
+ if(array_key_exists("name", $specs) && $specs["name"]) {
+ $search_name = $specs["name"];
+ }
+
+ $products = $this->api->getProducts();
+ foreach($products as $product) {
+ if($up == $product->bb_up && $down == $product->bb_down) {
+ if($search_name) {
+ if($product->name == $search_name) {
+ return $product->id;
+ }
+ } else {
+ return $product->id;
+ }
+ }
+ }
+
+ // not found, so create new product
+
+ $name = "xinon_tt_{$down}_{$up}";
+ if(array_key_exists("name", $specs)) {
+ $name = $specs["name"];
+ }
+
+ $product_id = $this->api->createProduct([
+ "name" => $name,
+ "bb_down" => $down,
+ "bb_up" => $up
+ ]);
+
+ if(!$product_id) {
+ return false;
+ }
+
+ return $product_id;
+ }
+
+ public function orderServices($preorder, $sublocation_id, $data) {
+ if(!is_numeric($sublocation_id) || !$sublocation_id) {
+ return false;
+ }
+
+ if(!array_key_exists("up", $data) || !array_key_exists("down", $data) || !is_numeric($data["up"]) || !is_numeric($data["down"])) {
+ return false;
+ }
+
+ if(!array_key_exists("services", $data) || is_array($data["services"]) || !count($data["services"])) {
+ return false;
+ }
+
+ $up = $data["up"];
+ $down = $data["down"];
+ $product_name = $data["product_name"];
+ $execution_date = $data["execution_date"];
+ $services = $data["services"];
+
+ if(!$execution_date) {
+ $execution_date = date("Y-m-d");
+ }
+
+
+ $product_data = [
+ "bb_up" => $up,
+ "bb_down" => $down,
+ "name" => $product_name
+ ];
+
+ // find or craete product
+ $product_id = $this->findOrCreateProduct($product_data);
+ if(!$product_id) {
+ $this->log->debug(__METHOD__.": no citycom product for query ".print_r($product_data, true));
+ return false;
+ }
+
+ // order all services and save ctags
+ $cc_service_types = $this->api->getServices();
+
+ $new_services = [];
+ foreach($cc_service_types as $stype) {
+ $service_data = [
+ "service_type" => $stype->id,
+ "product" => $product_id,
+ "billing_date" => $execution_date,
+ "ctag"
+ ];
+ $new_service = $this->api->createService($sublocation_id, $service_data);
+ }
+
+ return false;
+ }
+
+
+
+ public static function citycomIdToHausnummerExtref($id) {
+ if(!$id) return false;
+ return "citycom-$id";
+ }
+
+ public static function hausnummerExtrefToCitycomId($extref) {
+ if(!$extref) return false;
+ return str_replace("citycom-", "", $extref);
+ }
+}
\ No newline at end of file
diff --git a/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php b/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php
index 4cb99d99b..ab08c8500 100644
--- a/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php
+++ b/scripts/adb-rimo-import/ADBAddressHelper/address_helper.php
@@ -260,6 +260,10 @@ class AddressHelper
return false;
}
}
+ if($hausnummer->vlan_stag != $stag) {
+ $hausnummer->vlan_stag = $stag;
+ $hausnummer->save();
+ }
return $hausnummer;
diff --git a/scripts/adb-rimo-import/importer/citycom.php b/scripts/adb-rimo-import/importer/citycom.php
index 4a30372ad..fbc280b88 100644
--- a/scripts/adb-rimo-import/importer/citycom.php
+++ b/scripts/adb-rimo-import/importer/citycom.php
@@ -25,7 +25,7 @@ class CitycomImporter {
// get locations (Hausnummer) + Sublocations (Wohneinheiten)
$hausnummer_found_count = 0;
- $ccapi = new \Citycom_OanApi(CITYCOM_OAN_API_USER, CITYCOM_OAN_API_PASS);
+ $ccapi = new \Citycom_OanApiClient(CITYCOM_OAN_API_USER, CITYCOM_OAN_API_PASS);
$locations = $ccapi->getLocations();
if(!is_array($locations)) {