api = $apiClient; $this->log = mfLoghandler::singleton(); } 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; } /** * Creates services in Citycom API * * $data = [ * "up" = 300, * "down" = 300, * "execution_date" = [Y-m-d | false], * "services" = CITYCOM_OAN_API_SERVICES_FOR_ORDER, * "product_name" = "thetool-test OAN 300/300" * ] * * @param $preorder Preorder * @param $sublocation_id integer * @param $data Array * @return boolean|Array */ 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"]; $want_services = $data["services"]; if(!$execution_date) { $execution_date = date("Y-m-d"); } $ctag_range_search = false; if(array_key_exists("ctag_range_search", $data) && $data["ctag_range_search"]) { $ctag_range_search = $data["ctag_range_search"]; } $product_data = [ "up" => $up, "down" => $down, "name" => $product_name ]; // find or craete product $product_id = $this->findOrCreateProduct($product_data); if(!$product_id) { $this->log->error(__METHOD__.": no citycom product found for ".print_r($product_data, true)); return false; } // order all services and save ctags $cc_service_types = $this->api->getServiceTypes(); $this->log->debug(__METHOD__.": Want services: ".print_r($want_services, true)); $allowed_service_types = array_merge(CITYCOM_OAN_API_SERVICES_FOR_ORDER, CITYCOM_OAN_API_SERVICES_FOR_RESERVATION); // check if we have these services already foreach($cc_service_types as $stype) { if(!in_array($stype->name, $allowed_service_types)) continue; $ctag_service_type = (array_flip($allowed_service_types))[$stype->name]; if(PreorderCtag::getFirstActive(["preorder_id" => $preorder->id, "service_type" => $ctag_service_type])) { // service was ordered already, remove from want_services unset($want_services[$ctag_service_type]); } } $this->log->debug(__METHOD__.": Want services after filtering: ".print_r($want_services, true)); $new_services = []; if($ctag_range_search) { list($ctags, $mgmt_ctag) = $preorder->getFreeCtagsInSet($ctag_range_search); } else { list($ctags, $mgmt_ctag) = $preorder->getNextFreeCtags(); } //var_dump($ctags); //var_dump($mgmt_ctag); $this->log->debug(__METHOD__.": ctags: ".print_r($ctags, true)); $this->log->debug(__METHOD__.": mgmt ctag: ".print_r($mgmt_ctag, true)); if(!is_array($ctags)) { $this->log->error(__METHOD__.": No Free Ctags (Preorder ".$preorder->id.")"); return false; } $ctag_count = count($ctags); if($mgmt_ctag) $ctag_count++; if($ctag_count < count($want_services)) { $this->log->error(__METHOD__.": Not enough New Free CTags for Preorder ".$preorder->id); return false; } $preorder_ctag_data = [ "preorder_id" => $preorder->id, "network" => "citycom-oan", "stag" => $preorder->adb_hausnummer->vlan_stag, ]; $service_count = 0; foreach($cc_service_types as $stype) { // was this service type requested if(!in_array($stype->name, $want_services)) continue; // ensure mgmt_ctag is always known (currently last in range) if($mgmt_ctag && $stype->name == $allowed_service_types["mgmt"]) { $ctag = $mgmt_ctag; } else { $ctag = array_shift($ctags); } $ctag_service_type = array_flip($allowed_service_types)[$stype->name]; if(!$ctag_service_type) { $this->log->error(__METHOD__.": Cannot create Service ".$stype->name." for preorder ".$preorder->id." because no ctag service type defined"); return false; } $service_data = [ "sublocation" => $sublocation_id, "service_type" => $stype->id, "product" => $product_id, "billing_date" => $execution_date, "ctag" => $ctag, ]; //echo "Creating Service ".$stype->name." on sublocation $sublocation_id with product_id $product_id and ctag $ctag\n"; $this->log->info(__METHOD__.": Creating Service ".$stype->name." on sublocation $sublocation_id with product_id $product_id and ctag $ctag"); //continue; // register new Service with Citycom $new_service = $this->api->createService($service_data); if(!$new_service) { $this->log->error(__METHOD__.": Error creating service"); $this->log->error(__METHOD__.": Last Error: ".$this->api->lastError); return false; } /*$service_return[] = [ "service_number" => $new_service->service_number, "sublocation_id" => $sublocation_id, "service_type" => $ctag_service_type, "ctag" => $ctag, "ont" => [ "serial" => $new_service->ont->serial, "fsan" => $new_service->ont->fsan, ], ];*/ /*$service_return[] = [ "sublocation_id" => $sublocation_id, "service_number" => "30-fggreger-01", "service_type" => $ctag_service_type, "ctag" => $ctag, "ont" => [ "serial" => "ONT123456", "fsan" => "FSAN7890", ], ];*/ // save ctag $ctag_data = $preorder_ctag_data; $ctag_data["ctag"] = $ctag; $ctag_data["service_type"] = $ctag_service_type; $pct = PreorderCtag::create($ctag_data); $service_count++; if(!$pct->save()) { $this->log->error(__METHOD__.": Error saving PreorderCtag (Preorder ".$preorder->id.")"); return false; } try { $pct->configureNetwork(); } catch(Exception $e) { $this->log->error(__METHOD__.": Error configuring network equipment (Preorder ".$preorder->id.")"); $mail = new Emailnotification(); $mail->setFrom("office@xinon.at"); $mail->setTo("schubert@sknetworx.net"); $mail->setSubject("Fehler beim Konfigurieren von ctag auf Citycom NNI Router"); $mail->setBody("Preorder ID: ".$preorder->id); $mail->send(); } } return true; } /** * Updates service values if nesseccary * * @param $service_ext_num * @param $data * @return bool */ public function updateService($service_ext_id, $data) { // get service and compare data $services = $this->api->getServices(); if(!$services) { $this->log->error(__METHOD__.": Error getting services."); return false; } $service = false; foreach($services as $cc_service) { if($cc_service->id == $service_ext_id) { $service = $cc_service; break; } } if(!$service) { $this->log->error(__METHOD__.": Service not available."); return false; } $service_data = []; // update service if nesseccary if(array_key_exists("product_name", $data) && $data["product_name"] && $service->product->name != $data["product_name"]) { $product_data["up"] = $data["up"]; $product_data["down"] = $data["down"]; $product_data["name"] = $data["product_name"]; $product_id = $this->findOrCreateProduct($product_data); if(!$product_id) { $this->log->error(__METHOD__.": Cannot find or create product ".$product_data["name"]); return false; } $service_data["product"] = $product_id; } if(!count($service_data)) return true; $result = $this->api->updateService($service->id, $service_data); if($result) return true; 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); } }